Command menu components

Powerful and customizable React command menu components built for modern applications and websites. These command menus are built using React Aria and styled with Tailwind CSS.

Installation

You can add this command menu component using our CLI or manually:

npx untitledui@latest add command-menu

Command menu examples

Below are examples and variations of this command menu component:

API reference

Import the parts and assemble them:

import { CommandMenu } from "@/components/application/command-menus/command-menu";
 
<CommandMenu>
    <CommandMenu.Group>
        <CommandMenu.List>
            <CommandMenu.Section />
        </CommandMenu.List>
        <CommandMenu.Preview />
    </CommandMenu.Group>
</CommandMenu>

CommandDialog

Renders React Aria’s ModalOverlay — all of its props are supported.

CommandDialog props
PropTypeDefaultDescription
dialogClassNameClassNameOrFunction<ModalRenderProps>—Class name applied to the modal panel inside the overlay. The backdrop itself is styled with className.
Props from React Aria Components (13)
CommandDialog inherited props
PropTypeDefaultDescription
defaultOpenboolean—Whether the overlay is open by default (uncontrolled).
isDismissablebooleanfalseWhether to close the modal when the user interacts outside it.
isEnteringboolean—Whether the modal is currently performing an entry animation.
isExitingboolean—Whether the modal is currently performing an exit animation.
isKeyboardDismissDisabledbooleanfalseWhether pressing the escape key to close the modal should be disabled.
isOpenboolean—Whether the overlay is open by default (controlled).
onOpenChange((isOpen: boolean) => void)—Handler that is called when the overlay's open state changes.
shouldCloseOnInteractOutside((element: Element) => boolean)—When user interacts with the argument element outside of the overlay ref, return true if onClose should be called. This gives you a chance to filter out interaction with elements that should not dismiss the overlay. By default, onClose will always be called on interaction outside the overlay ref.
styleStyleOrFunction<ModalRenderProps>—The inline style for the element. A function may be provided to compute the style based on component state.
childrenChildrenOrFunction<ModalRenderProps>—The children of the component. A function may be provided to alter the children based on component state.
slotstring | null—A slot name for the component. Slots allow the component to receive props from a parent component. An explicit null value indicates that the local props completely override all props received from a parent.
classNameClassNameOrFunction<ModalRenderProps>—The CSS className for the element. A function may be provided to compute the class based on component state.
renderDOMRenderFunction<"div", ModalRenderProps>—Overrides the default DOM element with a custom render function. This allows rendering existing components with built-in styles and behaviors such as router links, animation libraries, and pre-styled components.Requirements:
  • You must render the expected element type (e.g. if <button> is expected, you cannot render an <a>).
  • Only a single root DOM element can be rendered (no fragments).
  • You must pass through props and ref to the underlying DOM element, merging with your own prop as appropriate.

Also accepts the global HTML attributes (dir, lang, hidden, inert, translate), all standard React DOM event handlers.

CommandMenu

Renders CommandDialog.

