Skip to content
GitHub

Overlays

Command

A filterable list of actions — the ⌘K surface.

Examples

inline

navigaterunescclose

dialog

or press K

Notes

A filterable list of actions — the ⌘K surface.

Built on cmdk rather than on a Select or a menu, because the interaction is neither: the list is filtered as you type, the highlighted row moves with the arrow keys while focus STAYS in the input, and Enter runs the highlighted row. That is the ARIA combobox pattern, and it is the part nobody should hand-roll — aria-activedescendant moving without focus moving is precisely where a home-made palette stops working with a screen reader.

Props

Takes no props of its own.

Parts

Composed at the call site rather than configured through props, so a layout this component did not anticipate is still expressible.

CommandInput

The filter field. Carries the search icon and the combobox semantics.

Takes no props of its own.

CommandList

Takes no props of its own.

CommandEmpty

Shown when the filter matches nothing. Say what would match, not "no results".

Takes no props of its own.

CommandFooter

The key-hint strip along the bottom.

A palette is a keyboard surface whose keys are invisible: nothing on screen says the arrows move the row or that Enter runs it, and a reader who reaches for the mouse has been failed by the design rather than by themselves.

Takes no props of its own.

CommandHint

One key-and-verb pair inside a CommandFooter.

CommandHint props
PropTypeDefaultDescription
childrenrequiredReactNodeWhat they do — a verb, lowercase, no sentence.
keysrequiredstring[]The keys this hint describes, printed as `Kbd` chips.

Also accepts everything in Omit<ComponentProps<'span'>, 'children'>. Those are forwarded to the underlying element and are not listed row by row.

CommandGroup

Takes no props of its own.

CommandSeparator

A divider between groups.

Marked presentational, because ARIA permits a listbox to contain only option and group — and the library renders this as role="separator", which puts a critical aria-required-children violation inside every palette that uses one. The grouping is already announced by the groups themselves, so removing the divider from the accessibility tree loses nothing.

Takes no props of its own.

CommandItem

CommandItem props
PropTypeDefaultDescription
iconReactNodeA leading glyph. Pass the icon element, sized 16. It is what makes a long list scannable — the eye sorts by shape before it reads, and forty identical rows of text defeat that.
metaReactNodeA quiet note at the end of the row — what kind of thing this is, or its current state. Not a description: a palette that prints a sentence per row stops being scannable at about six of them.
shortcutstringA shortcut printed at the end of the row.

Also accepts everything in ComponentProps<typeof CommandPrimitive.Item>. Those are forwarded to the underlying element and are not listed row by row.

CommandDialog

The palette in a modal, which is how it is nearly always used.

The dialog's own padding is removed: a palette is edge-to-edge, and its input is the first thing focus lands on.

CommandDialog props
PropTypeDefaultDescription
childrenrequiredReactNode
labelrequiredstringNames the palette for assistive tech.
onOpenChangerequired(open: boolean) => void
openrequiredboolean

Keyboard

Command keyboard interactions
KeyDoes
Moves the highlight. Focus stays in the input, so what you typed stays editable.
EnterRuns the highlighted item.
EscapeCloses the palette.

Accessibility

  • The list filters as you type, the highlight moves with the arrow keys, and focus stays in the input. That last part is the ARIA combobox pattern and the part a home-made palette gets wrong.