Skip to content
Protocore Design Systemv1.6.9

/// Overlay

CommandPalette

A ⌘K spotlight finder — grouped, filterable commands driven entirely from the keyboard over a dimmed backdrop.

import { CommandPalette } from "@protocore/pds";
View as Markdown

Basics

Feed groups of commands — each item has an id, label, optional icon / hint / keywords, and an onSelect handler. Set bindShortcut to register a global ⌘K / Ctrl+K toggle. Type to filter across labels, hints, group names, and keywords; the palette closes before running the choice.

Press ⌘K or the button, then type to filter.

Global ⌘K, no button

In uncontrolled mode with bindShortcut, ⌘K opens the palette from anywhere — no trigger element required. emptyMessage customizes the no-results copy.

With bindShortcut, ⌘K / Ctrl+K toggles the palette globally — no trigger button needed.

When to use it

A CommandPalette is the keyboard-first launcher for a dense app: navigation, actions, and settings unified behind ⌘K and fuzzy search. It rewards power users and scales to hundreds of commands where a visible menu can't. Group commands by domain (Navigate, Deploy, Settings) and add keywords so a command surfaces under the words people actually type.

It is not a form control — for selecting a value from options with typeahead, use a [Combobox](/inputs/combobox) or [Select](/inputs/select). For a small, fixed action list off a button, a [DropdownMenu](/overlay/dropdown-menu) is simpler. Reserve the palette for the app-wide command surface, and always keep a visible entry point (a search affordance or hint) so the shortcut is discoverable.

Usage

Do

  • Group commands by domain and label each group.
  • Add keywords so commands match the terms users actually type.
  • Enable bindShortcut for a global ⌘K and show a visible hint of it.
  • Put frequent shortcuts in each item's hint (⌘S, ⌘↵).

Don't

  • Use it as a form field — that's a Combobox or Select.
  • Hide it behind a shortcut with no on-screen affordance to reveal it exists.
  • Dump every command flat with no grouping — filtering gets noisy.
  • Duplicate ids across groups; each command id must be unique.

Accessibility

KeysAction
⌘K / Ctrl+KToggles the palette when bindShortcut is enabled.
↑ / ↓Moves the active command; the list wraps at the ends.
Home / EndJumps to the first / last command.
EnterRuns the active command and closes the palette.
EscCloses the palette without running anything.
  • Focus stays on the search input; the results are a role=listbox driven by aria-activedescendant.
  • The active option is announced via aria-activedescendant as you arrow through results.
  • Built on Radix Dialog: modal backdrop, focus trapped, focus restored on close.
  • Typing re-filters instantly and resets the active row to the first match.

CommandPalette props

PropTypeDefaultDescription
bindShortcutbooleanfalseRegister a global ⌘K / Ctrl+K listener that toggles the palette.
classNamestringMerged after the pds class on the panel.
defaultOpenbooleanInitial open state in uncontrolled mode.
emptyMessagestringNo resultsCopy shown when nothing matches the query.
groups *CommandGroup[]The command catalog, grouped. Empty groups (after filtering) are hidden.
onOpenChange((open: boolean) => void)Fires when the palette requests open/close (⌘K, Esc, backdrop, selection).
openbooleanControlled open state.
placeholderstringSearch commands…Search input placeholder.

Related

  • DialogA modal panel over a dimmed backdrop for focused tasks — forms, confirmations, and detail views that demand attention.
  • SearchInputAn Input specialised for queries — leading magnifier, sunken field, and a clear button once text is present.
  • DropdownMenuA menu of actions opened from a button — items, checkboxes, radio groups, and nested submenus with full keyboard navigation.
  • KbdKey cap — a small sunken mono chip for keyboard shortcuts.