Command Menu

A keyboard-driven command palette component with global Cmd+K / Ctrl+K shortcut. Built on Radix UI Dialog for accessibility and focus management.

Command Menu Demo

Press ⌘K to open the command menu.

Vertical Variant (Default)

Horizontal Variant

Press ⌘J to open.

Keyboard Shortcuts

  • ⌘K – Open vertical command menu
  • ⌘J – Open horizontal command menu
  • – Navigate items
  • Enter – Select item
  • Tab – Cycle tabs
  • Esc – Close menu

Basic Usage

Press Cmd+K (Mac) or Ctrl+K (Windows/Linux) to open the command menu.

import { CommandMenu } from '@/components/CommandMenu'

<CommandMenu.Root onSelect={(value) => console.log(value)}>
  <CommandMenu.Content>
    <CommandMenu.Search placeholder="Search all commands..." />

    <CommandMenu.Tabs defaultValue="home">
      <CommandMenu.Tab value="home">Home</CommandMenu.Tab>
      <CommandMenu.Tab value="dashboard" badge={5}>Dashboard</CommandMenu.Tab>
    </CommandMenu.Tabs>

    <CommandMenu.Divider />

    <CommandMenu.Group label="Actions">
      <CommandMenu.Item value="settings" icon={<SettingsIcon />}>
        Settings
      </CommandMenu.Item>
      <CommandMenu.Item value="profile" icon={<UserIcon />}>
        Profile
      </CommandMenu.Item>
    </CommandMenu.Group>

    <CommandMenu.Footer />
  </CommandMenu.Content>
</CommandMenu.Root>

Variants

The Command Menu supports two layout variants.

Vertical (Default)

A compact 500px wide modal with horizontal tabs.

<CommandMenu.Root variant="vertical">
  <CommandMenu.Content>
    {/* ... */}
  </CommandMenu.Content>
</CommandMenu.Root>

Horizontal

A wider 895px modal with vertical sidebar tabs.

<CommandMenu.Root variant="horizontal">
  <CommandMenu.Content>
    <CommandMenu.Search />
    <div className="flex flex-1">
      {/* Sidebar tabs */}
      <div className="border-r border-bg-surface p-4">
        <CommandMenu.Tabs defaultValue="home">
          <CommandMenu.Tab value="home">Home</CommandMenu.Tab>
          <CommandMenu.Tab value="dashboard">Dashboard</CommandMenu.Tab>
        </CommandMenu.Tabs>
      </div>
      {/* Main content */}
      <div className="flex-1 p-4">
        <CommandMenu.Group label="Commands">
          {/* ... items */}
        </CommandMenu.Group>
      </div>
    </div>
    <CommandMenu.Footer showNavigation showHelp />
  </CommandMenu.Content>
</CommandMenu.Root>

Recent Items

Use CommandMenu.Tag for removable recent items.

<CommandMenu.Group label="Recent" showClear onClear={handleClear}>
  <div className="flex flex-wrap gap-2">
    <CommandMenu.Tag icon={<FileIcon />} onRemove={() => remove('doc1')}>
      Q2 Strategy.doc
    </CommandMenu.Tag>
    <CommandMenu.Tag icon={<FolderIcon />} onRemove={() => remove('project1')}>
      Project Alpha
    </CommandMenu.Tag>
  </div>
</CommandMenu.Group>

Tab Filtering

Items can be assigned to specific tabs using the tabId prop.

<CommandMenu.Tabs defaultValue="home">
  <CommandMenu.Tab value="home">Home</CommandMenu.Tab>
  <CommandMenu.Tab value="settings">Settings</CommandMenu.Tab>
</CommandMenu.Tabs>

<CommandMenu.Group label="Actions">
  {/* Only visible when "home" tab is active */}
  <CommandMenu.Item value="dashboard" tabId="home">
    Dashboard
  </CommandMenu.Item>

  {/* Only visible when "settings" tab is active */}
  <CommandMenu.Item value="account" tabId="settings">
    Account Settings
  </CommandMenu.Item>
</CommandMenu.Group>

Custom Keyboard Shortcut

Change the default Cmd+K shortcut using the shortcutKey prop.

{/* Opens with Cmd+J instead of Cmd+K */}
<CommandMenu.Root shortcutKey="j">
  <CommandMenu.Content>
    {/* ... */}
  </CommandMenu.Content>
</CommandMenu.Root>

Controlled Mode

Control the open state externally.

const [open, setOpen] = useState(false)

<CommandMenu.Root open={open} onOpenChange={setOpen}>
  <CommandMenu.Content>
    {/* ... */}
  </CommandMenu.Content>
</CommandMenu.Root>

{/* Open programmatically */}
<button onClick={() => setOpen(true)}>Open Menu</button>

Keyboard Navigation

KeyAction
Cmd+K / Ctrl+KOpen/close command menu
Arrow Up/DownNavigate through items
EnterSelect highlighted item
Tab / Shift+TabCycle through tabs
EscapeClose menu

Accessibility

  • Built on Radix UI Dialog for robust focus management
  • Full keyboard navigation support
  • Proper ARIA attributes (role="dialog", aria-modal)
  • Focus trap within the modal
  • Auto-focus on search input when opened
  • Screen reader friendly item descriptions

API Reference

CommandMenu.Root Props

PropTypeDefaultDescription
variant'vertical' | 'horizontal''vertical'Layout variant
openboolean-Controlled open state
defaultOpenbooleanfalseDefault open state
onOpenChange(open: boolean) => void-Callback when open state changes
onSelect(value: string) => void-Callback when item is selected
shortcutKeystring'k'Keyboard shortcut key (used with Cmd/Ctrl)
defaultTabstring-Default active tab

CommandMenu.Content Props

PropTypeDefaultDescription
classNamestring-Additional CSS classes

CommandMenu.Search Props

PropTypeDefaultDescription
placeholderstring'Search all commands...'Placeholder text
showKbdbooleantrueShow keyboard shortcut indicator
showFilterbooleantrueShow filter icon button
onFilterClick() => void-Filter button click handler

CommandMenu.Tabs Props

PropTypeDefaultDescription
defaultValuestring-Default active tab value

CommandMenu.Tab Props

PropTypeDefaultDescription
valuestringRequiredUnique value for this tab
badgenumber-Badge count to display

CommandMenu.Group Props

PropTypeDefaultDescription
labelstring-Section label
showClearbooleanfalseShow clear button
onClear() => void-Clear button click handler

CommandMenu.Item Props

PropTypeDefaultDescription
valuestringRequiredUnique value for this item
iconReact.ReactNode-Icon element
tabIdstring-Tab this item belongs to (for filtering)
showArrowbooleanfalseShow arrow icon (for navigation items)
showEnterbooleantrueShow enter icon when highlighted
disabledbooleanfalseDisable this item

CommandMenu.Tag Props

PropTypeDefaultDescription
iconReact.ReactNode-Icon element
onRemove() => void-Remove button click handler

CommandMenu.Footer Props

PropTypeDefaultDescription
showNavigationbooleantrueShow navigation arrows hint
showHelpbooleanAutoShow help section (defaults based on variant)
helpTextstring'Contact support'Help link text
onHelpClick() => void-Help link click handler