Skip to content

CommandMenu

A fast, filterable command palette for keyboard-driven navigation and actions. It always opens as a modal dialog, and the list filters as you type.

import { CommandMenu } from '@ontoui/react';
const commands = ['New File', 'New Window', 'Open Folder', 'Save', 'Close Editor'];
<CommandMenu.Root items={commands}>
<CommandMenu.Trigger>Open command menu</CommandMenu.Trigger>
<CommandMenu.Panel>
<CommandMenu.Input placeholder="Type a command or search..." />
<CommandMenu.List>
{(item) => (
<CommandMenu.Item key={item} value={item}>
{item}
</CommandMenu.Item>
)}
</CommandMenu.List>
<CommandMenu.Empty>No results found.</CommandMenu.Empty>
</CommandMenu.Panel>
</CommandMenu.Root>;

Anatomy

PartDescription
CommandMenu.RootWraps all parts, owns the open state, and filters items against the query.
CommandMenu.TriggerOptional button that opens the menu.
CommandMenu.PanelThe modal dialog with its backdrop. Renders in a portal.
CommandMenu.InputThe search field that drives filtering.
CommandMenu.ListThe scrollable list of results.
CommandMenu.ItemA selectable command. Fires onClick and closes the menu when chosen.
CommandMenu.EmptyRendered when no items match the current query.
CommandMenu.GroupGroups related items together.
CommandMenu.GroupLabelA heading for a group.
CommandMenu.SeparatorA visual divider between items or groups.

Examples

Keyboard shortcut

Most command palettes open from a shortcut rather than a button. Control open yourself and skip CommandMenu.Trigger.

Press K to open the command menu.
const [open, setOpen] = useState(false);
useEffect(() => {
function onKeyDown(event: KeyboardEvent) {
if (event.key === 'k' && (event.metaKey || event.ctrlKey)) {
event.preventDefault();
setOpen((current) => !current);
}
}
document.addEventListener('keydown', onKeyDown);
return () => document.removeEventListener('keydown', onKeyDown);
}, []);
<CommandMenu.Root items={commands} open={open} onOpenChange={setOpen}>
<CommandMenu.Panel>
<CommandMenu.Input placeholder="Type a command or search..." />
<CommandMenu.List>
{(item) => (
<CommandMenu.Item key={item} value={item}>
{item}
</CommandMenu.Item>
)}
</CommandMenu.List>
<CommandMenu.Empty>No results found.</CommandMenu.Empty>
</CommandMenu.Panel>
</CommandMenu.Root>;

Grouped commands

Pass an array of groups to items and render each one with CommandMenu.Group. Filtering applies across all groups.

const groups = [
{ value: 'file', items: ['New File', 'Open Folder', 'Save'] },
{ value: 'edit', items: ['Undo', 'Redo', 'Find'] },
];
<CommandMenu.Root items={groups}>
<CommandMenu.Trigger>Open command menu</CommandMenu.Trigger>
<CommandMenu.Panel>
<CommandMenu.Input placeholder="Type a command or search..." />
<CommandMenu.List>
{(group) => (
<CommandMenu.Group key={group.value}>
<CommandMenu.GroupLabel>{group.value}</CommandMenu.GroupLabel>
{group.items.map((item) => (
<CommandMenu.Item key={item} value={item}>
{item}
</CommandMenu.Item>
))}
</CommandMenu.Group>
)}
</CommandMenu.List>
<CommandMenu.Empty>No results found.</CommandMenu.Empty>
</CommandMenu.Panel>
</CommandMenu.Root>;

Keeping the menu open

Choosing an item closes the menu. Pass closeOnSelect={false} for items that toggle something in place.

<CommandMenu.Item value="wrap" closeOnSelect={false} onClick={toggleWrap}>
Toggle word wrap
</CommandMenu.Item>

API Reference

CommandMenu.Root

Prop Type Default
children? ReactNode
items? readonly unknown[]
value? string
defaultValue? string
onValueChange? (value: string) => void
open? boolean
defaultOpen? boolean false
onOpenChange? (open: boolean) => void

CommandMenu.Trigger

Prop Type Default
children? ReactNode
render? ReactElement<unknown, string | JSXElementConstructor<any>> <Button.Root />

CommandMenu.Panel

Prop Type Default
children? ReactNode
className? string
aria-label? string 'Command menu'
ref? Ref<HTMLDivElement>

CommandMenu.Input

Prop Type Default
className? string
placeholder? string
disabled? boolean
ref? Ref<HTMLDivElement>

CommandMenu.List

Prop Type Default
children? ReactNode | ((item: any, index: number) => ReactNode)
className? string
ref? Ref<HTMLDivElement>

CommandMenu.Item

Prop Type Default
children? ReactNode
className? string
value? unknown
disabled? boolean
onClick? MouseEventHandler<HTMLDivElement>
closeOnSelect? boolean true
ref? Ref<HTMLDivElement>

CommandMenu.Empty

Prop Type Default
children? ReactNode
className? string
ref? Ref<HTMLDivElement>

CommandMenu.Group

Prop Type Default
children? ReactNode
className? string
ref? Ref<HTMLDivElement>

CommandMenu.GroupLabel

Prop Type Default
children? ReactNode
className? string
ref? Ref<HTMLDivElement>

CommandMenu.Separator

Prop Type Default
className? string
ref? Ref<HTMLDivElement>