Command

A headless command palette with search filtering, keyboard navigation, and grouped options.

Features

  • Built-in filtering
  • Keyboard-first
  • Grouped options
  • Fallback content
  • Controlled or uncontrolled
  • Headless styling

Installation

npm install @ariaui/command

Examples

Command palette with grouped options, typeahead filtering, optional shortcut hints, a clear control via Command.Button, and a "no results" fallback.

Styling uses semantic tokens from @ariaui/tokens; icons are from @heroicons/react/24/outline. The fence is generated from the same JSX as the preview.

Default

Default command menu using @ariaui/command with grouped options, filtering, and an empty state.

Preview

No preview output yet.

live.tsxReady

Anatomy

tsx
import * as Command from "@ariaui/command";

export default function Example() {
  return (
    <Command.Root>
      <Command.Input />
      <Command.Content>
        <Command.Empty />
        <Command.Group>
          <Command.Label />
          <Command.Option />
        </Command.Group>
        <Command.Separator />
        <Command.Loading />
      </Command.Content>
    </Command.Root>
  );
}

API Reference

Root

State container on a focusable wrapper. Owns selection, search filtering, grouped visibility, and keyboard routing.

PropTypeDefault
value
string
defaultValue
string""
onValueChange
(value: string) => void
searchValue
string
defaultSearchValue
string""
onSearchValueChange
(value: string) => void
filter
(value: string, search: string, keywords?: string[]) => boolean | numbersubstring match
shouldFilter
booleantrue
label
string
loop
booleanfalse
disablePointerSelection
booleanfalse
AttributeValues
tabIndex-1 (Root is roving container for key events)

Input

Combobox input wired to Root search state. Typing filters options by default.

PropTypeDefault
onValueChange
(value: string) => void
value
string
AttributeValues
rolecombobox
aria-controlsID of Content listbox
aria-labelledbyHidden label from Root
aria-autocompletelist
aria-activedescendantID of active Option
aria-expandedtrue

Content

Listbox region for options and structural helpers.

PropTypeDefault
label
string"Suggestions"
AttributeValues
rolelistbox
aria-activedescendantID of the active Option

Empty

Renders children only while there are mounted options yet zero visible matches after filtering.

AttributeValues
rolepresentation

Loading

Progressbar slot for async data.

PropTypeDefault
label
string"Loading..."
progress
number
AttributeValues
roleprogressbar

Group

Groups options. Stays hidden when every child option is filtered out unless `forceMount`.

PropTypeDefault
heading
React.ReactNode
forceMount
booleanfalse
value
string
AttributeValues
rolegroup
aria-labelledbyWhen heading is provided
hiddenWhen no visible children

Label

Standalone label element for custom layouts.

Option

Selectable row. Filters against search text unless `forceMount`.

PropTypeDefault
value*
string
disabled
booleanfalse
keywords
string[][]
forceMount
booleanfalse
onSelect
(value: string) => void
AttributeValues
roleoption
aria-selectedMatches active highlight (typeahead / pointer / keyboard)
aria-disabledWhen disabled
data-selectedMirror of active highlight
data-disabledWhen disabled
data-valueOption value string

Separator

Divides groups; hides while searching unless `alwaysRender`.

PropTypeDefault
alwaysRender
booleanfalse
AttributeValues
roleseparator

Keyboard

ShortcutAction
Move active highlight to the next option; wraps when `loop` is true.
Move active highlight to the previous option; wraps when `loop` is true.
Ctrl+N/Ctrl+JMove active highlight down; wraps when `loop` is true (same as ArrowDown).
Ctrl+P/Ctrl+KMove active highlight up; wraps when `loop` is true (same as ArrowUp).
HomeMove to the first enabled visible option.
EndMove to the last enabled visible option.
EnterSelect the active option (updates `value` and runs `onSelect`).

Accessibility

The Command primitives implement the WAI-ARIA Combobox pattern adapted for command palette use:

  • Input carries role="combobox" with aria-controls pointing to the Content listbox and aria-autocomplete="list".

  • Content renders as role="listbox" and tracks the active option via aria-activedescendant.

  • Each Option exposes role="option" with aria-selected when active and aria-disabled when disabled.

  • DOM focus stays on the Input during keyboard navigation; the active option is communicated via aria-activedescendant.

  • Separator uses role="separator" for proper semantics between groups.

Previous
Combobox