Nothing chosen yet
import * as React from "react"
import {
Calculator,When to use it#
Use a command palette in an app with many pages and actions, where power users want to reach any of them without the mouse: "go to invoices", "new customer", "change theme". It opens over the page, takes the whole keyboard, and closes as soon as something is picked.
It opens with Ctrl or Cmd with K, which people know from other apps, and from a button for everyone else. For a small menu of actions that belongs next to one button, use a Command Menu or a Dropdown Menu.
Import#
import {
CommandPalette,
CommandPaletteInput,
CommandPaletteList,
CommandPaletteItem,
CommandPaletteGroup,
CommandPaletteGroupLabel,
CommandPaletteCollection,
CommandPaletteEmpty,
CommandPaletteFooter,
} from "@hel/ui/command-palette"Anatomy#
CommandPalette is the window, the dimmed backdrop and the logic in one. Pass it your items, and put the parts inside it. A Dialog gives it the window and the focus handling, and a Combobox gives it the searching and the arrow keys.
CommandPaletteInputis the search box.CommandPaletteListrenders the items. Give it a function, which is called for each item.CommandPaletteItemis one command. It takes thevalue, which is the whole item object, alabeland anicon.CommandPaletteEmptyis shown when nothing matches.CommandPaletteFootershows hints for the keys, such as the arrows, Enter and Escape.CommandPaletteGroup,CommandPaletteGroupLabelandCommandPaletteCollectionsplit the list under headings.
<CommandPalette items={COMMANDS} onSelect={(command) => run(command)}>
<CommandPaletteInput placeholder="What do you want to do?" />
<CommandPaletteEmpty>Nothing matches that.</CommandPaletteEmpty>
<CommandPaletteList>
{(command) => (
<CommandPaletteItem key={command.value} value={command} label={command.label} />
)}
</CommandPaletteList>
</CommandPalette>onSelect is called with the chosen item, and the palette closes. Set closeOnSelect={false} to keep it open.
Opening it#
By default the palette toggles with Ctrl or Cmd with K, from anywhere on the page. shortcut changes the key, or turns it off with false. The examples on this page turn it off, because this site's own search already uses it.
Pass trigger for a button that opens it, or control it with open and onOpenChange, for instance to open it from a search field in the header.
Examples#
Groups#
For a long list of commands, split it into groups. The list gets an array of groups, and each group has its own items. Typing filters across all of them.
The first example at the top of the page is grouped. The palette should always have a name for screen readers, which is title. It is not shown on screen.
A flat list, with your own hints#
Without groups, pass a flat array of items and render the items straight from the list. The footer hints take their texts from the app's config, and messages changes them for one palette.
import { FileText, Receipt, Users } from "lucide-react"
import type { LucideIcon } from "lucide-react"
Props#
CommandPalette#
| Prop | Type | Default |
|---|---|---|
items | an array of items, or of groups | required |
onSelect | (item) => void | none |
closeOnSelect | boolean | true |
shortcut | string | false | "k" |
title | string | "Command palette" |
trigger | ReactElement | none |
open / defaultOpen | boolean | false |
onOpenChange | (open: boolean) => void | none |
blur | boolean | false |
It also takes the search options of the Combobox, such as how items are turned into labels.
CommandPaletteFooter#
| Prop | Type | Default |
|---|---|---|
messages | { navigate, select, close } | Built-in text |
showNavigate / showSelect / showClose | boolean | true |