Loading...
Loading...
Build keyboard-driven command palettes using cmdk + shadcn/ui. Use when: (1) Adding command palette to web apps, (2) Implementing keyboard navigation, (3) Building spotlight-style search, (4) Setting up cmdk with shadcn components.
npx skill4agent add gwenwindflower/.charmschool web-ux-command-palette| Component | Purpose |
|---|---|
| Modal wrapper (Dialog + Command) |
| Search input with icon |
| Scrollable results container |
| "No results" state |
| Categorized sections with headings |
| Individual selectable items |
| Visual divider between groups |
| Keyboard shortcut hint display |
<CommandDialog open={open} onOpenChange={setOpen}>
<CommandInput placeholder="Type a command..." />
<CommandList>
<CommandEmpty>No results found.</CommandEmpty>
<CommandGroup heading="Navigation">
<CommandItem onSelect={() => navigate('/home')}>
<HomeIcon /> Home
</CommandItem>
</CommandGroup>
</CommandList>
</CommandDialog>Cmd+KCtrl+K/EscapeEnteruseEffect(() => {
const handler = (e: KeyboardEvent) => {
if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
e.preventDefault();
setOpen(prev => !prev);
}
if (e.key === '/' && !isInputFocused(e.target)) {
e.preventDefault();
setOpen(true);
}
};
document.addEventListener('keydown', handler);
return () => document.removeEventListener('keydown', handler);
}, []);
function isInputFocused(target: EventTarget | null): boolean {
return target instanceof HTMLElement &&
['INPUT', 'TEXTAREA', 'SELECT'].includes(target.tagName);
}interface SearchItem {
title: string;
description?: string;
href: string;
type: string; // e.g., "page", "blog", "command"
keywords?: string[];
}valueCommandItemvalue={title + ' ' + keywords?.join(' ')}<CommandList className="max-h-[300px]">DialogContent<CommandItem className="data-[selected=true]:bg-accent">