Command

Pro

A searchable command palette: the Cmd-K menu. Arrows move the highlight, Enter runs the active row, and focus never leaves the input. Built on Radix Dialog; filtering and the roving highlight are hand-rolled.

Press ⌘ K or click the button.

Installation#

# One-time setup (tokens + lib helpers)npx koalaui-cli@latest init# Activate your Pro license (once per machine)npx koalaui-cli@latest login <key># Add this component (its dependencies come along)npx koalaui-cli@latest add command

Usage#

This example is part of Koala UI Pro

The preview is yours to explore. Its code comes with a Pro license, paid once and used in every project.

Have a license? Unlock it here

Each CommandItem has a required value (its searchable identity) and an optional keywords array for synonyms. A row that doesn't match the query removes itself, so empty groups and the CommandEmpty state collapse on their own.

Anatomy#

import {  CommandDialog,  Command,  CommandInput,  CommandList,  CommandEmpty,  CommandGroup,  CommandItem,  CommandSeparator,  CommandShortcut,} from "@/components/ui/command"<Command>  <CommandInput />  <CommandList>    <CommandEmpty />    <CommandGroup>      <CommandItem>        <CommandShortcut />      </CommandItem>    </CommandGroup>    <CommandSeparator />  </CommandList></Command>{/* or, as a modal: CommandDialog in place of Command */}<CommandDialog>  <CommandInput />  <CommandList /></CommandDialog>

Inline#

Skip CommandDialog and use Command directly to embed the palette in a page or a Popover. It brings its own surface, so it reads as a finished card on any background. Disabled rows stay visible but drop out of the keyboard order.

Create
New project
Invite teammate
Navigate
Dashboard
Account
Support (offline)

Highlight with ↑ ↓, run with Enter.

Keyboard#

The search field keeps focus while you navigate (the active row is announced through aria-activedescendant): ↑ / ↓ move the highlight (wrapping at the ends), Home / End jump to the first and last rows, Enter runs the active row, and (inside CommandDialog) Esc closes. Wire a global ⌘K / Ctrl+K listener to toggle the dialog.

This example is part of Koala UI Pro

The preview is yours to explore. Its code comes with a Pro license, paid once and used in every project.

Have a license? Unlock it here

Motion#

The palette is tuned to keep up with the keyboard. One shared highlight glides between rows as you arrow or sweep the pointer (it jumps without easing when typing changes the rows under it), the list eases its height as the query trims or restores results, and CommandDialog opens and closes on the fast duration, growing down from the search field. The dialog is centered on screen as the full-height panel, so the field you type into stays put while results shrink beneath it. Each motion is a CSS transition, so a held arrow key retargets smoothly instead of queueing. Under prefers-reduced-motion the glide, the height ease and the zoom switch off, leaving a plain fade on the dialog.

Density#

Like the rest of Koala, Command honors the cross-cutting density axis (or a DensityProvider): compact tightens the search height and row padding for an information-dense surface, never touching color or radius.

Appearance
Light
Dark
System
Resources
GitHub repository

API reference#

Command

The palette root: owns the query and the roving highlight, and paints the popover surface. Forwards all native <div> props; every part accepts className, merged last.

PropTypeDefaultDescription
searchstring-Controlled search query.
defaultSearchstring""Initial query when uncontrolled.
onSearchChange(search: string) => void-Fires on every keystroke in the search field.
filter(search: string, value: string, keywords?: string[]) => numbersubstring matchReturn 0 to hide a row, any positive number to keep it. The default is a case-insensitive substring match on value and keywords; an empty query keeps every row.
onSelect(value: string) => void-Fires when any row is chosen, after that row's own onSelect.
labelstring"Commands"Accessible name for the search field and the result list.
density"comfortable" | "compact""compact"Search row height and row padding. Falls back to the nearest DensityProvider.
CSS variableDescription
--surfaceSet to var(--popover), read by nested controls.
--command-list-maxCaps the list height; defaults to min(28rem, 64vh).

CommandDialog

The palette in a Radix Dialog (focus trap, scroll lock, Escape to close), opening on the fast duration and hung from its search field. Takes every Command prop; className goes on the positioned dialog content, not the palette.

PropTypeDefaultDescription
openboolean-Controlled open state.
defaultOpenboolean-Initial open state when uncontrolled.
onOpenChange(open: boolean) => void-Called when the dialog opens or closes.
closeOnSelectbooleantrueClose after a row is chosen. Works controlled (onOpenChange(false) fires) and uncontrolled with defaultOpen.
titlestring"Command palette"Visually hidden dialog title for assistive tech.
descriptionstring"Search for a command to run."Visually hidden dialog description for assistive tech.
Data attributeDescription
data-state"open" or "closed", on the dialog content and the overlay.

CommandInput

The search field, a combobox that keeps focus while the active row is announced through aria-activedescendant. Forwards native <input> props except value and onChange; inside CommandDialog it ends with an Esc hint that closes the dialog on click.

PropTypeDefaultDescription
iconboolean | React.ReactNodefalseLeading glyph: true shows the magnifying glass, a node renders your own icon.
placeholderstring"Type a command or search…"Placeholder text for the empty field.

CommandList

The scrolling listbox viewport, which eases its height as rows filter in and out. It also paints the sliding highlight, so rows must live inside one. Forwards all native <div> props.

CommandEmpty

Shown only while no row matches; children default to No results found. Forwards all native <div> props.

CommandGroup

A labeled section that hides, heading and all, when every row inside it filters out. Forwards all native <div> props.

PropTypeDefaultDescription
headingReact.ReactNode-Section label above the rows, also the group's accessible name.

CommandItem

A selectable row, role="option"; a row that does not match the query renders nothing. Forwards native <div> props except onSelect.

PropTypeDefaultDescription
value*string-The row's searchable identity, also passed to onSelect.
keywordsstring[]-Extra terms to match on: synonyms, ids, a page path.
disabledbooleanfalseKeeps the row visible but out of the keyboard order and unclickable.
onSelect(value: string) => void-Fires when the row is chosen by click or Enter.
Data attributeDescription
data-active"true" on the highlighted row.
data-disabledPresent when disabled is set.
data-valueThe row's value.

CommandSeparator

A rule between groups that hides itself when filtering strands it beside an empty group or over the empty state. Forwards all native <div> props.

CommandShortcut

Trailing key hint on a row; drop Kbd children inside. Forwards all native <span> props.

FAQ#

Use Command for an open-ended, searchable list of actions or destinations (the ⌘K pattern), where typing to filter is the primary interaction. DropdownMenu and Select are for short, fixed sets that you pick from without searching.