Skip to content
Redpanda UI
Esc
↑↓navigate↵open⌘Jpreview
Made by pacocoursey
Edit on GitHub

Command

A searchable command menu with keyboard navigation.

Installation

bash
npx shadcn@latest add @redpanda/command
bash
pnpm dlx shadcn@latest add @redpanda/command
bash
yarn dlx shadcn@latest add @redpanda/command
bash
bunx shadcn@latest add @redpanda/command
bash
nubx shadcn@latest add @redpanda/command
bash
aube dlx shadcn@latest add @redpanda/command

When to use

Use this decision tree to determine when to use the Command component:

Usage

tsx
import {  Command,  CommandDialog,  CommandEmpty,  CommandGroup,  CommandInput,  CommandItem,  CommandList,  CommandSeparator,  CommandShortcut,  CommandSub,  CommandSubTrigger,  CommandSubContent,  SimpleCommand,} from '@/components/ui/command';
tsx
<Command>  <CommandInput placeholder="Type a command or search..." />  <CommandList>    <CommandEmpty>No results found.</CommandEmpty>    <CommandGroup heading="Suggestions">      <CommandItem>Calendar</CommandItem>      <CommandItem>Search Emoji</CommandItem>      <CommandItem>Calculator</CommandItem>    </CommandGroup>    <CommandSeparator />    <CommandGroup heading="Settings">      <CommandItem>Profile</CommandItem>      <CommandItem>Billing</CommandItem>      <CommandItem>Settings</CommandItem>    </CommandGroup>  </CommandList></Command>

Surface variants

Use variant="standalone" for the rounded, bordered panel shown in the examples instead of adding border, radius, and shadow classes at the call site. The default elevated variant retains its existing, smaller corner radius. minimal and dialog omit the elevated border and shadow recipe. CommandDialog selects dialog for its inner command.

Examples

Simple Command

A higher-level component that provides a simplified API for creating command menus.

SimpleCommand Props

Prop Type Default Description
placeholder string "Type a command or search..." Input placeholder text
emptyMessage string "No results found." Message shown when no results
groups Array<CommandGroup> - Array of command groups (required)
size 'sm' | 'md' | 'lg' | 'full' 'md' Command size variant
className string - Additional CSS classes

CommandGroup Interface

tsx
interface CommandGroup {  heading?: string;  items: CommandItem[];}
interface CommandItem {  icon?: React.ReactNode;  label: string;  shortcut?: string;  disabled?: boolean;  onSelect?: () => void;}

Usage

tsx
import { SimpleCommand } from '@/components/ui/command';
const commandGroups = [  {    heading: 'Actions',    items: [      {        icon: <Calendar />,        label: 'Calendar',        shortcut: '⌘C',        onSelect: () => console.log('Calendar selected'),      },      {        icon: <Settings />,        label: 'Settings',        disabled: true,        onSelect: () => console.log('Settings selected'),      },    ],  },];
<SimpleCommand groups={commandGroups} placeholder="Search commands..." emptyMessage="No commands found." />;

With Icons

Loading State

Result Breadcrumbs

Dialog

To show the command menu in a dialog, use the <CommandDialog /> component.

CommandDialog accepts a showCloseButton prop that is forwarded to the underlying DialogContent. It defaults to true (a close button is rendered), which differs from shadcn/ui where it defaults to false. Pass showCloseButton={false} to hide the close button.