CommandMenu props
PropTypeDefaultDescription
placeholderstring"Search"Placeholder text for the search input at the top of the dialog.
emptyStateReactNode—Content rendered in place of the list when the search matches no items.
dialogClassNameClassNameOrFunction<ModalRenderProps>—Class name applied to the modal panel — the rounded, elevated box that holds the input, list and footer.
overlayClassNameClassNameOrFunction<ModalRenderProps>—Class name applied to the full-screen blurred backdrop behind the modal panel.
itemsCommandMenuGroupType[]—Groups of items rendered in the list. They are also flattened so that any item shortcutKeys can be registered as global hotkeys.
defaultItemsCommandMenuGroupType[]—Groups used to seed the list when items is not provided. Their shortcutKeys are registered as global hotkeys either way.
sensitivity
"base""accent""case""variant"
"base"Collation sensitivity passed to React Aria's useFilter, controlling how loosely search text matches — base ignores case and accents, variant matches exactly.
shortcutstring | null"⌘/"Keyboard shortcut that focuses the search input, written as a display string such as ⌘/. Each character is one key of the combination, and the string is also shown as a hint inside the input. Pass null for no shortcut.
filterfalse | ((textValue: string, inputValue: string, node: Node<object>) => boolean)—Custom match function for the underlying Autocomplete. Defaults to a contains match built from sensitivity; pass false to skip client-side filtering entirely and show items as given.
Props from React Aria (37)
CommandMenu inherited props
PropTypeDefaultDescription
onBlur((e: FocusEvent<Element, Element>) => void)—Handler that is called when the element loses focus.
onFocus((e: FocusEvent<Element, Element>) => void)—Handler that is called when the element receives focus.
onFocusChange((isFocused: boolean) => void)—Handler that is called when the element's focus status changes.
autoFocus
falsetrue"first""last"
—Whether to auto focus the listbox or an option.
children* (required)ReactNode—The children wrapped by the autocomplete. Consists of at least an input element and a collection element to filter.
defaultInputValuestring—The default value of the autocomplete input (uncontrolled).
defaultOpenboolean—Whether the overlay is open by default (uncontrolled).
defaultSelectedKeysIterable<Key> | "all"—The initial selected keys in the collection (uncontrolled).
dependenciesreadonly any[]—Values that should invalidate the item cache when using dynamic collections.
disableAutoFocusFirstbooleanfalseWhether or not to focus the first item in the collection after a filter is performed. Note this is only applicable if virtual focus behavior is not turned off via disableVirtualFocus.
disabledKeysIterable<Key>—The item keys that are disabled. These items cannot be selected, focused, or otherwise interacted with.
disableVirtualFocusbooleanfalseWhether the autocomplete should disable virtual focus, instead making the wrapped collection directly tabbable.
disallowEmptySelectionboolean—Whether the collection allows empty selection.
dragAndDropHooksDragAndDropHooks<NoInfer<CommandMenuGroupType>>—The drag and drop hooks returned by useDragAndDrop used to enable drag and drop behavior for the ListBox.
escapeKeyBehavior
"clearSelection""none"
"clearSelection"Whether pressing the escape key should clear selection in the listbox or not.Most experiences should not modify this option as it eliminates a keyboard user's ability to easily clear selection. Only use if the escape key is being handled externally or should not trigger selection clearing contextually.
idstring—The element's unique identifier.
inputValuestring—The value of the autocomplete input (controlled).
isOpenboolean—Whether the overlay is open by default (controlled).
layout
"stack""grid"
"stack"Whether the items are arranged in a stack or grid.
onAction((key: Key) => void)—Handler that is called when a user performs an action on an item. The exact user event depends on the collection's selectionBehavior prop and the interaction modality.
onInputChange((value: string) => void)—Handler that is called when the autocomplete input value changes.
onOpenChange((isOpen: boolean) => void)—Handler that is called when the overlay's open state changes.
onSelectionChange((keys: Selection) => void)—Handler that is called when the selection changes.
orientation
"horizontal""vertical"
"vertical"The primary orientation of the items. Usually this is the direction that the collection scrolls.
renderEmptyState((props: ListBoxRenderProps) => ReactNode)—Provides content to display when there are no items in the list.
selectionBehavior
"toggle""replace"
"toggle"How multiple selection should behave in the collection.
selectionMode
"none""single""multiple"
—The type of selection that is allowed in the collection.
shouldFocusOnHoverboolean—Whether options should be focused when the user hovers over them.
shouldFocusWrapboolean—Whether focus should wrap around when the end/start is reached.
shouldSelectOnPressUpboolean—Whether selection should occur on press up instead of press down.
styleStyleOrFunction<ListBoxRenderProps>—The inline style for the element. A function may be provided to compute the style based on component state.
slotstring | null—A slot name for the component. Slots allow the component to receive props from a parent component. An explicit null value indicates that the local props completely override all props received from a parent.
renderDOMRenderFunction<"div", ListBoxRenderProps>—Overrides the default DOM element with a custom render function. This allows rendering existing components with built-in styles and behaviors such as router links, animation libraries, and pre-styled components.Requirements:
  • You must render the expected element type (e.g. if <button> is expected, you cannot render an <a>).
  • Only a single root DOM element can be rendered (no fragments).
  • You must pass through props and ref to the underlying DOM element, merging with your own prop as appropriate.
aria-describedbystring—Identifies the element (or elements) that describes the object.
aria-detailsstring—Identifies the element (or elements) that provide a detailed, extended description for the object.
aria-labelstring—Defines a string value that labels the current element.
aria-labelledbystring—Identifies the element (or elements) that labels the current element.

Also accepts the global HTML attributes (dir, lang, hidden, inert, translate), all standard React DOM event handlers.

CommandMenu.Collection

