Appearance
CommandPalette
Purpose
CommandPalette is the shared UI for listing and selecting commands.
- Built on
cmdk+ shadcn-style command primitives - Expects command data (including grouping) from
useCommandPalette - Keeps the “what commands exist” logic out of the UI layer
When to use
Use CommandPalette when:
- You want a consistent “Cmd/Ctrl+K” experience across routes
- You want global search + action execution in one surface
- Commands are defined in feature modules but rendered centrally
Example
tsx
import React, { useMemo } from 'react'
import { useCommandPalette, type Command } from '@/shared/hooks'
import { CommandPalette } from '@/shared/ui/components/CommandPalette'
export function AppCommandPalette() {
const initialCommands: Command[] = useMemo(
() => [
{
id: 'go-dashboard',
label: 'Go to Dashboard',
group: 'Navigation',
shortcut: 'G D',
action: async () => {
// navigate('/dashboard')
},
},
{
id: 'refresh-data',
label: 'Refresh data',
group: 'Actions',
action: async () => {
// queryClient.invalidateQueries(...)
},
},
],
[]
)
const palette = useCommandPalette({ initialCommands })
return (
<CommandPalette
open={palette.isOpen}
onOpenChange={(open) => (open ? palette.open() : palette.close())}
commands={palette.commands}
groupedCommands={palette.groupedCommands}
onSelect={(cmd) => palette.execute(cmd.id)}
/>
)
}Props (concise)
open/onOpenChange(open)- Controlled open state (usually from
useCommandPalette).
- Controlled open state (usually from
commands: Command[]- The full flat list of commands.
groupedCommands: Map<string, Command[]>- Grouped representation used for rendering sections.
onSelect(command)- Called when a user selects a command (the component won’t call it for
disabledcommands).
- Called when a user selects a command (the component won’t call it for
placeholder?/emptyText?- UI strings for search input and empty state.
Notes / Gotchas
- Grouping: the component renders from
groupedCommands; keep it derived from the samecommandslist to avoid drift. - Disabled commands: pass
disabled: trueon a command to keep it visible but non-selectable. - Closing behavior:
useCommandPaletteexecute(id)closes the palette after running the action. - Shortcut binding:
useCommandPaletteregistersCtrl+Kby default (implemented asctrl: truein the hook).