Skip to content
Design System
Contact

Command palette

Keyboard-first search across actions and records with fuzzy matching.

Componentscmdk

Playground

An inline cmdk palette. Every result does something: pages and records open in the workspace, actions confirm with a toast, and Change theme opens a nested page that restyles the workspace.

Preview
Demo data
↑↓ Move↵ Run
WorkspaceSystem theme

Overview

Page

Recent commands

  • Run a command to see it here

Props

Size
example.tsxtsx
1import {
2 Command, CommandEmpty, CommandGroup, CommandInput,
3 CommandItem, CommandList, CommandSeparator, CommandShortcut,
4} from "@/components/ui/command"
5
6<Command loop className="rounded-xl border">
7 <CommandInput placeholder="Search or run a command…" />
8 <CommandList>
9 <CommandEmpty>No results. Try “invoice” or “theme”.</CommandEmpty>
10 <CommandGroup heading="Navigation">
11 <CommandItem keywords={["work"]} onSelect={() => router.push("/projects")}>
12 <FolderKanban />
13 Projects
14 <CommandShortcut>G P</CommandShortcut>
15 </CommandItem>
16 </CommandGroup>
17 <CommandSeparator />
18 <CommandGroup heading="Actions">
19 <CommandItem onSelect={() => setPages([...pages, "theme"])}>
20 <Palette />
21 Change theme…
22 <CommandShortcut>⌘T</CommandShortcut>
23 </CommandItem>
24 </CommandGroup>
25 </CommandList>
26</Command>

States

Real cmdk roots with a controlled selection. Highlight follows data-selected from both the pointer and the arrow keys, so hover and keyboard look the same.

States
  • Defaultrest
  • Hoverdata-selected
  • Focusinput :focus-visible
  • Loadingcmdk-loading
  • Disabledaria-disabled
  • Errorcmdk-empty
  • SuccessonSelect → done

Examples

The same content in a CommandDialog, and queries that show off matching, nesting, loading and the empty state.

Dialog with ⌘J

Or press ⌘J (Ctrl+J) anywhere on this page

Command palette

Search pages, actions and records

Try these in the playground
nwd
Fuzzy match on word starts finds Northwind renewal
bill
Keywords map synonyms to Create invoice
theme
Opens a nested page; Backspace on an empty input goes back
acme
Records load after a short delay with a loading row
zzz
The empty state suggests queries that do match

API

Props of the cmdk parts as used here. Nested pages are plain state: keep a stack and render a different list for the top page.

PropTypeDefaultDescription
Command.loopbooleanfalseArrow keys wrap from the last item to the first and back.
Command.shouldFilterbooleantrueTurn off when results come from a server that already filters them.
Command.filter(value, search, keywords) => number—Custom ranking. The default is a fuzzy score that favours word starts.
CommandInput.valuestring—Control the search, e.g. to clear it after running a command or when changing page.
CommandItem.onSelect(value: string) => void—Runs on click or Enter. Close the dialog here, then act.
CommandItem.keywordsstring[]—Extra terms that match without being shown, like synonyms or the record type.
CommandItem.disabledbooleanfalseVisible but skipped by the arrow keys. Say why in the item, e.g. Owners only.
CommandShortcutReactNode—Right-aligned hint. Display only; register the real shortcut separately.
CommandDialog.openboolean—Controlled open state for the dialog form, with title and description for screen readers.

Accessibility

Keyboard

Move the highlight
↑or↓
First or last result
HomeorEnd
Run the highlighted command
Enter
Leave a nested page (empty input)
Backspace
Open or close the dialog
⌘+J
Close the dialog
Esc

Semantics and ARIA

  • The input is a combobox that owns a listbox; focus stays in the input and aria-activedescendant points at the highlighted option.
  • Group headings label their role="group", so screen readers hear Navigation, Actions or Recent records when entering a group.
  • Disabled items keep aria-disabled and a reason instead of disappearing, and arrow keys skip them.
  • The loading row is role="progressbar" with a label; results that run an action confirm through a toast, which is a polite live region.
  • The dialog has a visually hidden title and description, traps focus and returns it to the trigger on close. ⌘K stays with the app shell.