A headless React hook

Command Menu

Build your own command menu

Headless, keyboard-first, fully typed

    • Home
    • Documentation
      ⌘D
    • About
    • Contact
    • Open File
      ⌘O
    • Copy Link
      ⌘K
    • Open Terminal
      ⌘J
    • Settings
      ⌘⇧S

Features

All of the behaviour, none of the markup.

Usage

One hook, your markup.

Hand the hook your items. It gives back the filtered list and a few sets of props to spread onto your own elements.

  1. menuProps the wrapper, for the keyboard
  2. searchProps the input, as a combobox
  3. listProps the list, as its listbox
  4. itemProps each row, as an option
Read the full guide
CommandMenu.tsx TSX
import { type Config, useCommandMenu } from "commandmenu";

const config = [
  { id: "docs", label: "Documentation", onSelect: openDocs },
  { id: "search", label: "Search", shortcut: "F", onSelect: openSearch },
] as const satisfies readonly Config[];

export const CommandMenu = () => {
  const { menuProps, searchProps, listProps, list, selectedId } =
    useCommandMenu({ config });

  return (
    <div {...menuProps}>
      <input {...searchProps} placeholder="Search…" />
      <ul {...listProps}>
        {list.map((item) => (
          <li
            key={item.id}
            {...item.itemProps}
            aria-selected={item.id === selectedId}
          >
            {item.label}
          </li>
        ))}
      </ul>
    </div>
  );
};