Command menu

Fast, composable command palette with search and keyboard shortcuts.

Installation
$Terminal
npx shadcn@latest add https://sdk-components.thesqd.com/r/command.json
Usage
Import from the master file and compose. Wrap items in groups; pair with `CommandDialog` for the cmd/ctrl + K pattern.
TSImport
import { CommandMenu } from "@/components/ui/command";
TSExample
import { CalendarIcon } from "lucide-react";
import { CommandMenu } from "@/components/ui/command";

export function Example() {
  return (
    <CommandMenu
      groups={[
        {
          heading: "Suggestions",
          items: [
            { label: "Calendar", icon: <CalendarIcon />, onSelect: () => {} },
          ],
        },
      ]}
    />
  );
}
Composition
Anatomy of the Command primitive.
CommandMenu                       (single component — pass groups as data)
├── placeholder="Type a command…"
├── groups={[
│     {
│       heading?: ReactNode,
│       items: [
│         { label, icon?, shortcut?, onSelect?, disabled?, value? },
│         …
│       ],
│     },
│     …
│   ]}
├── emptyMessage="No results found."
├── asDialog                       (optional — wraps in CommandDialog modal)
├── open / onOpenChange            (controlled when asDialog)
└── className

Need a custom shape — manual filtering, an empty state with full JSX, or
nested groups? The slot exports — Command, CommandInput, CommandList,
CommandEmpty, CommandGroup, CommandItem, CommandSeparator, CommandShortcut,
CommandDialog — are still exported as the escape hatch.
Default
Inline panel — drop it anywhere. Wrap with a fixed-width container if you don't want it to fill its parent.
Simple
Flat list with a small tonal Badge per row labelling each entry's source group. Same shape the app-wide search palette uses.
Dialog (cmd/ctrl + K)
Pass `asDialog` and the menu opens as a centered modal triggered by your `open` / `onOpenChange` state.

Press K or click below.

Multiple groups
Multiple `groups` entries automatically separate themselves with a divider and their own heading.
Empty state
When every item is filtered out, `emptyMessage` renders inline — pass JSX for a richer layout.
API Reference
Props exposed by the CommandMenu component.

CommandMenu

PropTypeDefaultDescription
groupsCommandGroupSpec[]List of groups to render. Each group has an optional heading and an `items` array.
placeholderstring"Type a command or search…"Placeholder text rendered in the search input.
emptyMessageReactNode"No results found."Rendered when the search filters every item out. Pass JSX for a richer empty layout.
asDialogbooleanfalseWrap the menu in `CommandDialog` so it opens as a centered modal triggered by `open` / `onOpenChange`.
openbooleanControlled open state when `asDialog` is set.
onOpenChange(open: boolean) => voidFires when the dialog opens or closes.
dialogTitlestring"Command Palette"Accessible title used by `asDialog`.
classNamestringOverride or extend the resolved classes.

CommandItemSpec

PropTypeDefaultDescription
labelReactNodeItem content. Pass JSX for badges, secondary text, etc.
iconReactNodeLeading icon — typically a lucide icon component.
shortcutReactNodeKeyboard hint shown on the trailing edge of the row.
onSelect(value: string) => voidFires when the item is chosen via mouse or keyboard.
disabledbooleanSkip the item in keyboard navigation and matching.
valuestringCustom string used for filtering and for the `onSelect` callback. Defaults to the rendered text content.