Renders React Aria’s Collection — all of its props are supported.

CommandMenu.Collection props
PropTypeDefaultDescription
itemsIterable<T>—Item objects in the collection.
childrenReactNode | ((item: T) => ReactNode)—The contents of the collection.
dependenciesreadonly any[]—Values that should invalidate the item cache when using dynamic collections.
idScopeKey—A scope to prepend to all child item ids to ensure they are unique.
addIdAndValueboolean—Whether to add id and value props to all child items.

CommandMenu.Group

Renders a <div> element.

Also accepts all standard HTML attributes, all aria-* attributes, all standard React DOM event handlers.

CommandMenu.List

Renders React Aria’s ListBox — all of its props are supported.

CommandMenu.List props
PropTypeDefaultDescription
onBlur((e: FocusEvent<Element, Element>) => void)—Handler that is called when the element loses focus.
onFocus((e: FocusEvent<Element, Element>) => void)—Handler that is called when the element receives focus.
onFocusChange((isFocused: boolean) => void)—Handler that is called when the element's focus status changes.
autoFocus
falsetrue"first""last"
—Whether to auto focus the listbox or an option.
childrenReactNode | ((item: CommandMenuGroupType) => ReactNode)—The contents of the collection.
defaultSelectedKeysIterable<Key> | "all"—The initial selected keys in the collection (uncontrolled).
dependenciesreadonly any[]—Values that should invalidate the item cache when using dynamic collections.
disabledKeysIterable<Key>—The item keys that are disabled. These items cannot be selected, focused, or otherwise interacted with.
disallowEmptySelectionboolean—Whether the collection allows empty selection.
dragAndDropHooksDragAndDropHooks<NoInfer<CommandMenuGroupType>>—The drag and drop hooks returned by useDragAndDrop used to enable drag and drop behavior for the ListBox.
escapeKeyBehavior
"clearSelection""none"
"clearSelection"Whether pressing the escape key should clear selection in the listbox or not.Most experiences should not modify this option as it eliminates a keyboard user's ability to easily clear selection. Only use if the escape key is being handled externally or should not trigger selection clearing contextually.
idstring—The element's unique identifier.
layout
"stack""grid"
"stack"Whether the items are arranged in a stack or grid.
onAction((key: Key) => void)—Handler that is called when a user performs an action on an item. The exact user event depends on the collection's selectionBehavior prop and the interaction modality.
onSelectionChange((keys: Selection) => void)—Handler that is called when the selection changes.
orientation
"horizontal""vertical"
"vertical"The primary orientation of the items. Usually this is the direction that the collection scrolls.
renderEmptyState((props: ListBoxRenderProps) => ReactNode)—Provides content to display when there are no items in the list.
selectedKeysIterable<Key> | "all"—The currently selected keys in the collection (controlled).
selectionBehavior
"toggle""replace"
"toggle"How multiple selection should behave in the collection.
selectionMode
"none""single""multiple"
"single"The type of selection that is allowed in the collection.
shouldFocusOnHoverboolean—Whether options should be focused when the user hovers over them.
shouldFocusWrapboolean—Whether focus should wrap around when the end/start is reached.
shouldSelectOnPressUpboolean—Whether selection should occur on press up instead of press down.
Styling (4)
CommandMenu.List styling props
PropTypeDefaultDescription
styleStyleOrFunction<ListBoxRenderProps>—The inline style for the element. A function may be provided to compute the style based on component state.
slotstring | null—A slot name for the component. Slots allow the component to receive props from a parent component. An explicit null value indicates that the local props completely override all props received from a parent.
classNameClassNameOrFunction<ListBoxRenderProps>—The CSS className for the element. A function may be provided to compute the class based on component state.
renderDOMRenderFunction<"div", ListBoxRenderProps>—Overrides the default DOM element with a custom render function. This allows rendering existing components with built-in styles and behaviors such as router links, animation libraries, and pre-styled components.Requirements:
  • You must render the expected element type (e.g. if <button> is expected, you cannot render an <a>).
  • Only a single root DOM element can be rendered (no fragments).
  • You must pass through props and ref to the underlying DOM element, merging with your own prop as appropriate.
Accessibility (4)
CommandMenu.List accessibility props
PropTypeDefaultDescription
aria-describedbystring—Identifies the element (or elements) that describes the object.
aria-detailsstring—Identifies the element (or elements) that provide a detailed, extended description for the object.
aria-labelstring"Command menu results"Defines a string value that labels the current element.
aria-labelledbystring—Identifies the element (or elements) that labels the current element.