tsx
export function CommandMenu() {  const [open, setOpen] = React.useState(false);  const invokingControl = React.useRef<HTMLElement | null>(null);
  React.useEffect(    function bindPaletteShortcut() {      const down = (e: KeyboardEvent) => {        if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {          e.preventDefault();          if (!open) {            const activeControl = document.activeElement;            invokingControl.current = activeControl instanceof HTMLElement ? activeControl : null;          }          setOpen((isOpen) => !isOpen);        }      };      document.addEventListener('keydown', down);      return () => document.removeEventListener('keydown', down);    },    [open],  );
  return (    <CommandDialog finalFocus={invokingControl} open={open} onOpenChange={setOpen}>      <CommandInput placeholder="Type a command or search..." />      <CommandList>        <CommandEmpty>No results found.</CommandEmpty>        <CommandGroup heading="Suggestions">          <CommandItem>Calendar</CommandItem>          <CommandItem>Search Emoji</CommandItem>          <CommandItem>Calculator</CommandItem>        </CommandGroup>      </CommandList>    </CommandDialog>  );}

For a triggerless keyboard shortcut, capture the focused control before opening and pass its ref as finalFocus, as above. CommandDialog forwards this public focus destination to the underlying dialog popup; closing returns focus to that control.

Pass props for the inner Command through commandProps, such as a custom filter when cmdk’s default scoring ranks the wrong entry first. Its className merges with the owned dialog recipe. CommandDialog always uses variant="dialog"; the contradictory commandProps.variant override is removed. Keep size, filter, loop, shouldFilter, and other inner command props as needed.

tsx
<CommandDialog commandProps={{ filter: rankExactMatchesFirst }} onOpenChange={setOpen} open={open}>  {/* ... */}</CommandDialog>

Use CommandSub, CommandSubTrigger, and CommandSubContent to create nested command menus that open as a popover to the right of the trigger item.

tsx
function CommandWithSubmenu() {  const [labelOpen, setLabelOpen] = React.useState(false);
  return (    <Command>      <CommandInput placeholder="Type a command or search..." />      <CommandList>        <CommandGroup heading="Actions">          <CommandItem>Search</CommandItem>          <CommandSub open={labelOpen} onOpenChange={setLabelOpen}>            <CommandSubTrigger>Apply Label</CommandSubTrigger>            <CommandSubContent>              <Command>                <CommandInput placeholder="Filter labels..." />                <CommandList>                  <CommandEmpty>No labels found.</CommandEmpty>                  <CommandGroup>                    <CommandItem>Bug</CommandItem>                    <CommandItem>Feature</CommandItem>                    <CommandItem>Enhancement</CommandItem>                  </CommandGroup>                </CommandList>              </Command>            </CommandSubContent>          </CommandSub>        </CommandGroup>      </CommandList>    </Command>  );}

CommandSub - Root wrapper that manages submenu state with a Popover.

Prop Type Description
open boolean Whether the submenu is open
onOpenChange (open: boolean) => void Callback when open state changes
children ReactNode CommandSubTrigger and CommandSubContent

CommandSubTrigger - Item that opens the submenu when selected. Renders a chevron icon on the right.

Prop Type Default Description
inset boolean? false Indent the trigger with left padding
className string? — Additional CSS classes

Inherits all props from CommandItem.

CommandSubContent - Popover content for the nested command list. Opens to the right of the trigger.

Prop Type Description
className string? Additional CSS classes
children ReactNode Nested Command with CommandList

Combobox

You can use the <Command /> component as a combobox. See the Combobox page for more information.

Props

Credits

  • We use cmdk for the command component.
  • We take our inspiration from Shadcn UI for the command style.

Recent changes

  • patchv1.2.0Pin shipped dependency floors to the version we develop against. Registry items now declare ranges like `^5.1.9` (the actual installed version) instead of collapsing to `^5.0.0`, so consumers start on the known-tested baseline while caret semantics still allow any compatible release within the same major.#133
  • minorv1.1.0Theme docs refresh, readability pass on semantic foregrounds, and consumer-facing Base UI regression fixes.#121
  • minorv1.0.0Post-Base-UI polish. Public API unchanged.#116
  • majorv1.0.0Migrate every Radix-based primitive to `@base-ui/react@^1.4.0` (Base UI).#114
  • patchv0.3.1## 🚧 Updated#112
See full history →

Last updated on

Was this page helpful?