@biem/ui

Command

A searchable menu that lets users find and run an action.

A command menu lists actions and filters them while users type in its search input. Users move through the results with the arrow keys and run the selected item with Enter or a click, so they reach an action without leaving the keyboard. When no item matches the search, the menu shows its empty message.

Usage

command-default.tsx
import {
	Command,
	CommandEmpty,
	CommandGroup,
	CommandInput,
	CommandItem,
	CommandList,
} from "@biem/ui/components/ui/command";

export function CommandDefault() {
	return (
		<Command className="max-w-sm">
			<CommandInput placeholder="Search actions..."/>
			<CommandList>
				<CommandEmpty>No actions found.</CommandEmpty>
				<CommandGroup heading="Inventory">
					<CommandItem>Create transfer</CommandItem>
					<CommandItem>Receive delivery</CommandItem>
					<CommandItem>Start inventory count</CommandItem>
				</CommandGroup>
			</CommandList>
		</Command>
	);
}

Examples

With Separator

Related actions are easier to find when they stand together, and a menu with several groups reads more calmly when a boundary divides them. A separator marks that boundary while the search is empty. As soon as users type, it disappears, and only the matching items and their groups remain.

With Icons

In a menu that users open many times a day, an icon lets them recognize a familiar action before they read its words. The search still matches the text of each item, so users find every action by name, whatever its icon.

With Shortcuts

Frequent actions deserve a faster route than the search. A CommandShortcut in the item names the key combination for its action, so users learn it while they search and can skip the menu next time. It only displays the keys, and the application itself must listen for them.

Dialog

Users reach a command menu fastest when it is available from every page instead of one place only. Inside CommandDialog, the menu opens above the current page and keeps the focus until users close it with Escape or a press outside. The example also closes it when users run an action, so they return to their work at once. Its title and description stay invisible, yet they tell assistive technology what the dialog offers.

Actions

Search for an action to run.

Selected by Default

Often one action is the likely next step of a workflow. With defaultValue, the item of that action is already selected when the menu appears, so users run it with Enter right away. As soon as they type, the selection moves to the best match.

Controlled Selection

An application sometimes needs to know which item users are considering before they run it, for example to explain what the action will change. Held in value and onValueChange, the selection belongs to the application, which can also move it from elsewhere in the interface.

Context often suggests a search before users type, for example when they open the menu from a page about a single article. Through value and onValueChange of CommandInput, the application holds the search text, so it can fill it in beforehand, clear it, or keep it for the next time users open the menu.

Without Results

A search that finds nothing still owes users an answer, or they wonder whether the menu has stopped working. Only when no item matches does CommandEmpty appear, and its message makes clear that the search ran without a match, so users rephrase it instead of waiting.

Disabled Item

Some actions are unavailable for a while, such as a price update that still waits for approval. The item stays visible, in the search results as well, so users know that the action exists. With disabled, however, they can neither select nor run it, the arrow keys pass over it, and assistive technology announces it as unavailable.

Checked Item

A command menu also serves as a picker, for example when users switch the period a report covers, and then users need to see which option is active. Set to true on the item of the current choice, data-checked marks it, and the application moves that mark when users pick another option.

With Keywords

Users often search with their own words, such as an abbreviation or a term from another department, and these words may differ from the label of an action. Additional terms in keywords make an item match those words as well, while its label stays the same.

Custom Filter

By default, the search matches loosely: the typed letters only need to appear in the same order, so a few of them find an item even when they are spread across its words. Where users expect stricter results, such as article numbers that must match from the first digit, filter replaces that rule with one of the application's own, which also decides the order of the matching items.

Manual Filtering

A large catalog cannot be loaded into the menu at once, so a server returns the matching articles while users type. Once shouldFilter is set to false, the menu shows the items it receives in the order it receives them, and the arrow keys, Enter and the empty message work as before.

With Frame

Placed directly in a page rather than in a dialog or a popover, the menu needs a boundary that separates it from the surrounding content. Enclosed in CommandFrame, it shows users at once where the search and its results begin and end.

API Reference

Command

Proplabel
Typestring
Default–
DescriptionNames the command menu for assistive technology. The label is not visible.
Propvalue
Typestring
Default–
DescriptionSets the selected item by its value and makes the selection controlled. Update it in onValueChange.
PropdefaultValue
Typestring
Default–
DescriptionSets the item that is selected at first render. Without it, the first item is selected.
ProponValueChange
Type(value: string) => void
Default–
DescriptionRuns when the selection of a controlled command menu changes. It receives the value of the item that is selected next. It doesn't run while value is unset.
PropshouldFilter
Typeboolean
Defaulttrue
DescriptionFilters and sorts the items by how well they match the search. Set it to false when the code renders only the matching items itself.
Propfilter
Type(value: string, search: string, keywords?: string[]) => number
Default–
DescriptionReplaces the function that scores each item against the search. It returns a number from 0 to 1. An item with 0 is hidden, and an item with a higher score comes first.
Proploop
Typeboolean
Defaultfalse
DescriptionMoves the selection from the last item to the first, and from the first to the last, when users press an arrow key at the end of the list.
PropdisablePointerSelection
Typeboolean
Defaultfalse
DescriptionStops the pointer from selecting the item it moves over. A click still selects and runs the item.
PropvimBindings
Typeboolean
Defaulttrue
DescriptionLets users move the selection with Ctrl+N and Ctrl+J to the next item and with Ctrl+P and Ctrl+K to the previous one.

