components / commandpalette

CommandPalette

Centered search-and-action surface for fast command execution, grouped results, and optional mod+k invocation.

Overview

What it is

This section explains the intent of the component before the implementation details.

  • CommandPalette is the fast-path action surface for keyboard-driven product flows.
  • It brings filtering, grouped commands, and decisive action execution into one centered overlay.

Aliases

command menu, quick actions

Decision guide

How to choose it

Use these notes to decide quickly whether this is the right DK component for the job.

Decision guide

  • Choose CommandPalette when the interaction should feel deliberate, documented, and reusable across product surfaces.
  • If the scenario is more specialized than the current CommandPalette contract, prefer a simpler component or build a dedicated workflow on top of the lower-level DK primitives.

Do

  • Keep the CommandPalette label, value, or status language direct enough to scan quickly.
  • Use the documented size and state recipes instead of inventing one-off variants in product code.

Do not

  • Do not hide the main purpose of CommandPalette behind decorative copy or overloaded surface treatments.
  • Do not stretch CommandPalette into a workflow it was not designed to handle just because the visuals are close.

Usage

When to use

Prefer these situations when choosing this component.

  • Use CommandPalette when the user should be able to jump to an action faster than scanning regular navigation.
  • Use sections and keywords so the palette stays searchable as the command set grows.

Usage

When not to use

These patterns are better served by a different component or a simpler surface.

  • Do not use CommandPalette as a replacement for everyday primary navigation.
  • Do not hide essential first-run actions behind the palette alone.

Anti-patterns

  • Using CommandPalette as a generic layout container instead of a purpose-built interaction or content surface.
  • Forking the documented recipe in product code instead of extending the shared DK contract.

Migration notes

  • Migrate legacy commandpalette usage by mapping existing variants and states onto the documented DK props before porting any custom styling.
  • Treat the docs examples as the reference contract for accessibility and event behavior during adoption.

Anatomy

Structural parts

The anatomy explains which pieces matter to the recipe and accessibility model.

command shell

surface

Centered overlay surface that owns the filter input and result list.

command query

input

Combobox-style query field for filtering commands.

command option

item

Single command row with optional section and shortcut metadata.

API

Public interface

The docs contract distinguishes props, DOM events, and slots so integration behavior is explicit.

Props

NameTypeDefaultDescription
openbooleanfalseControlled open state.
itemsArray<{ id: string; label: string; section?: string; shortcut?: string; keywords?: string[]; disabled?: boolean }>Command definitions available in the palette.
querystring''Controlled query string.
placeholderstring'Search commands'Query input placeholder.
emptyTitlestringHeading shown when filtering returns no results.
emptyDescriptionstringSupporting empty-state guidance.
hotkey'mod+k' | falsefalseEnables or disables the global mod+k launcher.
onOpenChange(detail: { open: boolean }) => voidCallback fired when the palette opens or closes.
onQueryChange(detail: { query: string }) => voidCallback fired when the query changes.
onAction(detail: { id: string }) => voidCallback fired when a command is executed.
themeThemeContractOverrides the compiled DK theme used to resolve tokens and recipes for this component.

Events

NamePayloadDescription
openchange{ open: boolean }Fires when an overlay-style component opens or closes through user interaction.
querychange{ query: string }Fires when the filter query changes.
action{ id?: string; value?: string }Fires when the component exposes a primary action and the user activates it.

Slots

NameDescription
defaultCommandPalette is data-driven in v1 and does not expose command item slots.

Recipes

Variants, sizes, and states

These notes summarize the intended recipe surface rather than exposing raw implementation detail first.

Variants

  • default: One centered command shell with grouped results and optional hotkey.

Sizes

  • default: CommandPalette uses one width recipe tuned for search and action scanning.

States

  • closed: Palette hidden
  • open: Palette visible
  • highlighted: One command is active for keyboard execution

Accessibility

Accessibility contract

This is the behavior the component promises to assistive tech and keyboard users today.

Semantics

  • Uses dialog-style overlay semantics with a searchable command list.