Also accepts the global HTML attributes (dir, lang, hidden, inert, translate), all standard React DOM event handlers.

CommandMenu.Preview

Renders a <div> element.

CommandMenu.Preview props
PropTypeDefaultDescription
children* (required)({ selectedId }: PreviewChildrenProps) => ReactNode | ReactNode—Preview content for the highlighted item. When a function, it is called with the selected item's key; nothing renders while no item is selected.
asChildboolean—Whether to render the children directly instead of wrapping them in a div that receives the remaining props.

Also accepts all standard HTML attributes, all standard React DOM event handlers, all aria-* attributes.

CommandMenu.Section

Renders React Aria’s ListBoxSection — all of its props are supported.

CommandMenu.Section props
PropTypeDefaultDescription
titlestring—Heading rendered above the section's items. When omitted, the section renders without a header.
Props from React Aria Components (9)
CommandMenu.Section inherited props
PropTypeDefaultDescription
childrenReactNode | ((item: CommandDropdownMenuItemProps) => ReactElement)—Static child items or a function to render children.
dependenciesreadonly any[]—Values that should invalidate the item cache when using dynamic collections.
idKey—The unique id of the section.
itemsIterable<CommandDropdownMenuItemProps>—Item objects in the section.
valueCommandDropdownMenuItemProps—The object value that this section represents. When using dynamic collections, this is set automatically.
classNamestring—The CSS className for the element.
renderDOMRenderFunction<"section", undefined>—Overrides the default DOM element with a custom render function. This allows rendering existing components with built-in styles and behaviors such as router links, animation libraries, and pre-styled components.Requirements:
  • You must render the expected element type (e.g. if <button> is expected, you cannot render an <a>).
  • Only a single root DOM element can be rendered (no fragments).
  • You must pass through props and ref to the underlying DOM element, merging with your own prop as appropriate.
styleCSSProperties—The inline style for the element.
aria-labelstring—An accessibility label for the section.

Also accepts the global HTML attributes (dir, lang, hidden, inert, translate), all standard React DOM event handlers.

CommandMenu.Trigger

Renders React Aria’s DialogTrigger — all of its props are supported.

CommandMenu.Trigger props
PropTypeDefaultDescription
children* (required)ReactNode——
isOpenboolean—Whether the overlay is open by default (controlled).
defaultOpenboolean—Whether the overlay is open by default (uncontrolled).
onOpenChange((isOpen: boolean) => void)—Handler that is called when the overlay's open state changes.

FAQs

Please refer to our frequently asked questions page for more.

The shortcut prop registers a global hotkey that focuses the search input of an already-open menu — it does not open the menu. It defaults to "⌘/"; pass a different string to change it, or shortcut={null} to register nothing. To open the menu, drive the isOpen and onOpenChange props yourself, or wrap a button in CommandMenu.Trigger.

items (or defaultItems for an uncontrolled list) takes an array of groups shaped { id, title?, items }. Every entry in a group's items needs an id and a label (the label is also the text the search matches against), and can carry description, shortcutKeys and stacked. The search input's placeholder defaults to "Search" and is changed with the placeholder prop.

Set type on an item to "icon" (add an icon component), "avatar" (add src and alt), or "dot" (add dotColor: "green"); omitting type gives the plain "default" item. Adding stacked to any item switches it to a two-line layout with the description below the label and a larger leading icon or avatar.

Yes. Pass filter={false} to switch off the built-in filtering and feed already-filtered results into items yourself, driving the query with the inputValue and onInputChange props. By default the menu filters with React Aria's contains matcher, whose sensitivity prop defaults to "base", and you can also supply your own filter function.

Pass any React node to the emptyState prop on the command menu root. It is rendered by the underlying list box whenever the filtered result set is empty.

Give the item a shortcutKeys array, for example shortcutKeys: ["⌘", "K"]. The keys are rendered next to the item and registered as a hotkey that fires onSelectionChange with that item's id, so the command can be triggered without opening the menu.

Compose them from the sub-components: CommandMenu.List holds CommandMenu.Section and CommandMenu.Item, CommandMenu.Footer pins a footer to the bottom of the dialog, and CommandMenu.Preview takes a render prop receiving { selectedId } so you can show details for the currently selected command.