Summit
ComponentsNavigation

Command

The Command component allows users to filter a list of commands by typing and to run the one they choose.

When to Use

  • as a command palette in a Dialog, for one search over a product’s actions and pages that users open from the keyboard
  • for a list of actions that needs a search, in a page or a Popover

When Not to Use

  • to choose a value for a form, as a Command list runs an action and has no value (use a Combobox)
  • for a few actions on one record (use a Dropdown Menu)

Anatomy

ElementUsage
Search fieldRequired
Group headingOptional
ItemRequired
ShortcutOptional
ContainerRequired
SeparatorOptional

CommandInput renders an Input Group with a search icon. CommandEmpty is shown in place of the list when no item matches. CommandItem adds a check, which appears when the item has data-checked="true" and no shortcut.

CommandDialog renders its children in a Dialog that has a visually hidden title and description and no close button.

Behavior

The Command component has no trigger and no popup of its own. When it is placed on a page, it is always open. To open it over the page as a command palette, place it in a CommandDialog.

The Command component fills the width and the height of its container. The list has a maximum height of 288px and scrolls when its items are taller.

Content

StringRuleExampleCounterexample
PlaceholderSay what the search covers“Search for a command”“Search…”
ItemStart an action with its verb“Create invoice”“New invoice”
Empty messageName what was not found“No commands found.”“No results.”

The hidden title and description of a CommandDialog are set in labels.command: “Command palette” and “Search for a command to run…” by default. To replace them for one CommandDialog, pass title and description. To translate them, use the Summit Provider.

Accessibility

The cmdk library sets the roles and keeps focus in the input. When users press an arrow key or move the pointer, aria-activedescendant on the input points to the highlighted item.

Keyboard

KeyResult
A characterFilters the list and moves the highlight to the first match
ArrowDown, ArrowUpMoves the highlight to the next or the previous item. It stops at the ends unless loop is set on Command.
Ctrl+N or Ctrl+JMoves the highlight to the next item
Ctrl+P or Ctrl+KMoves the highlight to the previous item. To turn off all four, set vimBindings={false} on Command.
Home, EndMoves the highlight to the first or the last item
Meta+ArrowUp, Meta+ArrowDownMoves the highlight to the first or the last item
Alt+ArrowUp, Alt+ArrowDownMoves the highlight to the first item of the previous or the next group
EnterRuns onSelect on the highlighted item
EscapeIn a CommandDialog, closes the Dialog and returns focus to where it was
TabMoves focus out of an inline list. In a CommandDialog, focus stays in the input.

Requirements

The search input needs a name so that screen readers can announce it, as WCAG 2.2 SC 4.1.2 Name, Role, Value requires. To provide one, set label on Command. The cmdk library uses that label to name the input.

The list is named by labels.command.suggestions, which is “Suggestions” by default. To translate it, use the Summit Provider.

Installation

npx shadcn@latest add @summit/command

The CLI also adds @summit/dialog, @summit/input-group, and @summit/summit-provider.

Usage

You provide what each item does, the shortcut that opens a command palette, and the code that closes the palette after a command has run.

import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command';

<Command label="Commands" className="w-96 border">
    <CommandInput placeholder="Search for a command" />
    <CommandList>
        <CommandEmpty>No commands found.</CommandEmpty>
        <CommandGroup heading="Create">
            <CommandItem onSelect={createInvoice}>Create invoice</CommandItem>
            <CommandItem onSelect={logTime}>Log time</CommandItem>
        </CommandGroup>
    </CommandList>
</Command>;

As a Command Palette

To use the Command component as a command palette, keep open in state, toggle it from a shortcut, and set it to false in each onSelect.

As a Command Palette
import { useEffect, useState } from 'react';

import { Command, CommandDialog, CommandInput, CommandItem, CommandList } from '@/components/ui/command';

const [open, setOpen] = useState(false);

useEffect(() => {
    function toggle(event: KeyboardEvent) {
        if (event.key === 'k' && (event.metaKey || event.ctrlKey)) {
            event.preventDefault();
            setOpen((current) => !current);
        }
    }

    document.addEventListener('keydown', toggle);

    return () => document.removeEventListener('keydown', toggle);
}, []);

<CommandDialog open={open} onOpenChange={setOpen}>
    <Command label="Command palette">
        <CommandInput placeholder="Search for a command" />
        <CommandList>
            <CommandItem
                onSelect={() => {
                    setOpen(false);
                    createInvoice();
                }}
            >
                Create invoice
            </CommandItem>
        </CommandList>
    </Command>
</CommandDialog>;

With an Icon and a Shortcut

Place the icon first, with aria-hidden, and the CommandShortcut last. Set value so that the shortcut’s characters aren’t included in the search.

With an Icon and a Shortcut
import { CommandItem, CommandShortcut } from '@/components/ui/command';
import { ReceiptIcon } from '@phosphor-icons/react';

<CommandItem value="Create invoice" onSelect={createInvoice}>
    <ReceiptIcon aria-hidden />
    Create invoice
    <CommandShortcut>⌘I</CommandShortcut>
</CommandItem>;

Mark the Current Item

To mark the current item with a check at its end, such as the theme in use, set data-checked.

Mark the Current Item
<CommandItem data-checked={theme === 'dark'} onSelect={() => setTheme('dark')}>
    Dark
</CommandItem>

API Reference

CommandShortcut accepts the props of a span. The other parts, except CommandDialog, accept the props of their matching parts in cmdk. See the cmdk documentation for label, shouldFilter, filter, loop, value, keywords, and onSelect.

CommandDialog

PropTypeDefaultDescription
titlestringlabels.command.titleThe hidden title of the Dialog
descriptionstringlabels.command.descriptionThe hidden description of the Dialog
showCloseButtonbooleanfalseShows the close button of the Dialog
classNamestringNoneClasses for the popup of the Dialog

CommandDialog also accepts the props of Dialog, such as open and onOpenChange.

On this page