Command Palette
An accessible modal command search dialog following the WAI-ARIA combobox pattern. Triggered via global keyboard shortcuts (⌘K or Ctrl+K), it provides instant fuzzy search, categorized action groups, and keyboard navigation.
tsx
import { CommandPalette } from '@nofinite/nui';Interactive Preview
Key Features
- Global Hotkey Support: Automatically listens for ⌘K / Ctrl+K and Escape triggers.
- Categorized Sections: Group commands logically into Navigation, Quick Actions, Settings, or Recent Files.
- Fuzzy Filtering: Fast client-side search ranking that handles typos and partial string matches.
- Accessible Focus Management: Traps focus inside the dialog and maintains visual focus indicators across list items using ARIA
activedescendant.
Usage
Basic Usage
tsx
import { useState, useEffect } from 'react';
import { CommandPalette, Button, Kbd } from '@nofinite/nui';
export default function AppCommandSearch() {
const [isOpen, setIsOpen] = useState(false);
// Optional: Global keydown listener
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
e.preventDefault();
setIsOpen((prev) => !prev);
}
};
window.addEventListener('keydown', handleKeyDown);
return () => window.removeEventListener('keydown', handleKeyDown);
}, []);
const sections = [
{
title: 'Navigation',
items: [
{ id: '1', label: 'Go to Documentation', shortcut: '⌘D', onSelect: () => window.location.href = '/docs' },
{ id: '2', label: 'Explore Components', shortcut: '⌘C', onSelect: () => window.location.href = '/nui/components/button' },
]
},
{
title: 'Actions',
items: [
{ id: '3', label: 'Create New Document', shortcut: '⌘N', onSelect: () => alert('Document Created!') },
{ id: '4', label: 'Toggle Dark Mode', shortcut: '⌘T', onSelect: () => alert('Theme Toggled!') }
]
}
];
return (
<>
<Button variant="outline" onClick={() => setIsOpen(true)}>
Search commands... <Kbd className="ml-2">⌘K</Kbd>
</Button>
<CommandPalette
open={isOpen}
onOpenChange={setIsOpen}
sections={sections}
placeholder="Type a command or search..."
/>
</>
);
}Keyboard Interaction
| Key | Behavior |
|---|---|
| ⌘K / Ctrl+K | Open or close the command palette dialog |
| ArrowDown | Focus the next command item |
| ArrowUp | Focus the previous command item |
| Enter | Trigger the currently highlighted command |
| Escape | Close the command palette and restore trigger focus |
Best Practices
Do
- Provide concise, action-oriented titles for commands (e.g., "Toggle Fullscreen" rather than "Fullscreen").
- Display relevant keyboard shortcuts in command descriptions to educate users over time.
- Restore focus back to the user's previous active element when the palette closes.
Don't
- Do not clutter the palette with hundreds of low-frequency or trivial links; prioritize primary workflows.
- Avoid slow network requests on every keystroke; prefer fast in-memory filtering.
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
sections* | CommandSection[] | — | — |
placeholder | string | Search commands… | — |
className | string | — | — |
open | boolean | — | Forces the palette open/closed. If undefined, it operates purely via Cmd+K internally. |
onOpenChange | ((open: boolean) => void) | — | — |