Filter commands as you type, then choose one to run. Wrap the list in CommandDialog for a command palette.
tsx
import { Command, CommandDialog, CommandDialogContent, CommandDialogTrigger, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, useCommandDialogClose,} from "@/components/ui/command"function Palette() { const close = useCommandDialogClose() return ( <Command className="border-0 bg-transparent" onSelect={close}> <CommandInput placeholder="Type a command or search…" /> <CommandList> <CommandEmpty>No results found.</CommandEmpty> <CommandGroup heading="Suggestions"> <CommandItem value="calendar">Calendar</CommandItem> <CommandItem value="emoji">Search Emoji</CommandItem> <CommandItem value="calculator">Calculator</CommandItem> </CommandGroup> <CommandSeparator /> <CommandGroup heading="Settings"> <CommandItem value="profile">Profile</CommandItem> <CommandItem value="billing">Billing</CommandItem> <CommandItem value="settings">Settings</CommandItem> </CommandGroup> </CommandList> </Command> )}export function Example() { return ( <CommandDialog> <CommandDialogTrigger>Open Menu</CommandDialogTrigger> <CommandDialogContent> <Palette /> </CommandDialogContent> </CommandDialog> )}Installation
npx @arctis-sh/@arctis-sh/ui@latest add commandUsage
import { Command, CommandDialog, CommandDialogContent, CommandDialogTrigger, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, useCommandDialogClose,} from "@/components/ui/command"function Palette() { const close = useCommandDialogClose() return ( <Command className="border-0 bg-transparent" onSelect={close}> <CommandInput placeholder="Search commands…" /> <CommandList> <CommandEmpty>No results found.</CommandEmpty> <CommandGroup heading="Suggestions"> <CommandItem value="docs">Open docs</CommandItem> <CommandItem value="registry">Search registry</CommandItem> </CommandGroup> </CommandList> </Command> )}export function Example() { return ( <CommandDialog> <CommandDialogTrigger>Open menu</CommandDialogTrigger> <CommandDialogContent> <Palette /> </CommandDialogContent> </CommandDialog> )}Composition
Command
├── CommandInput
└── CommandList
├── CommandEmpty
├── CommandGroup
│ ├── CommandItem
│ └── CommandItem
├── CommandSeparator
└── CommandGroup
├── CommandItem
└── CommandItemWith dialog:
CommandDialog
├── CommandDialogTrigger
└── CommandDialogContent
└── Command
├── CommandInput
└── CommandList
├── CommandEmpty
├── CommandGroup
│ └── CommandItem
├── CommandSeparator
└── CommandGroup
└── CommandItemBasic
A command menu inside a dialog. Pass useCommandDialogClose to onSelect to close it after a choice.
tsx
import { Command, CommandDialog, CommandDialogContent, CommandDialogTrigger, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, useCommandDialogClose,} from "@/components/ui/command"function Palette() { const close = useCommandDialogClose() return ( <Command className="border-0 bg-transparent" onSelect={close}> <CommandInput placeholder="Type a command or search…" /> <CommandList> <CommandEmpty>No results found.</CommandEmpty> <CommandGroup heading="Suggestions"> <CommandItem value="calendar">Calendar</CommandItem> <CommandItem value="emoji">Search Emoji</CommandItem> <CommandItem value="calculator">Calculator</CommandItem> </CommandGroup> <CommandSeparator /> <CommandGroup heading="Settings"> <CommandItem value="profile">Profile</CommandItem> <CommandItem value="billing">Billing</CommandItem> <CommandItem value="settings">Settings</CommandItem> </CommandGroup> </CommandList> </Command> )}export function Example() { return ( <CommandDialog> <CommandDialogTrigger>Open Menu</CommandDialogTrigger> <CommandDialogContent> <Palette /> </CommandDialogContent> </CommandDialog> )}Shortcuts
Add keyboard hints with CommandShortcut.
tsx
import { Command, CommandDialog, CommandDialogContent, CommandDialogTrigger, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, useCommandDialogClose,} from "@/components/ui/command"function Palette() { const close = useCommandDialogClose() return ( <Command className="border-0 bg-transparent" onSelect={close}> <CommandInput placeholder="Type a command or search…" /> <CommandList> <CommandEmpty>No results found.</CommandEmpty> <CommandGroup heading="Suggestions"> <CommandItem value="calendar">Calendar</CommandItem> <CommandItem value="emoji">Search Emoji</CommandItem> <CommandItem value="calculator">Calculator</CommandItem> </CommandGroup> <CommandSeparator /> <CommandGroup heading="Settings"> <CommandItem value="profile" label="Profile"> Profile <CommandShortcut>⌘P</CommandShortcut> </CommandItem> <CommandItem value="billing" label="Billing"> Billing <CommandShortcut>⌘B</CommandShortcut> </CommandItem> <CommandItem value="settings" label="Settings"> Settings <CommandShortcut>⌘S</CommandShortcut> </CommandItem> </CommandGroup> </CommandList> </Command> )}export function Example() { return ( <CommandDialog> <CommandDialogTrigger>Open Menu</CommandDialogTrigger> <CommandDialogContent> <Palette /> </CommandDialogContent> </CommandDialog> )}Groups
Organize related items with headings, icons, and separators.
tsx
import type { SVGProps } from "react"import { Command, CommandDialog, CommandDialogContent, CommandDialogTrigger, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, useCommandDialogClose,} from "@/components/ui/command"function CalendarIcon(props: SVGProps<SVGSVGElement>) { return ( <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" {...props}> <path d="M8 2v4" /><path d="M16 2v4" /><rect width="18" height="18" x="3" y="4" rx="2" /><path d="M3 10h18" /> </svg> )}function SmileIcon(props: SVGProps<SVGSVGElement>) { return ( <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" {...props}> <circle cx="12" cy="12" r="10" /><path d="M8 14s1.5 2 4 2 4-2 4-2" /><line x1="9" x2="9.01" y1="9" y2="9" /><line x1="15" x2="15.01" y1="9" y2="9" /> </svg> )}function CalculatorIcon(props: SVGProps<SVGSVGElement>) { return ( <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" {...props}> <rect width="16" height="20" x="4" y="2" rx="2" /><line x1="8" x2="16" y1="6" y2="6" /><line x1="16" x2="16" y1="14" y2="18" /><path d="M16 10h.01" /><path d="M12 10h.01" /><path d="M8 10h.01" /><path d="M12 14h.01" /><path d="M8 14h.01" /><path d="M12 18h.01" /><path d="M8 18h.01" /> </svg> )}function UserIcon(props: SVGProps<SVGSVGElement>) { return ( <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" {...props}> <path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2" /><circle cx="12" cy="7" r="4" /> </svg> )}function CreditCardIcon(props: SVGProps<SVGSVGElement>) { return ( <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" {...props}> <rect width="20" height="14" x="2" y="5" rx="2" /><path d="M2 10h20" /> </svg> )}function SettingsIcon(props: SVGProps<SVGSVGElement>) { return ( <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" {...props}> <path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z" /> <circle cx="12" cy="12" r="3" /> </svg> )}function Palette() { const close = useCommandDialogClose() return ( <Command className="border-0 bg-transparent" onSelect={close}> <CommandInput placeholder="Type a command or search…" /> <CommandList> <CommandEmpty>No results found.</CommandEmpty> <CommandGroup heading="Suggestions"> <CommandItem value="calendar" label="Calendar"> <CalendarIcon /> Calendar </CommandItem> <CommandItem value="emoji" label="Search Emoji"> <SmileIcon /> Search Emoji </CommandItem> <CommandItem value="calculator" label="Calculator"> <CalculatorIcon /> Calculator </CommandItem> </CommandGroup> <CommandSeparator /> <CommandGroup heading="Settings"> <CommandItem value="profile" label="Profile"> <UserIcon /> Profile </CommandItem> <CommandItem value="billing" label="Billing"> <CreditCardIcon /> Billing </CommandItem> <CommandItem value="settings" label="Settings"> <SettingsIcon /> Settings </CommandItem> </CommandGroup> </CommandList> </Command> )}export function Example() { return ( <CommandDialog> <CommandDialogTrigger>Open Menu</CommandDialogTrigger> <CommandDialogContent> <Palette /> </CommandDialogContent> </CommandDialog> )}Scrollable
CommandList keeps long sets of results scrollable.
tsx
import { Fragment } from "react"import { Command, CommandDialog, CommandDialogContent, CommandDialogTrigger, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, useCommandDialogClose,} from "@/components/ui/command"const groups = [ { heading: "A – F", items: ["Alpha", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot"], }, { heading: "G – L", items: ["Golf", "Hotel", "India", "Juliet", "Kilo", "Lima"], }, { heading: "M – R", items: ["Mike", "November", "Oscar", "Papa", "Quebec", "Romeo"], }, { heading: "S – Z", items: ["Sierra", "Tango", "Uniform", "Victor", "Whiskey", "X-ray", "Yankee", "Zulu"], },] as constfunction Palette() { const close = useCommandDialogClose() return ( <Command className="border-0 bg-transparent" onSelect={close}> <CommandInput placeholder="Search letters…" /> <CommandList className="max-h-72"> <CommandEmpty>No results found.</CommandEmpty> {groups.map((group, index) => ( <Fragment key={group.heading}> {index > 0 ? <CommandSeparator /> : null} <CommandGroup heading={group.heading}> {group.items.map((letter) => ( <CommandItem key={letter} value={letter}> {letter} </CommandItem> ))} </CommandGroup> </Fragment> ))} </CommandList> </Command> )}export function Example() { return ( <CommandDialog> <CommandDialogTrigger>Open Menu</CommandDialogTrigger> <CommandDialogContent> <Palette /> </CommandDialogContent> </CommandDialog> )}API Reference
Command
| Prop | Type | Default |
|---|---|---|
| onSelect | (value: string) => void | — |
| className | string | — |
<Command> <CommandInput placeholder="Search commands…" /> <CommandList> <CommandEmpty>No results.</CommandEmpty> <CommandGroup heading="Suggestions"> <CommandItem>Open docs</CommandItem> </CommandGroup> </CommandList></Command>CommandDialog
| Prop | Type | Default |
|---|---|---|
| open | boolean | — |
| defaultOpen | boolean | false |
| onOpenChange | (open: boolean) => void | — |
<CommandDialog> <CommandDialogTrigger render={<Button variant="outline" />}> Open </CommandDialogTrigger> <CommandDialogContent> <Command>...</Command> </CommandDialogContent></CommandDialog>CommandDialogTrigger
| Prop | Type | Default |
|---|---|---|
| className | string | — |
<CommandDialogTrigger render={<Button variant="outline" />}> Open</CommandDialogTrigger>CommandDialogContent
| Prop | Type | Default |
|---|---|---|
| title | string | "Command Palette" |
| description | string | "Search for a command to run…" |
| className | string | — |
<CommandDialogContent> <Command>...</Command></CommandDialogContent>useCommandDialogClose
A hook for use inside CommandDialog. It returns a close function, typically passed to Command as onSelect.
| Returns | Type |
|---|---|
| close | () => void |
const close = useCommandDialogClose()<CommandItem onSelect={() => close()}>Close</CommandItem>CommandInput
| Prop | Type | Default |
|---|---|---|
| placeholder | string | "Type a command or search…" |
| className | string | — |
<CommandInput placeholder="Type a command..." />CommandList
| Prop | Type | Default |
|---|---|---|
| className | string | — |
<CommandList> <CommandItem>Open docs</CommandItem></CommandList>CommandEmpty
| Prop | Type | Default |
|---|---|---|
| children | ReactNode | "No results found." |
| className | string | — |
<CommandEmpty>No results.</CommandEmpty>CommandGroup
| Prop | Type | Default |
|---|---|---|
| heading | ReactNode | — |
| className | string | — |
<CommandGroup heading="Suggestions"> <CommandItem>Open docs</CommandItem></CommandGroup>CommandItem
| Prop | Type | Default |
|---|---|---|
| value | string | — |
| label | string | — |
| disabled | boolean | false |
| onSelect | (value: string) => void | — |
| children | ReactNode | — |
| className | string | — |
<CommandItem>Settings</CommandItem>CommandShortcut
| Prop | Type | Default |
|---|---|---|
| className | string | — |
<CommandItem> Settings <CommandShortcut>⌘S</CommandShortcut></CommandItem>CommandSeparator
| Prop | Type | Default |
|---|---|---|
| className | string | — |
<CommandSeparator />