Command palette uses a component for the overlay and typed command group data.

command-palette.ts
import {
  KuiButton,
  KuiCommandGroup,
  KuiCommandItem,
  KuiCommandPalette,
} from '@kikita-labs/ui';

Control open and query with signals, and run commands from the selected output.

<div class="basic-command-palette-example">
  <button kuiButton type="button" (click)="open.set(true)">Open command palette</button>

  @if (selectedCommand(); as command) {
    <p class="basic-command-palette-example__selection">Selected: {{ command }}</p>
  }

  <kui-command-palette
    [(open)]="open"
    [(query)]="query"
    [groups]="groups"
    (selected)="runCommand($event)"
  />
</div>

Items support metadata for rendering and keywords for search matching.

item data.ts
const groups: readonly KuiCommandGroup[] = [
  {
    heading: 'Project',
    items: [
      {
        id: 'rename',
        label: 'Rename project',
        description: 'Update the display name.',
        meta: 'Project',
        badge: 'New',
        shortcut: ['F2'],
        icon: 'R',
        keywords: ['edit', 'title'],
      },
      {
        id: 'delete',
        label: 'Delete project',
        danger: true,
        disabled: true,
      },
    ],
  },
];

Every command needs a stable, non-empty id without whitespace, unique across all groups of one palette, including disabled and filtered-out commands.

  • Use domain keys such as file.open and project.open; both may show the label "Open". Keep keys unchanged when you translate labels or recreate item objects, and never derive them from labels, array positions or per-render random values.
  • Development builds report invalid or duplicate ids. Production does not repair invalid data or generate replacement keys, so uniqueness is yours to keep.
  • selected emits the original complete item, not an id string: use item.id to dispatch the application action.
  • Changing the groups or the query resets keyboard activity to the first enabled match, and an empty result clears the active descendant. Separate palette instances namespace their option ids.

Set any of these on the component or an ancestor to restyle one part. Each token is optional: when it is not set, the part uses the role or scale token in the default column.

NameTypeDefaultDescription
--kui-command-input-placeholder-colorCSS custom property--kui-color-text-placeholderInput placeholder color
--kui-command-item-indicator-colorCSS custom property--kui-color-primary-indicatorItem indicator color
--kui-command-item-label-color-activeCSS custom property--kui-color-primary-soft-textItem label color, active
--kui-command-item-color-disabledCSS custom property--kui-color-text-disabledItem color, disabled
--kui-command-item-bg-dangerCSS custom property--kui-color-danger-soft-bgItem background, danger
--kui-command-item-match-colorCSS custom property--kui-color-primary-soft-textItem match color
--kui-command-badge-bgCSS custom property--kui-color-primary-soft-bgBadge background
--kui-command-badge-colorCSS custom property--kui-color-primary-soft-textBadge color
NameTypeDefaultDescription
--kui-command-backdrop-padding-inlineCSS custom property--kui-space-4Backdrop padding, inline
--kui-command-search-padding-inlineCSS custom property--kui-space-4Search padding, inline
--kui-command-input-font-sizeCSS custom property--kui-text-base-sizeInput font size
--kui-command-list-paddingCSS custom property--kui-space-1List padding
--kui-command-group-heading-padding-block-startCSS custom property--kui-space-3Group heading padding, block start
--kui-command-group-heading-padding-inlineCSS custom property--kui-space-3Group heading padding, inline
--kui-command-group-heading-padding-block-endCSS custom property--kui-space-1Group heading padding, block end
--kui-command-group-heading-font-sizeCSS custom property--kui-text-xs-sizeGroup heading font size
--kui-command-item-padding-inlineCSS custom property--kui-space-3Item padding, inline
--kui-command-item-radiusCSS custom property--kui-radius-smItem corner radius
--kui-command-item-label-font-sizeCSS custom property--kui-text-sm-sizeItem label font size
--kui-command-item-desc-font-sizeCSS custom property--kui-text-xs-sizeItem desc font size
--kui-command-footer-gapCSS custom property--kui-space-3Footer gap
--kui-command-footer-padding-blockCSS custom property--kui-space-2Footer padding, block
--kui-command-footer-padding-inlineCSS custom property--kui-space-4Footer padding, inline
--kui-command-footer-font-sizeCSS custom property--kui-text-xs-sizeFooter font size
--kui-command-footer-hint-gapCSS custom property--kui-space-1Footer hint gap
--kui-command-kbd-radiusCSS custom property--kui-radius-xsKbd corner radius
--kui-command-kbd-font-sizeCSS custom property--kui-text-2xs-sizeKbd font size
--kui-command-badge-radiusCSS custom property--kui-radius-fullBadge corner radius
--kui-command-badge-font-sizeCSS custom property--kui-text-2xs-sizeBadge font size
--kui-command-backdrop-padding-block-startCSS custom property--kui-space-6Backdrop padding, block start

