Command Primitive

Command provides an accessible action-result primitive with label-only selection queries and separate keyword matching while product workflows remain consumer-owned.

Overview and decision boundary

Use Command for an accessible local action picker whose query, results, and selection events remain composable and consumer-owned.

Do not add hidden fuzzy ranking, remote fetching, route navigation, or global shortcut registration to Command.

Navigation
Open overviewConsumer-owned action
Browse documents shared across every regional workspaceConsumer-owned action
Workspace
Workspace settingsConsumer-owned action
Invite teammateConsumer-owned action
Archive workspaceUnavailable for archived workspaces

Selected value: None

import { Kbd } from "@nerio-ui/ui";import { Command, CommandEmpty, CommandInput, CommandItem, CommandList } from "@nerio-ui/ui/client";const items = [  { value: "settings", label: "Workspace settings", keywords: ["preferences"] },  { value: "archive", label: "Archive workspace", disabled: true },];<Command items={items}>  <CommandInput aria-label="Workspace commands" placeholder="Search commands" />  <CommandEmpty>No matching commands.</CommandEmpty>  <CommandList>    {(item) => (      <CommandItem        key={item.value}        value={item.value}        disabled={item.disabled}        shortcut={<Kbd aria-hidden> ,</Kbd>}        onSelect={(value, event) => runCommand(value, event)}      >        {item.label}      </CommandItem>    )}  </CommandList></Command>

Installation and imports

Install the editable registry source, or use the matching package entrypoint when the product keeps Nerio as a workspace dependency.

pnpm dlx nerio add command-primitiveimport { Kbd } from '@nerio-ui/ui';import { Command, CommandEmpty, CommandInput, CommandItem, CommandList } from '@nerio-ui/ui/client';

Usage

Open overviewConsumer-owned action
Workspace settingsConsumer-owned action
Invite teammateConsumer-owned action
Archive workspaceUnavailable for archived workspaces
<Command items={items} filter={false} query={query} onQueryChange={setQuery}>...</Command>
<Popover trigger="Open commands">  <Command>...</Command></Popover>
<Dialog trigger="Open dialog" title="Workspace commands">  <Command>...</Command></Dialog>
<Sheet>  <SheetTrigger render={<Button>Open sheet</Button>} />  <SheetContent><Command>...</Command></SheetContent></Sheet>
import { Kbd } from '@nerio-ui/ui';import { Command, CommandEmpty, CommandInput, CommandItem, CommandList } from '@nerio-ui/ui/client';const items = [{ value: "settings", label: "Workspace settings", keywords: ["preferences"] }];<Command items={items}>  <CommandInput aria-label="Workspace commands" placeholder="Search commands" />  <CommandEmpty>No matching commands.</CommandEmpty>  <CommandList>    {(item) => (      <CommandItem key={item.value} value={item.value} shortcut={<Kbd aria-hidden>,</Kbd>} onSelect={(value, event) => runCommand(value, event)}>        {item.label}      </CommandItem>    )}  </CommandList></Command>

Variants

Navigation
Open overviewConsumer-owned action
Browse documents shared across every regional workspaceConsumer-owned action
Workspace
Workspace settingsConsumer-owned action
Invite teammateConsumer-owned action
Archive workspaceUnavailable for archived workspaces

Selected value: None

<Command items={groupedItems}>...</Command>
ModeContract
LocalLocale-aware matching uses label, value, and keywords; selection writes only the visible label.
Consumer-filteredfilter={false}; consumers replace items during loading or remote work.
GroupedLabelled group records preserve stable leaf values and listbox semantics.
OverlayThe same inline primitive composes inside Popover, Dialog, or Sheet.

Anatomy

SlotPurpose
commandInline Base UI Autocomplete root.
command-inputRequired named combobox input; DOM focus remains here.
command-listFiltered listbox and grouped result renderer.
command-group / command-group-labelAccessible labelled result group.
command-itemStable action value with optional content slots.
command-item-leadingGeneral React content that owns its semantics; decorative Nerio Icons hide themselves.
command-empty / command-loadingDedicated polite status regions outside listbox children.

States

No matching commands.
<Command defaultQuery="no-match" items={items}>...</Command>
StateBehavior
Activearia-activedescendant tracks the keyboard or pointer-highlighted item.
DisabledVisible but skipped during keyboard navigation and never selected.
EmptyOne concise polite message after filtering.
LoadingA single Spinner and localized polite status for consumer-owned async work.
IME compositionEnter does not select until composition finishes.

Motion

  • Command itself does not animate active-item movement or query updates.
  • Popover, Dialog, and Sheet retain their own reduced-motion-aware overlay behavior.