CommandDialog

Proptitle
Typestring
Default"Command Palette"
DescriptionNames the dialog for assistive technology. The title is not visible.
Propdescription
Typestring
Default"Search for a command to run..."
DescriptionDescribes the dialog for assistive technology. The description is not visible.
PropshowCloseButton
Typeboolean
Defaultfalse
DescriptionShows a close button in the top right corner of the dialog.
PropclassName
Typestring
Default–
DescriptionAdds classes to the content of the dialog.
Propchildren
TypeReactNode
Default–
DescriptionHolds the Command that the dialog shows. CommandDialog doesn't render a Command itself.
Propopen
Typeboolean
Default–
DescriptionSets whether the dialog is open and makes it controlled. Update it in onOpenChange.
PropdefaultOpen
Typeboolean
Defaultfalse
DescriptionOpens the dialog at first render. The dialog then tracks its open state itself.
ProponOpenChange
Type(open: boolean, eventDetails: DialogRootChangeEventDetails) => void
Default–
DescriptionRuns when users open or close the dialog. It receives the open state that follows.
ProponOpenChangeComplete
Type(open: boolean) => void
Default–
DescriptionRuns after the dialog has opened or closed and its animations have finished.
Propmodal
Typeboolean | "trap-focus"
Defaulttrue
DescriptionSets how the dialog limits the rest of the page while it is open. With true, focus stays in the dialog and the page doesn't scroll. With "trap-focus", focus stays in the dialog, but the page scrolls. With false, focus can move to the rest of the page, and the page scrolls.
PropdisablePointerDismissal
Typeboolean
Defaultfalse
DescriptionKeeps the dialog open when users press outside of it. A dialog with modal set to false then also stays open when focus moves outside of it.
ProptriggerId
Typestring | null
Default–
DescriptionSets the ID of the trigger that a controlled dialog is associated with. A dialog without open doesn't need it.
PropdefaultTriggerId
Typestring | null
Default–
DescriptionSets the ID of the trigger that the dialog is associated with when defaultOpen opens it at first render.
Prophandle
TypeDialogHandle<Payload>
Default–
DescriptionConnects the dialog with triggers that are rendered outside of it. Create the handle with Dialog.createHandle() from @base-ui/react/dialog.
PropactionsRef
TypeRefObject<DialogRootActions | null>
Default–
DescriptionReceives the functions close and unmount. close closes the dialog from code, and unmount removes it from the DOM after a closing animation that the code controls itself.

CommandInput

Propvalue
Typestring
Default–
DescriptionSets the search text and makes the input controlled. Update it in onValueChange.
ProponValueChange
Type(search: string) => void
Default–
DescriptionRuns when users change the search text. It receives the new text.
PropasChild
Typeboolean
Defaultfalse
DescriptionRenders the child element instead of the native input and passes the attributes and the behavior of the input on to it.

CommandList

Proplabel
Typestring
Default"Suggestions"
DescriptionNames the list for assistive technology. The label is not visible.

CommandEmpty

PropasChild
Typeboolean
Defaultfalse
DescriptionRenders the child element instead of the div and passes the attributes of the empty message on to it.

CommandGroup

Propheading
TypeReactNode
Default–
DescriptionSets the heading that is shown above the items of the group.
Propvalue
Typestring
Default–
DescriptionIdentifies the group. A group without a heading needs a unique value.
PropforceMount
Typeboolean
Defaultfalse
DescriptionKeeps the group and all of its items rendered when they don't match the search.

CommandSeparator

PropalwaysRender
Typeboolean
Defaultfalse
DescriptionKeeps the separator rendered while users search. Without it, the separator is only rendered while the search input is empty.
PropasChild
Typeboolean
Defaultfalse
DescriptionRenders the child element instead of the div and passes the attributes of the separator on to it.

CommandItem

Propvalue
Typestring
Default–
DescriptionIdentifies the item and is the text that the search matches. Without it, the item uses its text content. Set it when the text content changes between renders.
Propkeywords
Typestring[]
Default–
DescriptionAdds terms that the search matches in addition to the value.
ProponSelect
Type(value: string) => void
Default–
DescriptionRuns when users click the item or press Enter while it is selected. It receives the value of the item.
Propdisabled
Typeboolean
Defaultfalse
DescriptionPrevents users from selecting and running the item. The arrow keys skip it.
PropforceMount
Typeboolean
Default–
DescriptionKeeps the item rendered when it doesn't match the search. Without it, the item uses the value set on its group. An item inside a group is still hidden with the group when no other item of the group matches.

CommandShortcut

CommandShortcut shows the keyboard shortcut of an item at the end of the item. It only displays the keys and doesn't listen for them. It renders a span and has no props of its own.