Command palette
A modal search over whatever the app can name — pages, parcels, councils, commands. This site's own ⌘K runs on it, so the behaviour is proven, not promised.
Anatomy
Code
<GdCommandPalette
ref="palette"
:items="[
{ title: 'Button', group: 'Components', to: '/components/button' },
{ title: 'Toggle the theme', group: 'Actions', onSelect: toggleTheme }
]"
/>
<!-- anywhere: -->
palette.value?.open()What it is, and is not
- An item is a destination OR an action.
tonavigates,onSelectruns — one per row, so the label can say what Enter does. - Scoring is deliberately dumb: startsWith beats includes beats keyword beats group. Simple, explainable, right often enough. An app with ten thousand parcels should filter server-side and hand this the top slice — see GdSearchSuggest for that shape.
- Parked high, not centred. A results list grows downward; a centred dialog walks down the screen as you type.
- The docs site's own ⌘K is this component.
GdDocsSearchis a thin wrapper that flattens the docs nav into items — same palette, docs-shaped index. - One hotkey listener per page. The specimen above turns
hotkeyoff because the site's own palette is already listening — two listeners on one chord is a coin toss.
API
Props
itemsrequiredGdCommandItem[]—Everything the palette can reach — destinations (`to`) and actions (`onSelect`). One of the two per item, not both: a row that navigates AND mutates has a label that cannot tell the truth about what Enter does.
placeholderstring"Search…"The input's placeholder.
labelstring"Search"The input's accessible name.
hotkeybooleantrueListen for ⌘K / Ctrl-K globally. Turn it off when two palettes share a page — two listeners on one chord is a coin toss. This specimen does exactly that, because the site's own ⌘K is already listening.
Slots
emptyThe no-results message. Receives { query }.
Events
select[item: GdCommandItem]A row was chosen — after the navigation or the action, either way.
Exposes open() and close() — mount it once and open it from a navbar button, a shortcut, or anywhere else.