Accessibility

  • Uses the Base UI Autocomplete combobox and listbox interaction model while keeping DOM focus on CommandInput through aria-activedescendant.
  • CommandInput requires a visible label, aria-label, or aria-labelledby; placeholder text is not an accessible name.
  • Arrow keys navigate enabled items, disabled items are skipped, Enter selects the active item, and Escape bubbles to enclosing Popover, Dialog, or Sheet dismissal behavior.
  • Home and End preserve native input editing because virtual focus remains on the query field.
  • Base UI suppresses Enter selection during IME composition and supports pointer highlighting and selection without moving DOM focus into items.
  • Selection writes only the visible item label into controlled or uncontrolled query and form values; keywords and stable values are matching-only text.
  • CommandItem leading content owns its accessibility semantics; decorative Nerio Icons remain hidden through their own default contract.
  • CommandEmpty and CommandLoading use dedicated polite Base UI status regions and are not arbitrary children of the listbox.
  • RTL, long localized labels, compact density, reduced motion, and forced colors are supported through semantics and tokens.
  • Fetching, ranking, routing, permissions, analytics, history, global shortcuts, and complete command-palette workflows remain consumer or Pro responsibilities.

API

APIPurpose
itemsFlat CommandItemData or labelled CommandGroupData records with stable values.
query / defaultQuery / onQueryChangeControlled or uncontrolled visible query; selection writes the item label only.
filterTyped matcher over leaf items; default search includes label, value, and keywords, or false preserves external results.
onActiveValueChangeReports stable highlighted values without exposing internal indices.
CommandItem.onSelectEmits the stable value and event while the visible query remains label-only.

Implementation contract

ContractValue
Registry itemcommand-primitive installs 7 source files into the configured components directory.
Base UIautocomplete
Registry dependenciesspinner
Package dependencies@base-ui/react, @nerio-ui/adapters, clsx, react, tailwind-merge, tailwindcss

Styling contract

ContractValue
AuthoringComplete, statically detectable Tailwind CSS v4 recipes own component visuals.
ValuesSemantic and component --n-* variables remain the canonical customization layer.
OverridesCustomizable slots merge consumer className values with tailwindCn so conflicting utilities resolve deterministically.
Residual CSSOnly shared keyframes and scoped no-Preflight compatibility rules remain; there is no parallel visual selector layer.

Design notes

  • Command is not GlobalSearch, EntitySearch, Documentation Search, or a complete Command Palette.
  • Fetching, ranking, routing, permissions, analytics, history, recent items, and global shortcuts stay outside Core.
  • Use consumer state to replace items and toggle CommandLoading for asynchronous results.
  • Leading content is general React content and owns its semantics; use decorative Nerio Icons when no accessible meaning is needed.

Do / do not

Do

Use for local commands and compact action pickers; compose icons, descriptions, metadata, and Kbd.

Do not

Turn Core Command into GlobalSearch, Documentation Search, a routed palette, remote ranking, history, or global shortcut registration.

Tokens

These are the primary customization points. Override semantic or component tokens instead of changing component source.

TokenPurpose
--n-command-widthPublic customization point for this component contract.
--n-command-list-max-heightPublic customization point for this component contract.
--n-command-input-heightPublic customization point for this component contract.
--n-command-item-heightPublic customization point for this component contract.
--n-command-item-padding-blockPublic customization point for this component contract.
--n-command-item-padding-inlinePublic customization point for this component contract.
--n-command-list-paddingPublic customization point for this component contract.
--n-command-group-gapPublic customization point for this component contract.
--n-command-group-spacingPublic customization point for this component contract.
--n-command-item-gapPublic customization point for this component contract.
--n-command-state-min-heightPublic customization point for this component contract.
--n-command-state-paddingPublic customization point for this component contract.
--n-command-backgroundPublic customization point for this component contract.
--n-command-foregroundPublic customization point for this component contract.
--n-command-border-widthPublic customization point for this component contract.
--n-command-borderPublic customization point for this component contract.
--n-command-radiusPublic customization point for this component contract.
--n-command-item-radiusPublic customization point for this component contract.
--n-command-item-background-activePublic customization point for this component contract.
--n-overlay-backgroundPublic customization point for this component contract.
--n-overlay-foregroundPublic customization point for this component contract.
--n-overlay-foreground-mutedPublic customization point for this component contract.
--n-overlay-control-backgroundPublic customization point for this component contract.
--n-overlay-surface-filterPublic customization point for this component contract.
--n-overlay-shadowPublic customization point for this component contract.
--n-input-foreground-on-overlayPublic customization point for this component contract.
--n-input-placeholder-on-overlayPublic customization point for this component contract.
--n-focus-ringPublic customization point for this component contract.