Navigation
Command palette
The ⌘K launcher — one keystroke to search every command, project, and person, then act without touching the mouse. Built on Base UI Dialog for the overlay and Base UI Autocomplete for filtering, keyboard navigation, and ARIA combobox semantics.
npx shadcn@latest add @orbit/command-paletteOverview
Click the trigger, press ⌘K (Ctrl+K on Windows/Linux), or wire your own button — all three open the same palette. Selecting a command closes it and reports the pick.
Open the palette, type to filter, arrow to navigate.
last run: —
The palette
Type to filter across every group at once — actions, navigation, projects, and people. Results stay grouped, each with a tinted icon and its shortcut; empty groups disappear, and no matches shows a friendly empty state with the query. Try typing in the field below.
Anatomy
Four parts make the palette fast to scan and faster to act on.
A single input that filters every group at once, with an esc hint to dismiss.
Actions, Navigate, Projects, and People — each labeled, so the list stays scannable.
A tinted icon, a title and subtitle, and a trailing shortcut or a type tag.
Persistent ↑↓ navigate and ↵ select cues, plus the workspace it’s acting on.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| items | CommandGroup[] | — | Grouped commands: { label, items: CommandItem[] }. Empty groups disappear while filtering. |
| open | boolean | — | Controlled open state. Pair with onOpenChange. |
| defaultOpen | boolean | false | Initial open state when uncontrolled. |
| onOpenChange | (open: boolean) => void | — | Called when the palette opens or closes (trigger, ⌘K, Esc, scrim, select). |
| hotkey | boolean | true | Global ⌘K / Ctrl+K toggles the palette. Turn off to bind your own. |
| onSelect | (command: CommandItem) => void | — | Called with the picked command on Enter or click; the palette then closes. |
| placeholder | string | "Search commands, projects, people…" | Search input placeholder. |
| emptyHint | string | "Try a different term…" | Second line of the empty state, under “No results for …”. |
| workspace | string | "Orbit" | Workspace name shown in the footer next to the mark. |
| inline | boolean | false | Render the panel in the page flow instead of a ⌘K dialog — for docs and embeds. |
| children | ReactNode | — | Trigger slot — e.g. <CommandPaletteTrigger />. Ignored when inline. |
| className | string | — | Class applied to the 580px panel. |
| Prop | Type | Default | Description |
|---|---|---|---|
| CommandItem.id | string | — | Unique id, passed back through onSelect. |
| CommandItem.label | string | — | Primary row text; also what the filter matches. |
| CommandItem.description | string | — | Secondary line under the label. Also searched. |
| CommandItem.icon | ReactNode | — | Row visual — a 16px glyph, avatar, or dot. |
| CommandItem.tone | "blue" | "teal" | "green" | "amber" | "red" | "neutral" | — | Tint pair for the 30px icon tile. Omit to render the icon untiled (avatars). |
| CommandItem.shortcut | string[] | — | Trailing kbd hint, one key per entry — ["G", "I"]. |
| CommandItem.tag | string | — | Trailing type tag — e.g. “Project”. |
| CommandItem.keywords | string[] | — | Extra search terms that aren't visible on the row. |
| CommandItem.disabled | boolean | false | Renders the row non-interactive. |
| CommandPaletteTrigger.label | string | "Search or jump to…" | Placeholder-style label in the 260×38 search-box trigger. |
Usage
The palette rewards power users without getting in anyone else’s way.
Surface the most-used actions first
Order groups by frequency — actions and navigation before long lists of records.
Make it the only way in
The palette is an accelerator, not a replacement for visible buttons and nav.
Show the shortcut on the row
Teaching the chord next to the command is how people graduate to the keyboard.
Return a flat, unlabeled list
Grouping with headers is what keeps a long result set readable.
Keyboard & accessibility
The overlay is a Base UI Dialog — role=dialog with aria-modal, a focus trap, and focus restore on close. Inside it, Base UI Autocomplete gives the input ARIA combobox semantics: it owns the listbox and tracks the highlight with aria-activedescendant, so hands (and screen readers) never leave the search field. Esc always closes.