# Command

- Page: <https://kznlabs.github.io/labsUI/components/command>

## Command (`command`, component)

⌘K palette: filterable groups, arrow-key highlight, Enter to run, keyword matching. Inline or as CommandDialog with a global shortcut; the first Esc clears, the second closes.

- Install: `npx @kznlabs/labsui add command`
- Docs: <https://kznlabs.github.io/labsUI/components/command>
- Brings: button, button-variants, dialog, field, input, kbd, label, list, platform, search-input, separator, use-controllable-state, use-hotkey, utils
- npm: clsx@^2.1.1, lucide-react@1.63.0, motion@14.7.1, tailwind-merge@^3.7.0

### API

- `<Command>`: Filterable, keyboard-driven list. Arrows/Home/End move, Enter selects. Use inline or in CommandDialog.
  - `children: ReactNode`: `CommandInput` and `CommandList`.
  - `close?: () => void`: Called after a selection; CommandDialog passes its own close.
- `<CommandInput>`
  - `label?: string` = `"Search commands"`: Accessible name of the input.
  - `placeholder?: string` = `"Type a command or search…"`: Input placeholder.
- `<CommandList>`: Scrollable results. Shows `CommandEmpty` only when no option matches.
  - `children: ReactNode`: Groups, items, separators and `CommandEmpty`.
  - `label?: string` = `"Results"`: Accessible name of the listbox.
- `<CommandEmpty>` (+ <div> props)
- `<CommandGroup>`: Hides itself when none of its items match.
  - `children: ReactNode`: `CommandItem`s.
  - `heading?: string`: Visible group title.
- `<CommandSeparator>`: Hidden while filtering, when groups collapse and separators would stack up.
- `<CommandItem>`
  - `children: ReactNode`: Item content, e.g. an icon and a label.
  - `disabled?: boolean`: Shown but not selectable.
  - `keepOpen?: boolean`: Inside CommandDialog: stay open after selecting.
  - `keywords?: readonly string[]`: Extra search terms, e.g. ["settings", "preferences"].
  - `onSelect?: (value: string) => void`: Called with the item's `value` on click or Enter.
  - `value?: string`: Matched against the query and used for selection. Defaults to the item's text.
- `<CommandDialog>`: Command palette: Command in a Dialog, toggled by a global shortcut. Selecting closes it.
  - `children: ReactNode`: `CommandInput` and `CommandList`.
  - `onOpenChange?: (open: boolean) => void`: Called on the shortcut, Esc, outside click or a selection.
  - `open?: boolean`: Controlled state; pair with `onOpenChange`.
  - `shortcut?: false | `mod+${string}`` = `"mod+k"`: Global toggle, e.g. "mod+k" (⌘ on Mac, Ctrl elsewhere). Pass false to disable.
  - `title?: string` = `"Command palette"`: Accessible dialog title (visually hidden).

### Usage

```tsx
<CommandDialog shortcut="mod+k"><CommandInput /><CommandList><CommandEmpty /><CommandGroup heading="Pages"><CommandItem onSelect={go}>Home</CommandItem></CommandGroup></CommandList></CommandDialog>
```

### Example: site-palette.tsx

```tsx
"use client";

import { FileText } from "lucide-react";
import { useRouter } from "next/navigation";
import {
  CommandDialog,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
} from "@/components/ui/command";

const pages = [
  { href: "/", title: "Home" },
  { href: "/blog", title: "Blog" },
  { href: "/clips", title: "Clips" },
];

export function SitePalette() {
  const router = useRouter();
  return (
    <CommandDialog shortcut="mod+k">
      <CommandInput placeholder="Search pages…" />
      <CommandList>
        <CommandEmpty>No pages found.</CommandEmpty>
        <CommandGroup heading="Pages">
          {pages.map((p) => (
            <CommandItem key={p.href} onSelect={() => router.push(p.href)}><FileText />{p.title}</CommandItem>
          ))}
        </CommandGroup>
      </CommandList>
    </CommandDialog>
  );
}
```
