Command
Command — the ⌘K palette: type, see what matches across the product, pick with the keyboard.
Beta · Navigation and overlay · packages/css/src/components/command.css
.pui-command · __search __list — groups of .pui-menu-item under Dropdown menu’s group labels, an inline Empty.
Sizes across, states down.
What it is for
Section titled “What it is for”- Placeholder / Has placeholder, Query / Has query — the search row; Group 1 and Group 2 labels, Has group 2; Has empty + Empty text
- Items 1–6 are exposed Menu items — label, icon, shortcut, state; the first sits in hover as the keyboard’s current row
- At most eight rows before the list scrolls (a rule, not drawn); no footer — a hint row of caps is a later addition if a screen asks
Use when a product has more places and actions than a rail shows — MAFO’s search across campaigns, offers and publishers; jumping to a setting; running an action by name. Opens with ⌘K and from the Topbar’s search.
Do not use when the list is one field’s options (Combobox); the actions belong to one thing (Dropdown menu); on the site.
Relates to Dialog, Scrim, Menu item, Kbd, Combobox menu, Empty, Topbar, Dropdown menu.
Anti-patterns a palette without a keyboard shortcut · results without groups when they come from different places · a row without its icon among rows with icons · a palette wider than 512 · a fill changed on the instance.
Keywords: command, command palette, ⌘K, global search, cmdk, spotlight
Figma — page Command: Command (1 variants)
shadcn: command
The markup — copy this
Section titled “The markup — copy this”The class, the parts, and nothing that is not in the package. The same block opens command.css.
<div class="pui-command" role="dialog" aria-label="Command palette"> <div class="pui-command__search"><span class="pui-icon">…search…</span><input placeholder="Type a command…"><kbd class="pui-kbd">Esc</kbd></div> <div class="pui-command__list"> <div class="pui-dropdown-menu__group-label">Offers</div> …pui-menu-item… <div class="pui-dropdown-menu__separator"></div> <div class="pui-empty pui-empty--inline">No results found.</div></div></div>Keyboard the search input holds the tab stop; every row takes tabindex="-1". The script owes Up / Down over the rows, Enter to run, Escape to close and return focus to whatever opened the palette.Accessibility — measured, not assumed
Section titled “Accessibility — measured, not assumed”Every number here is measured on the rendered component: contrast (npm run contrast:render), the focus ring (npm run focus) and the keyboard (npm run keyboard). The floors are principle 12’s.
Contrast
Section titled “Contrast”| ink on ground | reads | floor | the matrix calls it | |
|---|---|---|---|---|
#544d4d on #f2f2f2 |
7.36 | 4.5 | text.muted on surface.sunken (promised) | ok |
#544d4d on #ffffff |
8.24 | 4.5 | text.muted on surface.page (promised) | ok |
#0b0202 on #f2f2f2 |
18.32 | 4.5 | text.default on surface.sunken (promised) | ok |
#0b0202 on #ffffff |
20.51 | 4.5 | text.default on surface.page (promised) | ok |
4 distinct pair(s) rendered, 0 that axe calls a violation.
The focus ring
Section titled “The focus ring”| primitive | on | the indicator | over | the change | |
|---|---|---|---|---|---|
| Command search | surface/page | shadow-inset #6a66e4 2 px |
#ffffff |
4.53 | ok |
6 of 6 focus stop(s) in this block meet WCAG 2.4.13 on screen — the same crop screenshotted focused and unfocused, and the difference measured.
Keyboard
Section titled “Keyboard”| role | tab stops | what the pattern requires | |
|---|---|---|---|
dialog .pui-command |
1 | — | — |
What the consumer’s script owes. the search input holds the tab stop; every row takes tabindex=“-1”. The script owes Up / Down over the rows, Enter to run, Escape to close and return focus to whatever opened the palette.
Tab order across the whole library is document order over 344 stops, and Shift+Tab is its exact reverse — no keyboard trap anywhere (WCAG 2.1.2).
Pepper UI v1.5.0
The Mobupps design system. 386 tokens, 88 components, 65 pages in the workshop — every page of this site generated from the repository, so nothing here is typed twice.