# Command Menu
Source: https://ui.spencerwueste.com/docs/components/command-menu
Markdown: https://ui.spencerwueste.com/llm/components/command-menu.md

> Cmd-K menu with search, groups, keyboard navigation, and an always-visible "Ask AI" escape hatch.

> Live preview: https://ui.spencerwueste.com/docs/components/command-menu (demo source: `src/demos/command-menu-demo.tsx`)

## Installation

```bash
npx shadcn@latest add https://ui.spencerwueste.com/r/command-menu.json
```

Manual install dependencies: `radix-ui @heroicons-animated/react motion`

Registry JSON: https://ui.spencerwueste.com/r/command-menu.json

Built on Radix Dialog with no `cmdk` dependency. Items filter on their text and arrow keys walk whatever is visible, so groups can be plain JSX.

## Usage

```tsx
import {
  CommandMenu,
  CommandMenuEmpty,
  CommandMenuGroup,
  CommandMenuInput,
  CommandMenuItem,
  CommandMenuList,
  useCommandMenuShortcut,
} from "@/components/pandacoderz-ui/command-menu";
```

```tsx
const [open, setOpen] = React.useState(false);
useCommandMenuShortcut(() => setOpen((o) => !o));

<CommandMenu open={open} onOpenChange={setOpen}>
  <CommandMenuInput placeholder="Search or ask…" />
  <CommandMenuList>
    <CommandMenuGroup heading="Actions">
      <CommandMenuItem shortcut="N" onSelect={newChat}>New conversation</CommandMenuItem>
    </CommandMenuGroup>
    <CommandMenuGroup heading="AI">
      <CommandMenuItem alwaysVisible onSelect={askAI}>Ask AI about this…</CommandMenuItem>
    </CommandMenuGroup>
    <CommandMenuEmpty />
  </CommandMenuList>
</CommandMenu>
```

Use `CommandMenuInline` to embed the same parts in a page instead of a dialog.

## API Reference

### CommandMenu

| Prop | Type | Description |
| --- | --- | --- |
| `open` / `onOpenChange` | controlled | Dialog state. |
| `query` / `onQueryChange` | controlled | Search text, if you need it outside. |

### CommandMenuItem

| Prop | Type | Description |
| --- | --- | --- |
| `value` | `string` | Filter text. Defaults to string children. |
| `alwaysVisible` | `boolean` | Ignore the filter. |
| `icon` / `shortcut` | `ReactNode` / `string` | Leading icon and trailing key hint. |
| `onSelect` | `() => void` | Called on click or Enter. |
