Color
Typography
Spacing
Radius
Border
Opacity
Elevation
Blur
Avatar
Badge
Button
Checkbox
Input
ProgressBar
RadioButton
Separator
Slider
Switch
TextArea
TextLink
Accordion
Breadcrumb
ButtonGroup
Combobox
DropdownMenu
ListItem
Pagination
SegmentedControl
Select
Tooltip
Calendar
Card
CommandMenu
DatePicker
Dialog
Drawer
EmptyState
Footer
Form
NavigationBar
Sidebar
Skeleton
Table
Tabs
Toaster

CommandMenu

Search and quick actions: a search field that filters a list of commands, grouped under headings. In the page, or as a modal dialog opened from a trigger.

Calendar
Search Emoji
Calculator
Profile⌘P
Billing⌘B
Settings⌘S
Results

Usage

Import the component and render it.

import { CommandMenu } from 'src/components/CommandMenu/CommandMenu';
import { Button } from 'src/components/Button/Button';
import { CalendarBlankIcon, SmileyIcon, CalculatorIcon, UserIcon, CreditCardIcon, GearIcon } from '@phosphor-icons/react';

<CommandMenu
  groups={[{"heading":"Suggestions","items":[{"label":"Calendar","icon":<CalendarBlankIcon />},{"label":"Search Emoji","icon":<SmileyIcon />},{"label":"Calculator","icon":<CalculatorIcon />,"disabled":true}]},{"heading":"Settings","items":[{"label":"Profile","icon":<UserIcon />,"shortcut":"⌘P"},{"label":"Billing","icon":<CreditCardIcon />,"shortcut":"⌘B"},{"label":"Settings","icon":<GearIcon />,"shortcut":"⌘S"}]}]}
  placeholder="Type a command or search…"
  trigger={<Button variant="outline" size="sm">Open command menu</Button>}
/>

Accessibility

Role: a search <input role="combobox" aria-autocomplete="list"> controlling a role="listbox" of options in named groups; modal: a <dialog> named by the label.

KeyAction
TypingFilters the commands; the first enabled match is highlighted
↓ / ↑Highlights the next / previous match (disabled ones are skipped; focus stays in the search field)
Home / EndHighlights the first / last match
EnterRuns the highlighted command (and closes the modal menu)
EscapeModal: closes it, and focus returns to the trigger. In the page: clears the search
  • The search field is named by the label (there is no visible label, as in Figma); the placeholder is not its name.
  • When nothing matches, the empty message is a live status (announced), not an option.
  • A click runs a command; the pointer does not move the highlight (Hover is its own state).
  • The Separators are decorative (hidden from assistive technology); each group is named by its heading.

Results

Results only changes the content: each example passes its own props.

Calendar
Search Emoji
Calculator
Profile⌘P
Billing⌘B
Settings⌘S
Default
No results found.
Empty
<CommandMenu groups={[{"heading":"Suggestions","items":[{"label":"Calendar","icon":<CalendarBlankIcon />},{"label":"Search Emoji","icon":<SmileyIcon />},{"label":"Calculator","icon":<CalculatorIcon />,"disabled":true}]},{"heading":"Settings","items":[{"label":"Profile","icon":<UserIcon />,"shortcut":"⌘P"},{"label":"Billing","icon":<CreditCardIcon />,"shortcut":"⌘B"},{"label":"Settings","icon":<GearIcon />,"shortcut":"⌘S"}]}]} />
<CommandMenu
  groups={[{"heading":"Suggestions","items":[{"label":"Calendar","icon":<CalendarBlankIcon />},{"label":"Search Emoji","icon":<SmileyIcon />},{"label":"Calculator","icon":<CalculatorIcon />,"disabled":true}]},{"heading":"Settings","items":[{"label":"Profile","icon":<UserIcon />,"shortcut":"⌘P"},{"label":"Billing","icon":<CreditCardIcon />,"shortcut":"⌘B"},{"label":"Settings","icon":<GearIcon />,"shortcut":"⌘S"}]}]}
  query="Unknown command"
/>

Composition

Use the following composition to build a CommandMenu:

CommandMenu
├── CommandMenuItem
├── Input
└── Separator

CommandMenuItem

One result of a Command Menu: an optional icon, a label and an optional keyboard shortcut. Only used inside CommandMenu.

Command⌘K
CommandMenuItem
<CommandMenuItem label="Command" />

Actions

Pass callbacks to respond to the component.

import { CommandMenu } from 'src/components/CommandMenu/CommandMenu';
import { Button } from 'src/components/Button/Button';
import { CalendarBlankIcon, SmileyIcon, CalculatorIcon, UserIcon, CreditCardIcon, GearIcon } from '@phosphor-icons/react';

<CommandMenu
  groups={[{"heading":"Suggestions","items":[{"label":"Calendar","icon":<CalendarBlankIcon />},{"label":"Search Emoji","icon":<SmileyIcon />},{"label":"Calculator","icon":<CalculatorIcon />,"disabled":true}]},{"heading":"Settings","items":[{"label":"Profile","icon":<UserIcon />,"shortcut":"⌘P"},{"label":"Billing","icon":<CreditCardIcon />,"shortcut":"⌘B"},{"label":"Settings","icon":<GearIcon />,"shortcut":"⌘S"}]}]}
  placeholder="Type a command or search…"
  trigger={<Button variant="outline" size="sm">Open command menu</Button>}
  onQueryChange={(query) => console.log(query)}
  onOpenChange={(open) => console.log(open)}
/>
CallbackWhen
onQueryChangeCalled as the search text changes.
onOpenChangeCalled when the modal menu opens or closes (trigger, running an item, Esc, a click outside).