Every text the component owns (accessible names, visible words, announcements) is a typed message with an English default. Override it for the application with provideKikitaUi({ messages }), or for a subtree with provideKuiMessages.

NameTypeDefaultDescription
placeholderstring — Search input placeholder. Default Type a command or search....
labelstring — Accessible name of the palette. Default Command palette.
emptystring — Text of the empty result state. Default No commands found.
emptyDescriptionstring — Description under the empty result text. Default Try a different query.
clearSearchstring — Name of the clear search button. Default Clear search.
keyUpstring — Key cap of the Up arrow in the footer. Default Up.
keyDownstring — Key cap of the Down arrow in the footer. Default Down.
keyEnterstring — Key cap of Enter in the footer. Default Enter.
keyEscapestring — Key cap of Escape in the footer. Default Esc.
hintNavigatestring — Footer hint next to the arrow keys. Default navigate.
hintRunstring — Footer hint next to Enter. Default run.
hintClosestring — Footer hint next to Escape. Default close.

Inputs and outputs verified against @kikita-labs/ui v2.0.0 public typings.

NameTypeDefaultDescription
openModelSignal<boolean> — Two-way model controlling overlay visibility.
groupsreadonly KuiCommandGroup[] — Command groups rendered in the list.
loadingboolean — Renders skeleton rows and sets aria-busy.
placeholderstring | undefined — Search input placeholder. Undefined when omitted: the text comes from the commandPalette.placeholder message.
labelstring | undefined — Accessible label for the modal dialog and search input. Defaults to the commandPalette.label message.
emptyTextstring | undefined — Empty-state title when no command matches. Defaults to the commandPalette.empty message.
queryModelSignal<string> — Two-way model for the current search value.
selectedOutputEmitterRef<KuiCommandItem> — Emits the selected command item.
messagesPartial<KuiCommandPaletteMessages> | undefinedundefinedPer-instance text overrides (placeholder, label, empty, emptyDescription, clearSearch, key hints and the rest). They win over scoped and root messages.
KuiCommandItem.idstring-Required stable key, unique across every group of one palette. Development builds report empty, whitespace-containing and duplicate ids.

The palette uses modal dialog semantics, focus trapping, and listbox navigation.

  • The palette renders through a CDK overlay with scroll blocking and a modal dialog container. Set label to describe the dialog and search input for screen readers.
  • A CDK focus trap keeps focus inside the palette while open. Focus returns to the element that opened the palette after it closes.
  • The search input exposes combobox and listbox relationships through aria-controls and aria-activedescendant.
  • Focus moves to the search input after the overlay has rendered, on every open, including when another control had focus.
  • Arrow keys move the active option; Enter selects it.
  • Escape closes the palette and restores focus.
  • Disabled commands are skipped by keyboard navigation and cannot be selected.
  • Setting loading renders skeleton rows and sets aria-busy on the list while results are pending.
  • Formal assistive-technology review is still pending for Command Palette per state-coverage.md; only static and browser smoke review have been completed so far.

Consumer-visible changes of @kikita-labs/ui 2.0 for Command Palette.

  • The class is KuiCommandPalette (it was KuiCommandPaletteComponent); ng update @kikita-labs/ui renames the import.
  • The placeholder and label inputs are undefined when omitted: the rendered text comes from the commandPalette messages, which you can translate through provideKikitaUi({ messages }) or the per-instance messages input.
  • Command ids must be stable, unique and non-empty; development builds report violations.
  • The search input is focused after the overlay renders instead of in a microtask.