Command

Finds and runs a command by typing.

Placement

  • inlinedefault

  • dialog

States

  • searching

  • empty

  • loading

Usage

When to use it
Use
A ⌘K palette across the product: run an eval, open an agent, change a setting.
Use
Picking one of many named things where typing beats scrolling: an agent, a model, a workspace.
Not for
Three to twelve actions on one item. Use Dropdown menu.
Not for
Choosing a value for a form field. Use a combobox.

Rules

8 rules
Must
Set shouldFilter={false} and mount CommandLoading while a server request runs. Because the client filter hides server results whose text lacks the query, and without CommandLoading the list says No results while the request runs.
Must
Wrap item text in CommandLabel and pass value when the item holds an icon or a shortcut. Because only a string child gets its matched letters drawn, so a mixed item shows no reason it matched.
Must
Give CommandDialog a title that says what it searches. Because the hidden title names the dialog, and the default "Command palette" does not say what it finds.
Never
Swap in a loose fuzzy matcher for filter. Because scattered-letter matches rank unrelated items first, and Enter runs the first item.
Should
Put CommandFooter with its CommandHint keys in a CommandDialog, after the Command, where it is the card's footer row.
Should
Pass keywords with the other words people use, such as ['ship', 'release'] for Publish prompt.
Should
Start an action with its verb and name things by their own name; ranking favours the first word.
Should
Say what can be found in the placeholder, such as "Search commands and agents".

State order

4 states, highest first
1
loading
2
empty
3
searching
4
rest

Accessibility

5 checks
The input is a combobox pointing at the active option with aria-activedescendant; focus never leaves it.
The list is a listbox of groups and options, with aria-posinset and aria-setsize in screen order.
A polite status outside the list says how many results, counting the unavailable ones.
The active row's wash is the indicator, as in the menu. The search is the header row and keeps the cursor for the palette's whole life, so it draws no ring; the caret shows it.
CommandDialog makes the page inert and closes with Escape back to the opener.

Keyboard

4 keys
Up, Down (Ctrl P, Ctrl N)
Moves the active item.
Home, End
The first and last item, when the field is empty or with Ctrl.
Enter
Runs the active item, which after typing is the best match.
Escape
Closes the palette and returns focus to the opener.

Edge cases

6 edge cases
A 90-character label
Truncates on one line; the shortcut keeps its place.
One-letter search
Names starting with it rank first across groups, then word starts, then the rest.
Nothing matches
No results, then the query that found nothing.
Request never returns
The search glyph turns; Empty never shows; typing goes on.
Touch
The key hints hide; the input is 16px so a phone browser does not zoom.
Reduced motion
The loading arc stays drawn and still.

API

7 props
Command label
string default 'Commands'
Command shouldFilter, filter
boolean, (value, search, keywords) => number default true, ranked words
Command loop
boolean default false
CommandInput value, onValueChange
string
CommandItem value, keywords, onSelect
string, string[], (value) => void default text content
CommandItem disabled, forceMount
boolean default false
CommandDialog title, description
ReactNode | null default 'Command palette'

Tokens

20 tokens
--paper
#ffffff
--line
rgb(5 5 5 / 0.10)
--line-faint
rgb(5 5 5 / 0.06)
--control-lg
36px
--scrollbar-thumb
rgb(5 5 5 / 0.20)
--radius-overlay
10px
--radius-tag
6px
--shell
#f1f1f0
--shell-inset
3px
--menu-row
32px
--popup-max
320px
--overlay-lg
640px
--hover
rgb(5 5 5 / 0.06)
--type-label
500 13px/1.35 var(--font-sans)
--type-body-sm
400 13px/1.5 var(--font-sans)
--type-code-xs
400 calc(12px * var(--mono-scale))/1.35 var(--font-mono)
--text-1
rgb(5 5 5 / 0.80)
--text-2
rgb(5 5 5 / 0.60)
--text-3
rgb(5 5 5 / 0.45)
--text-disabled
rgb(5 5 5 / 0.32)

Install

For your coding agent

GitHub

Please star me pookie

141

A new design system every week

Leave your email before you copy the prompt.