Overlays
CommandPalette
A Cmd+K style global command launcher — a centered search input over a filtered, keyboard-navigable, optionally grouped and virtualized list of commands.
CommandPaletteuseCommandPaletteShortcutPreview
Usage
tsx
import { CommandPalette, useCommandPaletteShortcut } from "@vesture/react";
function Example() {
const [open, setOpen] = useState(false);
useCommandPaletteShortcut(setOpen);
return (
<CommandPalette
open={open}
onOpenChange={setOpen}
commands={[
{ id: "new-file", label: "New File", group: "File", shortcut: "⌘N", onSelect: () => createFile() },
{ id: "toggle-theme", label: "Toggle Theme", group: "View", keywords: ["dark", "light"], onSelect: () => toggleTheme() },
]}
/>
);
}Behavior
- Fully controlled (open/onOpenChange), same shape as Modal — renders via FloatingPortal + FloatingOverlay (locks scroll) + a non-modal FloatingFocusManager that autofocuses the search input.
- Filters commands client-side by default (case-insensitive substring against label + keywords + group); pass filterCommands to override, e.g. for fuzzy matching.
- ArrowUp/ArrowDown move the highlighted command (skipping disabled ones, looping at the ends), Enter runs the active command's onSelect and closes, Escape closes without selecting.
- Commands with a group render under a section header, ordered by each group's first appearance in the commands array; headers are non-interactive and skipped by keyboard nav, and only appear for groups with at least one match after filtering.
- Long lists switch to windowed rendering once row count reaches virtualizationThreshold (default 50) — the same manual scrollTop-based approach as Combobox and DataGrid, not an external virtualization dependency.
- useCommandPaletteShortcut is a separate opt-in hook — CommandPalette itself has no baked-in global shortcut. It binds Cmd+K on Mac / Ctrl+K elsewhere by default (checks navigator.platform), attaches a document-level keydown listener, and cleans up on unmount.
Props
CommandItem
| Prop | Type | Default | Description |
|---|---|---|---|
| id | string | — | Required. Stable identity, used for React keys and aria ids. |
| label | string | — | Required. Displayed text, matched by the default filter. |
| description | string | — | Optional secondary line shown under the label. |
| icon | ReactNode | — | Optional leading icon. |
| keywords | string[] | — | Extra searchable terms not shown in the label. |
| shortcut | string | — | Display-only, e.g. "⌘K". |
| group | string | — | Groups render under a section header, ordered by first appearance. |
| onSelect | () => void | — | Required. Fires on Enter or click, then the palette closes. |
| disabled | boolean | — | Skipped by keyboard nav and unclickable. |
CommandPalette
| Prop | Type | Default | Description |
|---|---|---|---|
| open | boolean | — | Required. Controls visibility. |
| onOpenChange | (open: boolean) => void | — | Required. Fires on dismiss/select requests. |
| commands | CommandItem[] | — | Required. |
| placeholder | string | "Type a command or search..." | Search input placeholder. |
| emptyMessage | string | "No matching commands" | Shown when filtering matches nothing. |
| filterCommands | (commands, query) => CommandItem[] | — | Overrides the default substring filter. |
| virtualizationThreshold | number | 50 | Row count (commands + group headers) at/above which the list windows its rendering. |
useCommandPaletteShortcut(onOpenChange, options?)
| Prop | Type | Default | Description |
|---|---|---|---|
| key | string | "k" | Key to match, case-insensitive. |
| metaKey / ctrlKey | boolean | — | Override the platform default (Cmd on Mac, Ctrl elsewhere). |