Skip to content

CommandPalette

A keyboard-first command launcher (Cmd/Ctrl-K) for searching and running actions across the app.

  • stable
  • since v0.1.0
  • 12.5 kB
  • overlay
  • search
  • command
  • accessible

Powered by cmdk; the dialog-hosted CommandMenu uses role="dialog" with an sr-only title; ArrowUp / ArrowDown navigate items; Enter runs the focused item; Esc closes.

Preview
Open
tsx

CommandPalette is the raw cmdk surface. For the common case — a dialog that opens on Cmd/Ctrl-K — drop in the pre-wired CommandMenu.

import {
Button,
CommandEmpty,
CommandFooter,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
CommandMenu,
CommandSeparator,
} from "@arshad-shah/cynosure-react";
import { useState } from "react";
function App() {
const [open, setOpen] = useState(false);
return (
<>
<Button onClick={() => setOpen(true)}>Open palette</Button>
<CommandMenu open={open} onOpenChange={setOpen}>
<CommandInput />
<CommandList>
<CommandEmpty />
<CommandGroup heading="Actions">
<CommandItem onSelect={() => setOpen(false)}>Save</CommandItem>
<CommandItem onSelect={() => setOpen(false)}>Settings</CommandItem>
</CommandGroup>
</CommandList>
<CommandFooter />
</CommandMenu>
</>
);
}

Use CommandGroup heading="…" to label sections and shortcut="⌘K" on items to render Kbd chips on the right.

Preview
Open
tsx

CommandItem accepts an icon slot and a description line shown under the label.

Preview
Open
tsx

CommandMenu registers a global Cmd/Ctrl-K listener while mounted. Press the keys to toggle.

Preview
Open
tsx
PropTypeDefaultDescription
children
ReactNode
No results found.
Pass a string like `"⌘K"` or `"Ctrl+Shift+P"` — split on `+` / whitespace and rendered as a series of `<Kbd>` chips. JSX children are rendered untouched.
  • The dialog-hosted CommandMenu renders a screen-reader-only DialogTitle for an accessible name.
  • ArrowUp / ArrowDown move focus through visible items; Home / End jump to the first / last.
  • Enter activates the focused item via its onSelect handler; Esc closes the dialog and returns focus to the trigger.
  • CommandInput is the only focusable text input — typing filters items by label and keywords.
  • The CommandFooter hints (↵ select, Esc close) are decorative; they do not steal keyboard focus.
  • Pass keywords={["new", "create"]} on CommandItem to widen what the filter matches without changing the label.
  • Use shouldFilter={false} on CommandMenu when you fetch results asynchronously, and render <CommandLoading /> while pending.
  • Group destructive items at the bottom under a separate CommandGroup heading="Danger" so they are never the first match.
  • Pair with Kbd in your own onboarding copy (“Press ⌘K to search”) so the affordance is discoverable.