CommandPalette

A palette that filters commands as you type and runs them from the keyboard.

Import

ts
import { CommandPalette } from '@k8ordo/ui';

Usage

It filters on label and keywords, ignoring case. ↓ / ↑ move through the matches and wrap around; Enter or a click closes the palette and then calls onSelect. Focus stays in the search field. Items that share a group gather under its heading, and shortcut keys are drawn with Kbd.

CommandK

New file⌘N
Open file⌘O
Toggle theme
tsx
const [isOpen, setIsOpen] = useState(false);

<CommandPalette
  isOpen={isOpen}
  onClose={() => setIsOpen(false)}
  items={[
    {
      id: 'new-file',
      label: 'New file',
      group: 'File',
      shortcut: ['⌘', 'N'],
      onSelect: createFile,
    },
    {
      id: 'theme',
      label: 'Toggle theme',
      group: 'View',
      keywords: ['dark', 'light'],
      onSelect: toggleTheme,
    },
  ]}
/>

Opening from a key

Open and close it like Modal, with isOpen / onClose; a key such as ⌘K / Ctrl+K is the application’s to wire. Closing returns focus to where it was, and the next opening starts from an empty search.

tsx
useEffect(() => {
  const listener = (event: KeyboardEvent) => {
    if ((event.metaKey || event.ctrlKey) && event.key === 'k') {
      event.preventDefault();
      setIsOpen(true);
    }
  };
  document.addEventListener('keydown', listener);
  return () => {
    document.removeEventListener('keydown', listener);
  };
}, []);

Props

items
Type: readonly CommandPaletteItem[]
Default: -
aria-label?
Type: string
Default: -
defaultOpen?
Type: boolean
Default: -
isOpen?
Type: boolean
Default: -
onClose?
Type: () => void
Default: -
placeholder?
Type: string
Default: -
ref?
Type: Ref<HTMLDialogElement>
Default: -

Wording this component renders (labels, placeholders, and the like) comes from the message dictionary when no prop sets it. To change it, see: i18n