import { Component } from '@angular/core';
import { WrCommandPalette } from 'ngwr/command-palette';
@Component({ imports: [WrCommandPalette] })
export class MyComponent {}Command Palette
A ⌘K search box that finds and runs your app's actions.
Installation
Import the class, and @use the entry point in your global styles: without it the component renders unstyled.
Basic usage
Add one palette to your app shell; mod+k opens it. (picked) fires after the item's own action().
<wr-command-palette
[items]="commands"
trigger="mod+k"
(picked)="onPicked($event)"
/>Live demo
Press ⌘⇧K / Ctrl+Shift+K: the site header owns ⌘K, and when two palettes share a hotkey the first one wins.
Programmatic control
Bind [(open)]; [trigger]="null" turns off the hotkey.
<button (click)="open.set(true)">Open palette</button>
<wr-command-palette
[items]="commands"
[(open)]="open"
[trigger]="null"
(picked)="onPicked($event)"
/>Backed by a server
Fetch on (searchChange) and feed the result into [items]. serverSearch turns off the built-in filter; [loading] shows “Searching…”.
<wr-command-palette
[items]="results()"
[(query)]="query"
[loading]="loading()"
serverSearch
[debounceMs]="250"
(searchChange)="search($event)"
/>API
| Name | Description | Type | Default |
|---|---|---|---|
paletteLabel | Accessible name. Falls back to commandPalette.label, then 'Command palette'. | string | null | null |
items | Items shown in the palette. | readonly WrCommandItem[] | [] |
open | Controlled open state (two-way bindable). | boolean | false |
trigger | Global hotkey that opens the palette. null disables auto-binding. | WrHotkeySpec | null | 'mod+k' |
placeholder | Search input placeholder. Falls back to commandPalette.placeholder. | string | null | null |
emptyText | Text shown when no items match. Falls back to commandPalette.noResults. | string | null | null |
loadingText | Overrides the commandPalette.loading catalog string, shown instead of {@link emptyText} while {@link loading} is true. | string | null | null |
closeOnPick | Auto-close on (picked). Set false to keep open. | boolean | true |
(picked) | Fires when the user commits an item (Enter / click). | WrCommandItem | — |
query | The search text. Two-way, so a host can seed it, clear it, or read what the user is looking for — the palette used to keep this to itself, which is what made it impossible to back with anything but a static items array. Writing it does NOT re-run a host's search on its own: the debounced {@link searchChange} output is what fires, on exactly the cadence {@link debounceMs} sets. | string | '' |
serverSearch | The item list is already scoped to the query upstream — skip the built-in client-side filter. Set it when [items] is fed from a server via the {@link searchChange} output. Without this, a backend that ranks or tolerates typos (returning rows whose labels do not literally contain the query) would have those rows hidden again on the client — the same rule wr-select follows, and the same reason. | boolean | false |
loading | A host-driven search is in flight. Swaps the empty row for {@link loadingText} — an async palette that says "No results" between every keystroke and its answer is stating something false. | boolean | false |
debounceMs | How long the query must settle before {@link searchChange} fires, in ms. A search request per keystroke is what exhausts a metered search backend: typing select is six requests at 0 and roughly one at 250. | number | 250 |
(searchChange) | The settled query. This is the hook for a server-backed palette: dispatch on it, then feed the result into [items] with [serverSearch] set. Fires on the {@link debounceMs} cadence, NOT per keystroke — queryChange is the per-keystroke signal if that is what you want. | string | — |
Types
| Name | Description | Type | Default |
|---|---|---|---|
WrCommandItem | { id, label, description?, group?, icon?, keywords?, shortcut?, action? } | interface | — |
[wrCommandPaletteFooter] | Slot for a strip under the list: a hint, a link, a key legend. | content slot | — |
CSS variables
Set these on the component's selector or a wrapper, not on :root: the defaults are declared on ngwr/command-palette's own element.
| Variable | Default | Declared on |
|---|---|---|
--wr-command-palette-body-padding | var(--wr-space-sm) | .wr-command-palette__body |
--wr-command-palette-empty-font-size | var(--wr-text-sm) | .wr-command-palette__empty |
--wr-command-palette-empty-padding-x | var(--wr-space-lg) | .wr-command-palette__empty |
--wr-command-palette-empty-padding-y | var(--wr-space-xl) | .wr-command-palette__empty |
--wr-command-palette-font-family | var(--wr-font-family-base) | .wr-command-palette |
--wr-command-palette-footer-font-size | var(--wr-text-xs) | .wr-command-palette__footer |
--wr-command-palette-footer-gap | var(--wr-space-sm) | .wr-command-palette__footer |
--wr-command-palette-footer-padding-x | var(--wr-space-lg) | .wr-command-palette__footer |
--wr-command-palette-footer-padding-y | var(--wr-space-sm) | .wr-command-palette__footer |
--wr-command-palette-group-padding-y | var(--wr-space-xs) | .wr-command-palette__group |
--wr-command-palette-group-title-font-size | var(--wr-text-xs) | .wr-command-palette__group-title |
--wr-command-palette-group-title-font-weight | var(--wr-font-weight-semibold) | .wr-command-palette__group-title |
--wr-command-palette-group-title-letter-spacing | var(--wr-tracking-wide) | .wr-command-palette__group-title |
--wr-command-palette-group-title-padding-bottom | var(--wr-space-xs) | .wr-command-palette__group-title |
--wr-command-palette-group-title-padding-top | var(--wr-space-sm) | .wr-command-palette__group-title |
--wr-command-palette-group-title-padding-x | var(--wr-space-md) | .wr-command-palette__group-title |
--wr-command-palette-hint-font-size | var(--wr-text-xs) | .wr-command-palette__hint |
--wr-command-palette-hint-font-weight | var(--wr-font-weight-medium) | .wr-command-palette__hint |
--wr-command-palette-hint-letter-spacing | var(--wr-tracking-wide) | .wr-command-palette__hint |
--wr-command-palette-hint-padding-x | var(--wr-control-padding-x-sm) | .wr-command-palette__hint |
--wr-command-palette-hint-padding-y | var(--wr-control-padding-y-sm) | .wr-command-palette__hint |
--wr-command-palette-hint-radius | var(--wr-border-radius-sm) | .wr-command-palette__hint |
--wr-command-palette-option-description-font-size | var(--wr-text-xs) | .wr-command-palette__option-description |
--wr-command-palette-option-description-margin-top | var(--wr-space-xs) | .wr-command-palette__option-description |
--wr-command-palette-option-font-size | var(--wr-text-sm) | .wr-command-palette__option |
--wr-command-palette-option-gap | var(--wr-space-md) | .wr-command-palette__option |
--wr-command-palette-option-label-font-weight | var(--wr-font-weight-medium) | .wr-command-palette__option-label |
--wr-command-palette-option-line-height | var(--wr-leading-tight) | .wr-command-palette__option |
--wr-command-palette-option-padding-x | var(--wr-space-md) | .wr-command-palette__option |
--wr-command-palette-option-padding-y | var(--wr-space-sm) | .wr-command-palette__option |
--wr-command-palette-option-radius | var(--wr-border-radius-sm) | .wr-command-palette__option |
--wr-command-palette-option-shortcut-font-size | var(--wr-text-xs) | .wr-command-palette__option-shortcut |
--wr-command-palette-option-shortcut-font-weight | var(--wr-font-weight-medium) | .wr-command-palette__option-shortcut |
--wr-command-palette-option-shortcut-padding-x | var(--wr-control-padding-x-sm) | .wr-command-palette__option-shortcut |
--wr-command-palette-option-shortcut-padding-y | var(--wr-control-padding-y-sm) | .wr-command-palette__option-shortcut |
--wr-command-palette-option-shortcut-radius | var(--wr-border-radius-sm) | .wr-command-palette__option-shortcut |
--wr-command-palette-padding-bottom | var(--wr-space-lg) | .wr-command-palette |
--wr-command-palette-padding-top | 6rem | .wr-command-palette |
--wr-command-palette-padding-x | var(--wr-space-lg) | .wr-command-palette |
--wr-command-palette-panel-radius | var(--wr-border-radius-base) | .wr-command-palette__panel |
--wr-command-palette-search-font-size | var(--wr-text-base) | .wr-command-palette__search |
--wr-command-palette-search-gap | var(--wr-space-md) | .wr-command-palette__search |
--wr-command-palette-search-padding | var(--wr-space-lg) | .wr-command-palette__search |
Dependencies
See also
Guide KeyboardBind shortcuts, show them as keycaps, and see which keys each component handles.Service WrHotkeyRegister keyboard shortcuts like mod+k, where mod is ⌘ on macOS and Ctrl elsewhere.Component KeyboardA keycap for showing a keyboard shortcut.Component Context MenuA right-click menu for any element.Component IconRenders an SVG icon you register by name; ngwr ships none of its own.Guide OverlayStyle ngwr's floating panels and control where focus goes.