suiss/ui · Pattern
Command Palette
A searchable command menu that opens in a dialog on desktop and a drawer on mobile.
Command Palette is an open-source pattern from suiss/ui for React. The @esuiss/ui CLI copies its source into your project, so you own the code.
CommandPalette hosts a Command list inside a Dialog on desktop, positioned in the upper third of the viewport, and inside a bottom Drawer with a swipe handle below the 48rem breakpoint. Fill CommandPaletteContent with CommandInput, CommandList, CommandGroup, CommandItem and the other Command parts.
A global keyboard shortcut toggles the palette: Cmd+K on macOS and Ctrl+K elsewhere by default. Use it for app-wide search and quick actions.
Installation
CLI
Works in any project with a components.json. See Installation for the one-line registry setup. Or use the suiss/ui CLI:
Manual
-
Add the
cnhelper. -
Add the pieces it builds on: Command, Dialog, Drawer,
use-mobile,use-platform. -
Copy the source into
components/patterns/command-palette.tsx:
- Update the import paths to match your project.
Usage
The palette can be controlled with open and onOpenChange or uncontrolled with defaultOpen; the hotkey and the trigger update the same state. Set hotkey to another letter to change the shortcut, or to false to disable it. CommandPaletteTrigger accepts render to use your own button, for example a Button with a Kbd hint. Remaining props on CommandPaletteContent pass through to Command.
Examples
With close button
Shows an icon close button with showCloseButton.
With close label
Shows a text close button labelled Cancel with closeLabel.
Floating
Insets the mobile drawer from the screen edges with floating.
API Reference
CommandPalette
The root that renders a Dialog on desktop and a Drawer on mobile and registers the hotkey.
| Prop | Type | Default | Description |
|---|---|---|---|
onOpenChange | (open: boolean) => void | - | Called when the palette opens or closes, including through the hotkey. |
hotkey | string | false | "k" | The letter that toggles the palette together with Cmd on macOS or Ctrl elsewhere; false disables it. |
floating | boolean | - | Insets the mobile drawer from the screen edges with fully rounded corners. |
Also accepts the props of React.ComponentProps<typeof Dialog>.
CommandPaletteTrigger
The button that opens the palette.
| Prop | Type | Default | Description |
|---|---|---|---|
render | React.ReactElement | - | Replaces the default button element with your own element, such as a Button. |
Also accepts the props of React.ButtonHTMLAttributes<HTMLButtonElement>.
CommandPaletteContent
The popup that wraps a Command with a visually hidden title and description.
| Prop | Type | Default | Description |
|---|---|---|---|
title | string | "Command Palette" | Accessible name of the dialog, rendered visually hidden. |
description | string | "Search for a command to run..." | Accessible description of the dialog, rendered visually hidden. |
showCloseButton | boolean | false | Shows a close button in the corner of the popup. |
closeLabel | string | - | Replaces the close icon with this text; requires showCloseButton. |
Also accepts the props of React.ComponentProps<typeof Command>.
Accessibility
- The popup is a
dialognamed bytitleand described bydescription. - Opening the palette focuses the search input, and the first enabled option is selected.
- Arrow keys move between options and skip disabled ones; typing filters the list.
Escapecloses the palette and returns focus to the trigger.
Notes
Parts carry data-slot values command-palette, command-palette-trigger and command-palette-content. On mobile the list is capped at 60dvh and the input gains end padding when a close button is shown. className on CommandPaletteContent applies to the inner Command, not the dialog or drawer.