CommandPalette
Search and jump: pages, servers, skills and actions from one ⌘K / Ctrl+K box.
Examples
With its own trigger
The live, page-wide palette is the "Search docs" box in the topbar: press ⌘K / Ctrl+K anywhere. This second palette passes shortcut={false} so only its button opens it. Choosing an item here only changes the URL hash.
<CommandPalette
id="servers-palette"
trigger
shortcut={false}
triggerLabel="Jump to a server or skill"
placeholder="Search servers, skills, actions…"
items={[
{ group: 'Servers', label: 'GitHub', href: '/servers/github', icon: 'github', hint: 'mcp.github.com' },
{ group: 'Servers', label: 'Linear', href: '/servers/linear', icon: 'server', hint: 'mcp.linear.app' },
{ group: 'Servers', label: 'Sentry', href: '/servers/sentry', icon: 'server', keywords: ['errors'] },
{ group: 'Skills', label: 'Triage new issues', href: '/skills/triage', icon: 'book-open' },
{ group: 'Actions', label: 'Add server', href: '/servers?dialog=add-server', icon: 'plus' },
{ group: 'Actions', label: 'Rotate token', href: '/settings/tokens', icon: 'key' },
]}
/>Usage
import { CommandPalette } from '@switchboard/ui'
// Once, in the app topbar.
<CommandPalette items={commandItems} trigger />Props
Every component also takes mix, for css() and mixins applied after its own style.
CommandPalette
| Prop | Type | Default | Description |
|---|---|---|---|
| items* | CommandItem[] | – | Grouped in the order their group first appears. |
| id | string | 'command-palette' | id of the <dialog>. Give a second palette on the page its own. |
| trigger | boolean | – | Render the search-style trigger button. Without it only the shortcut opens the palette. |
| triggerLabel | string | 'Search or jump to…' | Trigger text. |
| placeholder | string | 'Search pages, servers, skills…' | Search input placeholder. |
| shortcut | boolean | true | Toggle on ⌘K / Ctrl+K. Only one palette per page should listen. |
| defaultOpen | boolean | – | Start open (tests, demos). |
CommandItem
| Prop | Type | Default | Description |
|---|---|---|---|
| group* | string | – | Group heading: "Servers", "Skills", "Actions". |
| label* | string | – | Item text; the first query word is bolded in it. |
| href* | string | – | Where choosing goes. Also the item key, so unique. |
| icon | IconName | 'chevron-right' | Leading icon. |
| keywords | string[] | – | Extra search terms: aliases, ids. |
| hint | string | – | Right-aligned mono hint, e.g. a host. |
Choosing dispatches a cancelable sb:command event ({ href }) on the dialog, then navigates unless prevented.
Accessibility
- A modal <dialog> named "Command palette": page inert, Escape closes, focus returns to what had it.
- The input is a combobox with aria-activedescendant over a grouped listbox; focus stays in the input while arrows move the highlight.
- Arrow keys move, Ctrl+Home/End jump, Enter opens. "No matches" is announced through role="status".
- The trigger advertises the shortcut with aria-keyshortcuts (omitted when shortcut is false).
Guidance
Do
- Mount one listening palette per page, in the topbar.
- Add keywords for names people search by: ids, old names, hosts.
Don’t
- Mount two palettes that both listen for ⌘K / Ctrl+K.
- Put destructive actions in the palette; link to the page that has them.