# Command Palette

Global search and jump on Cmd or Ctrl K: grouped results, prefix filters and keyboard navigation.

Source page: https://sproutboat.com/ikada/components/command-palette

## Installation
```sh
npx shadcn@latest add https://sproutboat.com/ikada/r/command-palette.json
```
Or from the package: `import { CommandPalette } from "@sproutboat/ikada";`
## Usage
```tsx
import { CommandPalette } from "@/components/ikada/command-palette";

const groups = [
  {
    id: "sprouts",
    label: "Sprouts",
    items: [
      { id: "robin", label: "robin", hint: "eu-west · production", icon: <RocketIcon /> },
      { id: "wren", label: "wren", hint: "us-east · production", icon: <RocketIcon /> },
      { id: "finch", label: "finch", hint: "eu-west · staging", icon: <RocketIcon /> },
    ],
  },
];

function Search() {
  const [open, setOpen] = useState(false);
  useCommandPaletteShortcut(() => setOpen((o) => !o));
  return (
    <>
      <Button onClick={() => setOpen(true)} aria-keyshortcuts="Meta+K Control+K">
        <SearchIcon />
        Search
        <Kbd aria-hidden="true">{shortcutLabel()}</Kbd>
      </Button>
      <CommandPalette
        open={open}
        onOpenChange={setOpen}
        groups={groups}
        onSelect={(item) => navigate(item.id)}
      />
    </>
  );
}
```
## Examples
### Search and jump
Opens with the button or the shortcut. Arrow keys move, Enter picks, Escape closes. Results are filtered as you type.
```tsx
const groups = [
  {
    id: "sprouts",
    label: "Sprouts",
    items: [
      { id: "robin", label: "robin", hint: "eu-west · production", icon: <RocketIcon /> },
      { id: "wren", label: "wren", hint: "us-east · production", icon: <RocketIcon /> },
      { id: "finch", label: "finch", hint: "eu-west · staging", icon: <RocketIcon /> },
    ],
  },
];

function Search() {
  const [open, setOpen] = useState(false);
  useCommandPaletteShortcut(() => setOpen((o) => !o));
  return (
    <>
      <Button onClick={() => setOpen(true)} aria-keyshortcuts="Meta+K Control+K">
        <SearchIcon />
        Search
        <Kbd aria-hidden="true">{shortcutLabel()}</Kbd>
      </Button>
      <CommandPalette
        open={open}
        onOpenChange={setOpen}
        groups={groups}
        onSelect={(item) => navigate(item.id)}
      />
    </>
  );
}
```
### Recents and prefixes
Recents show while the query is empty. Type d1: to narrow the search to one kind of thing.
```tsx
const groups = [
  {
    id: "sprouts",
    label: "Sprouts",
    items: [
      { id: "robin", label: "robin", hint: "eu-west · production", icon: <RocketIcon /> },
      { id: "wren", label: "wren", hint: "us-east · production", icon: <RocketIcon /> },
    ],
  },
  {
    id: "databases",
    label: "Databases",
    items: [
      { id: "heron-db", label: "heron-db", hint: "eu-west", icon: <DatabaseIcon />, scope: "d1" },
      { id: "wren-db", label: "wren-db", hint: "us-east", icon: <DatabaseIcon />, scope: "d1" },
    ],
  },
];
const recents = [{ id: "robin-recent", label: "robin", hint: "eu-west · production", icon: <RocketIcon /> }];
const prefixes = [{ scope: "d1", label: "D1 databases" }];

<CommandPalette
  open={open}
  onOpenChange={setOpen}
  groups={groups}
  recents={recents}
  prefixes={prefixes}
  onSelect={(item) => navigate(item.id)}
/>
```
## Props
### CommandPaletteProps

| Prop | Type | Description |
| --- | --- | --- |
| open | `boolean` | Whether it is open (controlled). |
| onOpenChange | `(open: boolean) => void` | Called with the new open state when it opens or closes. |
| groups | `readonly PaletteGroup[]` | Results to show, in order: each group a heading and its items. |
| recents? | `readonly PaletteItem[]` | Shown first while the query is empty. Default `[]`. |
| prefixes? | `readonly PalettePrefix[]` | Scopes typed as `scope:` that narrow the search, shown as a chip. Default `[]`. |
| onSelect | `(item: PaletteItem) => void` | Called with the chosen item; the palette closes after it. |
| loading? | `boolean` | Shows a spinner while results are fetched. Default `false`. |
| placeholder? | `string` | Placeholder of the search input. Default `Search projects, versions, storage…`. |
| label? | `string` | Name for screen readers. Default `Command palette`. |
Source: https://github.com/baronunread/ikada/blob/main/src/components/command-palette.tsx
