GitHub

Command Palette

Filterable command overlay. Set the commands property, then open with the button or ⌘/Ctrl + K. Arrow keys navigate, Enter runs, Esc closes.

Stable wc import '@esa/ecology/esa-command-palette';

Preview

Commands are set in a script: el.commands = [{ id, label, group, action }, …].

<button id="open-cmdk">Open command palette</button>

<esa-command-palette id="cmdk"></esa-command-palette>

API

PropTypeDefaultDescription
commands EsaCommand[] [] Command registry, set as a property. Each: { id, label, description?, shortcut?, group?, keywords?, disabled?, action }.
open boolean false Reflected open state.
hotkey boolean true Registers the global Cmd/Ctrl+K toggle listener.

Methods

PropTypeDefaultDescription
show() method Opens the palette, clears the query, and focuses the input.
close() method Closes the palette.
toggle() method Toggles open state — also bound to Cmd/Ctrl+K.

Selecting a command runs its action callback, then closes the palette — there is no separate event.

Accessibility

  • The overlay is role="dialog"; the results list is role="listbox" with role="option" items and aria-selected.
  • ArrowUp / ArrowDown move the active option (wrapping), Enter executes, Esc closes.
  • The search input is focused automatically when the palette opens.

Theming surface

Every public token this component reads, extracted from its source at build time. The Resolves to column walks each token's real lineage — component → semantic → primitive → raw value — so you can see exactly where re-pointing it lands. A spoke re-skins by overriding these in its theme-<slug>.css; component internals are never edited. No hook for what you need? File it with /request-lego.

TokenTierResolves to
--command-palette-bg component #fcfcfc via --color-surface-elevated--color-gray-1
--command-palette-border-color component #cecece via --color-border--color-gray-7
--command-palette-item-bg-active component #f0f0f0 via --color-surface-sunken--color-gray-3
--command-palette-max-height component 440px
--command-palette-radius component 0.75rem via --radius-400
--command-palette-shadow component 0 20px 60px rgba(0, 0, 0, 0.2)
--command-palette-width component 560px
--focus-ring-color component #65ba74 via --color-border-focus--color-grass-8
--focus-ring-width component 2px
--color-backdrop semantic rgba(0, 0, 0, 0.5) via --color-black-a-7
--color-border semantic #cecece via --color-gray-7
--color-border-light semantic #d9d9d9 via --color-gray-6
--color-surface-sunken semantic #f0f0f0 via --color-gray-3
--color-text-muted semantic #838383 via --color-gray-10
--color-text-primary semantic #202020 via --color-gray-12
--font-sans semantic 'DM Sans', sans-serif
--letter-spacing-wide semantic 0.03em
--type-size-100 semantic clamp(0.625rem, 0.56rem + 0.32vw, 0.75rem)
--type-size-150 semantic clamp(0.6875rem, 0.61rem + 0.38vw, 0.875rem)
--type-size-200 semantic clamp(0.75rem, 0.66rem + 0.44vw, 0.9375rem)
--type-size-300 semantic clamp(0.875rem, 0.77rem + 0.52vw, 1.125rem)
--font-weight-medium primitive 500
--font-weight-semibold primitive 550
--radius-100 primitive 0.25rem
--radius-200 primitive 0.5rem
--spacing-100 primitive 0.25rem
--spacing-200 primitive 0.5rem
--spacing-300 primitive 0.75rem
--spacing-400 primitive 1rem
--spacing-600 primitive 2rem
--z-modal primitive 400
--z-modal-backdrop primitive 300