---
id: "packages/active-ui/command"
title: "Command"
description: "A searchable list of commands, inline or as a command palette in a dialog, filtered as the reader types."
url: "/packages/active-ui/command"
locale: "en"
revision: "5f215ca1f083be7d"
---

# Command

`Command` is a list of commands with a search field: typing filters the list, the arrow keys move
and `Enter` chooses. Inline, it is a filterable menu; in `CommandDialog`, it is a command palette
that jumps to any page or action. It is built on [cmdk](https://cmdk.paco.me), whose props it
passes through. For picking a form value from a list, use a [combobox](/packages/active-ui/combobox).

**Example: Inline and as a palette**

Client: Runs entirely in your browser. Source: `examples/ui/command.tsx`.

```tsx
// apps/docs/examples/ui/command.tsx
'use client';

import {useState} from 'react';
import {FileTextIcon, SettingsIcon, UsersIcon} from 'lucide-react';

import {Button} from '@workspace/active-ui/components/primitives/button';
import {
  Command,
  CommandDialog,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
  CommandSeparator,
} from '@workspace/active-ui/components/primitives/command';

const PAGES = [
  {label: 'Schemes', icon: FileTextIcon},
  {label: 'Participants', icon: UsersIcon},
  {label: 'Settings', icon: SettingsIcon},
];
const ACTIONS = ['Create a scheme', 'Import participants', 'Send statements'];

function Palette({onChoose}: {onChoose: (value: string) => void}) {
  return (
    <>
      <CommandInput placeholder="Type a page or an action" />
      <CommandList>
        <CommandEmpty>Nothing matches.</CommandEmpty>
        <CommandGroup heading="Go to">
          {PAGES.map(({label, icon: Icon}) => (
            <CommandItem key={label} onSelect={() => onChoose(label)}>
              <Icon aria-hidden />
              {label}
            </CommandItem>
          ))}
        </CommandGroup>
        <CommandSeparator />
        <CommandGroup heading="Actions">
          {ACTIONS.map((label) => (
            <CommandItem key={label} onSelect={() => onChoose(label)}>
              {label}
            </CommandItem>
          ))}
        </CommandGroup>
      </CommandList>
    </>
  );
}

/**
 * A searchable list of commands: inline, as a filterable menu on the page,
 * and in a dialog, as a command palette. Typing filters by fuzzy match; the
 * arrow keys and Enter choose.
 */
export default function CommandExample() {
  const [open, setOpen] = useState(false);
  const [chosen, setChosen] = useState('nothing yet');
  return (
    <div className="flex w-full max-w-sm flex-col items-center gap-4">
      <Command
        label="Pages and actions"
        className="w-full rounded-lg border shadow-xs"
      >
        <Palette onChoose={setChosen} />
      </Command>
      <Button variant="outline" onClick={() => setOpen(true)}>
        Open the command palette
      </Button>
      <CommandDialog
        open={open}
        onOpenChange={setOpen}
        title="Command palette"
        description="Search for a page or an action."
      >
        <Command label="Pages and actions">
          <Palette
            onChoose={(value) => {
              setChosen(value);
              setOpen(false);
            }}
          />
        </Command>
      </CommandDialog>
      <p className="text-muted-foreground text-sm" aria-live="polite">
        Chosen: {chosen}
      </p>
    </div>
  );
}
```

## Usage

```tsx
import {
  Command,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
} from '@workspace/active-ui/components/primitives/command';

<Command label="Pages and actions">
  <CommandInput placeholder="Type a page or an action" />
  <CommandList>
    <CommandEmpty>Nothing matches.</CommandEmpty>
    <CommandGroup heading="Go to">
      <CommandItem onSelect={() => go('/schemes')}>Schemes</CommandItem>
    </CommandGroup>
  </CommandList>
</Command>;
```

## Anatomy

- `Command`: the search state. `label` names it for assistive technology; `filter` replaces the
  fuzzy match; `shouldFilter={false}` leaves filtering to you, for results from a server.
- `CommandInput`: the search field, with its icon.
- `CommandList` with `CommandGroup` (its `heading`), `CommandItem` (`onSelect`, `value`,
  `keywords` for extra search words, `disabled`), `CommandSeparator` and `CommandEmpty`, shown when
  nothing matches.
- `CommandShortcut`: shows a key combination beside an item; binding it is your application's
  work.
- `CommandDialog`: a [dialog](/packages/active-ui/dialog) for a palette. Put a `Command` inside it.

## What your application provides

- `label` on `Command`, and `title` and `description` on `CommandDialog`: they name and describe
  the palette for screen readers (visually hidden, required). `closeLabel` adds a close button;
  without it, `Escape` and a choice close the dialog.
- What each item does in `onSelect`, and closing the dialog afterwards.
- A way to open the palette, such as a button, and a keyboard shortcut if you bind one.

## Accessibility and keyboard

- The input is a `role="combobox"` that controls the list; the list is a `listbox` with `option`s.
- `↓` and `↑` move through the matching items, `Enter` runs the highlighted one.
- In the dialog, the focus starts in the input and returns to the opening element on close.

## API

### Command

| Prop | Type | Required | Description |
| --- | --- | --- | --- |

Command has no props of its own.

### CommandDialog

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `children` | `ReactNode` | yes |  |
| `description` | `string` | yes | What the palette is for, read with the name; visually hidden. |
| `title` | `string` | yes | The name of the palette for screen readers; visually hidden. |
| `className` | `string` | no | Classes for the dialog panel. |
| `closeLabel` | `string` | no | Name of the close button. Omitted? Then the panel shows no close button -- the dialog closes with Escape and with a choice from the list. |
| `actionsRef` | `RefObject<DialogRootActions \| null>` | no | A ref to imperative actions. - `unmount`: Ends the closing phase of the dialog after an externally controlled closing animation finishes. Call `preventUnmountOnClose()` in `onOpenChange` first, otherwise the dialog completes closing on its own. Whether it leaves the DOM is decided by `keepMounted` on the portal. - `close`: Closes the dialog imperatively when called. |
| `defaultOpen` | `boolean` | no | Whether the dialog is initially open.  To render a controlled dialog, use the `open` prop instead. |
| `defaultTriggerId` | `string \| null` | no | ID of the trigger that the dialog is associated with. This is useful in conjunction with the `defaultOpen` prop to create an initially open dialog. |
| `disablePointerDismissal` | `boolean` | no | Whether to prevent the dialog from closing on outside presses. For non-modal dialogs, this also prevents the dialog from closing when focus moves outside of it. |
| `handle` | `DialogHandle<unknown>` | no | A handle to associate the dialog with a trigger. If specified, allows external triggers to control the dialog's open state. Can be created with the Dialog.createHandle() method. |
| `modal` | `"trap-focus" \| boolean` | no | Determines if the dialog enters a modal state when open. - `true`: user interaction is limited to just the dialog: focus is trapped, document page scroll is locked, and pointer interactions on outside elements are disabled. - `false`: user interaction with the rest of the document is allowed. - `'trap-focus'`: focus is trapped inside the dialog, but document page scroll is not locked and pointer interactions outside of it remain enabled.  When `modal` is `true` or `'trap-focus'`, render `<Dialog.Close>` inside `<Dialog.Popup>` so touch screen readers can escape the popup. |
| `onOpenChange` | `((open: boolean, eventDetails: DialogRoot.ChangeEventDetails) => void)` | no | Event handler called when the dialog is opened or closed. |
| `onOpenChangeComplete` | `((open: boolean) => void)` | no | Event handler called after any animations complete when the dialog is opened or closed. |
| `open` | `boolean` | no | Whether the dialog is currently open. |
| `triggerId` | `string \| null` | no | ID of the trigger that the dialog is associated with. This is useful in conjunction with the `open` prop to create a controlled dialog. There's no need to specify this prop when the dialog is uncontrolled (that is, when the `open` prop is not set). |

### Other parts

**CommandInput**

| Prop | Type | Required | Description |
| --- | --- | --- | --- |

CommandInput has no props of its own.

**CommandList**

| Prop | Type | Required | Description |
| --- | --- | --- | --- |

CommandList has no props of its own.

**CommandEmpty**

| Prop | Type | Required | Description |
| --- | --- | --- | --- |

CommandEmpty has no props of its own.

**CommandGroup**

| Prop | Type | Required | Description |
| --- | --- | --- | --- |

CommandGroup has no props of its own.

**CommandItem**

| Prop | Type | Required | Description |
| --- | --- | --- | --- |

CommandItem has no props of its own.

**CommandShortcut**

| Prop | Type | Required | Description |
| --- | --- | --- | --- |

CommandShortcut has no props of its own.

**CommandSeparator**

| Prop | Type | Required | Description |
| --- | --- | --- | --- |

CommandSeparator has no props of its own.

> [!NOTE]
> **Based on shadcn/ui**
>
> This page adapts the Command documentation of shadcn/ui (MIT licence) to this
> package; see [Third-party notices](/third-party-notices).
