Skip to content

Command Palette ​

SCommandPalette is the ⌘K window: one search field over every action in the application, grouped and reachable from the keyboard. It opens over the page as a modal dialog, filters the commands as the user types, and reports the chosen one through select — running it is up to the application.

The component binds the global shortcut itself: Cmd + K on macOS, Ctrl + K elsewhere. Use shortcut-key to pick another letter or :shortcut-key="false" to bind nothing and open the palette only through v-model:open. The binding stays out of the way of text the user is writing: a keystroke that starts in an input, a textarea or a rich-text area is left to that field. With several palettes mounted, only the most recently mounted one answers the shortcut.

Reka UI owns the interaction. The search field is a combobox over a listbox: the arrow keys and Home/End move the highlight, skipping group headings and disabled rows, Enter runs the highlighted command, and the active row scrolls into view. Focus stays in the input the whole time — the highlighted row is announced through aria-activedescendant. Opening the palette focuses the search field, Escape closes it, and focus returns to whatever had it before.

Each command is { id, label } plus the optional description, icon, shortcut, keywords and disabled. shortcut is a hint drawn with SKbd — the application still binds those keys itself. keywords widen the search without showing up in the row.

Basic usage ​

Commands come in groups, each with its own heading. Selecting one closes the palette.

The global shortcut ​

This is the only example on the page with the shortcut live: press ⌘ K (or Ctrl K) anywhere outside a text field. Every other demo here sets :shortcut-key="false" so the page does not take the combination away from the reader's browser.

The footer slot is a good place for the keyboard hints. It is empty by default, because the wording belongs to the application's own vocabulary:

The item slot receives { item, active }, where active is true for the highlighted row.

With :filter="false" the palette lists groups exactly as they arrive: bind v-model:search to run the query on the server, and raise loading while the request is in flight.

The query is cleared when the palette closes, so the next opening starts from the full list.

Empty state ​

Without matches the palette shows the text from empty-text — or from the locale dictionary when the prop is not set. The empty slot replaces the whole block.

API ​

Props

NameTypeDefaultDescription
groups*{ label?: string; items: { id: string; label: string; description?: string; icon?: string; shortcut?: string[] | undefined; disabled?: boolean; keywords?: string[] }[] }[]requiredCommands to list, split into groups.
placeholderstringundefinedPlaceholder and accessible name of the search input (defaults to the locale dictionary).
empty-textstringundefinedText shown when nothing matches the query (defaults to the locale dictionary).
filterbooleantrueFilters groups by the query. Turn it off when the application searches server-side: what it puts into groups is then listed as it arrives.
shortcut-keystring | false"k"Key that opens the palette together with Cmd (macOS) or Ctrl. false binds nothing and leaves v-model:open as the only way in.
loadingbooleanfalseA search is in flight: a spinner appears in the input and the list reports it.
max-heightstring | numberundefinedHeight the list may grow to before it scrolls (22rem by default); a number means pixels. The list also never grows past 60% of the window height, so the palette stays on screen.
squarebooleanfalseSquare corners: removes the rounding of the panel.
flatbooleanundefinedRemoves the shadow. Overridden by the elevation prop when it is set.
elevation0 | 3 | 1 | 2 | 4 | 5undefinedShadow level 0–5 (scale); 0 means no shadow. Overrides flat.
openbooleanundefinedWhether the palette is open. Two-way binding via v-model:open.
searchstring""The query the user typed. Two-way binding via v-model:search: bind it to search on the server and hand the result back in groups with filter off. Closing the palette clears it, so the next opening starts from the full list rather than from a query nobody can see.

Events

NameSignatureDescription
update:open(value: boolean | undefined) => voidEmitted when open changes. Used for two-way binding (v-model:open).
update:search(value: string) => voidEmitted when search changes. Used for two-way binding (v-model:search).
select(item: SCommandItem) => voidThe user ran a command with the mouse or the keyboard. The application performs it; the palette only closes itself.

Slots

NameDescription
itemRow content instead of the icon, the label and the shortcut hints.
emptyPanel content when nothing matches the query.
footerHint row under the list, for example the keys that navigate and run a command.