Keyboard

  • Supports Arrow navigation, Enter commit, Escape dismissal, and optional mod+k opening.

Screen readers

  • Command labels remain explicit, with grouped sections and disabled commands still announced clearly.

Checklist

  • Verify the visible label or title still produces a clear accessible name.
  • Verify focus remains obvious in every supported state and size.
  • Verify disabled, selected, and error states do not rely on color alone.

Implementation

Tokens and slot vars

This section shows the representative compiled slot variables that the runtime consumes for the selected design system.

root

--dk-command-gap
0.5rem
--dk-command-offset
24px

backdrop

--dk-command-backdrop-bg
color-mix(in srgb, black 42%, transparent)

surface

--dk-command-surface-bg
#f2f5fb
--dk-command-surface-fg
#16181c
--dk-command-surface-border
#95989d
--dk-command-surface-shadow
0 10px 15px rgba(0, 0, 0, 0.06), 0 4px 6px rgba(0, 0, 0, 0.04)
--dk-command-surface-radius
clamp(1.333rem, 1.2222rem + 0.494vw, 1.667rem)
--dk-command-surface-width
min(42rem, calc(100vw - 2rem))
--dk-command-surface-max-height
min(32rem, calc(100vh - 3rem))
--dk-command-surface-padding
0.75rem

input

--dk-command-input-bg
#f2f5fb
--dk-command-input-fg
#16181c
--dk-command-input-border
#95989d
--dk-command-input-radius
clamp(0.75rem, 0.6875rem + 0.278vw, 0.938rem)
--dk-command-input-block-size
48px
--dk-command-input-inline-padding
0.875rem
--dk-command-input-font-size
0.95rem

section

--dk-command-section-fg
#16181c
--dk-command-section-size
0.72rem

item

--dk-command-item-bg
#f2f5fb
--dk-command-item-fg
#16181c
--dk-command-item-radius
clamp(0.75rem, 0.6875rem + 0.278vw, 0.938rem)
--dk-command-item-min-height
44px
--dk-command-item-inline-padding
0.75rem

itemLabel

--dk-command-item-label-size
0.95rem
--dk-command-item-label-weight
600

itemMeta

--dk-command-item-meta-fg
#16181c
--dk-command-item-meta-size
0.75rem

empty

--dk-command-empty-fg
#16181c
--dk-command-empty-size
0.9rem

Implementation notes

  • CommandPalette is intentionally data-driven in v1 so the command surface stays deterministic for docs, proofs, and hotkey behavior.

Implementation checklist

  • Use the public component API first and only drop to lower-level primitives when the component contract genuinely does not fit.
  • Keep theme overrides token-driven so proofs and recipes stay meaningful.
  • Verify the shipped examples and proof fixtures still represent the real product scenario you are implementing.

Examples

Copy-paste examples

Each example is intentionally practical, grouped by starter, common pattern, and edge-case coverage.

Examples
3
Depth
expanded

Starter

1 example

starter

Starter: filtered command runner

A centered command surface with grouped actions.

Copy snippet

<CommandPalette open={isOpen} items={commands} onAction={(detail) => runCommand(detail.id)} />

Common patterns

1 example

common

Common: global mod+k launcher

Enable the built-in hotkey when the app has a strong command model.

Copy snippet

<CommandPalette hotkey="mod+k" items={commands} open={isOpen} onOpenChange={(detail) => isOpen = detail.open} />

Edge cases

1 example

edge

Edge: externally controlled query

Control the query when search state also drives analytics or suggestions elsewhere in the app.

Copy snippet

<CommandPalette open={isOpen} query={query} onQueryChange={(detail) => query = detail.query} items={commands} />

Verification

Curated proof fixtures

Proofs stay visible in the docs so the system shows what it can guarantee, not just what it can render.

default

pass

  • Contrast: 98.5 Lc
  • Target: 48px
  • Rows: 44px
  • Surface: 672x512

selected

pass

  • Contrast: 98.5 Lc
  • Target: 48px
  • Rows: 44px
  • Surface: 672x512