suiss/ui
  • Docs
  • Components
  • Patterns
  • Interactions
  • Charts
  • Blocks
GitHubGet started
DocsComponentsPatternsInteractionsChartsBlocks
Components82
  • Overview
  • Accordion
  • Alert
  • Alert Dialog
  • Alert Sheet
  • Amount Input
  • Aspect Ratio
  • Attachment
  • Avatar
  • Badge
  • Bottom Bar
  • Breadcrumb
  • Bubble
  • Button
  • Button Group
  • Calendar
  • Card
  • Carousel
  • Chart
  • Checkbox
  • Chip
  • Collapsible
  • Combobox
  • Command
  • Context Menu
  • Dialog
  • Direction
  • Drawer
  • Dropdown Menu
  • Empty
  • FAB
  • Field
  • Fullscreen Menu
  • Haptics
  • Header
  • Hover Card
  • Icon
  • Input
  • Input Accessory Bar
  • Input Group
  • Input OTP
  • Item
  • Kbd
  • Keyboard Scroll View
  • Keypad
  • Label
  • Marker
  • Menubar
  • Message
  • Message Scroller
  • Native Select
  • Navigation Menu
  • Page Indicator
  • Pagination
  • Pin Pad
  • Popover
  • Progress
  • QR Scanner
  • Questionnaire
  • Radio Group
  • Resizable
  • Screen
  • Scroll Area
  • Select
  • Separator
  • Sheet
  • Sidebar
  • Signature Pad
  • Skeleton
  • Slider
  • Spinner
  • Switch
  • Tab Bar
  • Table
  • Tabs
  • Text
  • Textarea
  • Toast
  • Toggle
  • Toggle Group
  • Tooltip
  • Wheel Picker
  • Widget

suiss/ui · Component

Command

A searchable menu of commands, used inline or as a command palette in a dialog.

Command is an open-source component from suiss/ui for React. The @esuiss/ui CLI copies its source into your project, so you own the code.

import {
  CalculatorIcon,
  CalendarBlankIcon,
  CreditCardIcon,
  GearIcon,
  SmileyIcon,
  UserIcon,
} from "@phosphor-icons/react"
import {
  Command,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
  CommandSeparator,
  CommandShortcut,
} from "@/components/ui/command"

function CommandItems() {
  return (
    <>
      <CommandEmpty>No results found.</CommandEmpty>
      <CommandGroup heading="Suggestions">
        <CommandItem>
          <CalendarBlankIcon />
          Calendar
        </CommandItem>
        <CommandItem>
          <SmileyIcon />
          Search emoji
        </CommandItem>
        <CommandItem disabled>
          <CalculatorIcon />
          Calculator
        </CommandItem>
      </CommandGroup>
      <CommandSeparator />
      <CommandGroup heading="Settings">
        <CommandItem>
          <UserIcon />
          Profile
          <CommandShortcut mod>P</CommandShortcut>
        </CommandItem>
        <CommandItem>
          <CreditCardIcon />
          Billing
          <CommandShortcut mod>B</CommandShortcut>
        </CommandItem>
        <CommandItem>
          <GearIcon />
          Settings
          <CommandShortcut mod>S</CommandShortcut>
        </CommandItem>
      </CommandGroup>
    </>
  )
}

export default function CommandDemo() {
  return (
    <div className="w-140">
      <Command className="ring-foreground/5 shadow-md ring-1">
        <CommandInput placeholder="Type a command or search..." />
        <CommandList>
          <CommandItems />
        </CommandList>
      </Command>
    </div>
  )
}

Command is built on cmdk. The Command root filters and orders its items as people type into CommandInput. CommandList holds the results: CommandGroup sections with a heading, CommandItem rows, CommandSeparator dividers, and a CommandEmpty message shown when nothing matches. CommandShortcut displays a keyboard shortcut at the end of an item.

CommandDialog places a Command in a modal dialog for a command palette. Use a command menu for actions and navigation that people search by name. To pick a value for a form field, use a combobox instead.

Installation

CLI

$ pnpm dlx shadcn@latest add @esuiss/command

Works in any project with a components.json. See Installation for the one-line registry setup. Or use the suiss/ui CLI:

$ pnpm dlx @esuiss/ui@latest add command

Manual

  1. Install the dependencies and add the cn helper:
$ pnpm add @phosphor-icons/react cmdk
  1. Add the pieces it builds on: Dialog, use-platform.

  2. Copy the source into components/ui/command.tsx:

components/ui/command.tsx
"use client"

import { CheckIcon, MagnifyingGlassIcon } from "@phosphor-icons/react"
import { Command as CommandPrimitive } from "cmdk"
import type * as React from "react"
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog"
import { useModifierKey } from "@/hooks/use-platform"
import { cn } from "@/lib/utils"

function Command({
  1. Update the import paths to match your project.

Usage

import { Command, CommandDialog, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandSeparator, CommandItem, CommandShortcut } from "@/components/ui/command"
<div className="w-140">
  <Command className="ring-foreground/5 shadow-md ring-1">
    <CommandInput placeholder="Type a command or search..." />
    <CommandList>
      <CommandItems />
    </CommandList>
  </Command>
</div>

Compose CommandInput and CommandList inside Command, and put groups and items in the list. For a palette, wrap the Command in CommandDialog and control it with open and onOpenChange. Respond to a chosen item with its onSelect callback, and set disabled on items that are unavailable.

Set mod on CommandShortcut to prefix the shortcut with the platform modifier key: ⌘ on Apple platforms and Ctrl+ elsewhere.

Examples

Empty

A command menu with no items that always shows its empty message.

import {
  Command,
  CommandEmpty,
  CommandInput,
  CommandList,
} from "@/components/ui/command"

export default function CommandEmptyExample() {
  return (
    <div className="w-140">
      <Command className="ring-foreground/5 shadow-md ring-1">
        <CommandInput placeholder="Search projects..." />
        <CommandList>
          <CommandEmpty>No projects found.</CommandEmpty>
        </CommandList>
      </Command>
    </div>
  )
}

Dialog

A command palette in a dialog, opened from a button, that closes with Escape and returns focus to the button.

import {
  CalculatorIcon,
  CalendarBlankIcon,
  CreditCardIcon,
  GearIcon,
  SmileyIcon,
  UserIcon,
} from "@phosphor-icons/react"
import * as React from "react"
import { Button } from "@/components/ui/button"
import {
  Command,
  CommandDialog,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
  CommandSeparator,
  CommandShortcut,
} from "@/components/ui/command"

function CommandItems() {
  return (
    <>
      <CommandEmpty>No results found.</CommandEmpty>
      <CommandGroup heading="Suggestions">
        <CommandItem>
          <CalendarBlankIcon />
          Calendar
        </CommandItem>
        <CommandItem>
          <SmileyIcon />
          Search emoji
        </CommandItem>
        <CommandItem disabled>
          <CalculatorIcon />
          Calculator
        </CommandItem>
      </CommandGroup>
      <CommandSeparator />
      <CommandGroup heading="Settings">
        <CommandItem>
          <UserIcon />
          Profile
          <CommandShortcut mod>P</CommandShortcut>
        </CommandItem>
        <CommandItem>
          <CreditCardIcon />
          Billing
          <CommandShortcut mod>B</CommandShortcut>
        </CommandItem>
        <CommandItem>
          <GearIcon />
          Settings
          <CommandShortcut mod>S</CommandShortcut>
        </CommandItem>
      </CommandGroup>
    </>
  )
}

function CommandDialogExample({
  defaultOpen = false,
}: {
  defaultOpen?: boolean
}) {
  const [open, setOpen] = React.useState(defaultOpen)

  return (
    <>
      <Button variant="outline" onClick={() => setOpen(true)}>
        Open command palette
      </Button>
      <CommandDialog open={open} onOpenChange={setOpen}>
        <Command>
          <CommandInput placeholder="Type a command or search..." />
          <CommandList>
            <CommandItems />
          </CommandList>
        </Command>
      </CommandDialog>
    </>
  )
}

export default function CommandDialogDemo() {
  return (
    <div className="w-140">
      <CommandDialogExample />
    </div>
  )
}

Dialog open

A command palette that is open when the page loads.

import {
  CalculatorIcon,
  CalendarBlankIcon,
  CreditCardIcon,
  GearIcon,
  SmileyIcon,
  UserIcon,
} from "@phosphor-icons/react"
import * as React from "react"
import { Button } from "@/components/ui/button"
import {
  Command,
  CommandDialog,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
  CommandSeparator,
  CommandShortcut,
} from "@/components/ui/command"

function CommandItems() {
  return (
    <>
      <CommandEmpty>No results found.</CommandEmpty>
      <CommandGroup heading="Suggestions">
        <CommandItem>
          <CalendarBlankIcon />
          Calendar
        </CommandItem>
        <CommandItem>
          <SmileyIcon />
          Search emoji
        </CommandItem>
        <CommandItem disabled>
          <CalculatorIcon />
          Calculator
        </CommandItem>
      </CommandGroup>
      <CommandSeparator />
      <CommandGroup heading="Settings">
        <CommandItem>
          <UserIcon />
          Profile
          <CommandShortcut mod>P</CommandShortcut>
        </CommandItem>
        <CommandItem>
          <CreditCardIcon />
          Billing
          <CommandShortcut mod>B</CommandShortcut>
        </CommandItem>
        <CommandItem>
          <GearIcon />
          Settings
          <CommandShortcut mod>S</CommandShortcut>
        </CommandItem>
      </CommandGroup>
    </>
  )
}

function CommandDialogExample({
  defaultOpen = false,
}: {
  defaultOpen?: boolean
}) {
  const [open, setOpen] = React.useState(defaultOpen)

  return (
    <>
      <Button variant="outline" onClick={() => setOpen(true)}>
        Open command palette
      </Button>
      <CommandDialog open={open} onOpenChange={setOpen}>
        <Command>
          <CommandInput placeholder="Type a command or search..." />
          <CommandList>
            <CommandItems />
          </CommandList>
        </Command>
      </CommandDialog>
    </>
  )
}

export default function CommandDialogOpen() {
  return (
    <div className="w-140">
      <CommandDialogExample defaultOpen />
    </div>
  )
}

API Reference

Anatomy4 parts
<Command>
<CommandInput />
<CommandList>
<CommandEmpty />
</CommandList>
</Command>
01

Command

The root that filters and manages the items.

Also accepts the props of React.ComponentProps<typeof CommandPrimitive>.

02

CommandDialog

A modal dialog that presents a command menu as a palette.

PropTypeDefaultDescription
titlestring"Command Palette"The dialog's accessible title. It is visually hidden.
descriptionstring"Search for a command to run..."The dialog's accessible description. It is visually hidden.
classNamestring-Classes applied to the dialog's content panel.
showCloseButtonbooleanfalseShows the dialog's close button.
childrenReact.ReactNodeRequiredThe dialog's content, typically a Command.

Also accepts the props of React.ComponentProps<typeof Dialog>.

03

CommandInput

The search field, shown with a magnifying glass icon.

Also accepts the props of React.ComponentProps<typeof CommandPrimitive.Input>.

04

CommandList

The scrollable container for results.

Also accepts the props of React.ComponentProps<typeof CommandPrimitive.List>.

05

CommandEmpty

Content shown when no items match the search.

Also accepts the props of React.ComponentProps<typeof CommandPrimitive.Empty>.

06

CommandGroup

A section of related items with an optional heading.

Also accepts the props of React.ComponentProps<typeof CommandPrimitive.Group>.

07

CommandSeparator

A divider between groups.

Also accepts the props of React.ComponentProps<typeof CommandPrimitive.Separator>.

08

CommandItem

A selectable command.

Also accepts the props of React.ComponentProps<typeof CommandPrimitive.Item>.

09

CommandShortcut

Displays a keyboard shortcut at the end of an item.

PropTypeDefaultDescription
modboolean-Prefixes the shortcut with the platform modifier key, ⌘ on Apple platforms and Ctrl+ elsewhere.

Also accepts the props of React.ComponentProps<"span">.

Accessibility

  • The input has the combobox role and items have the option role. The highlighted item sets aria-selected and disabled items set aria-disabled.
  • The first item is highlighted by default. Arrow keys move the highlight and skip disabled items; Enter selects the highlighted item.
  • CommandDialog renders a dialog named by its title, moves focus inside when it opens, closes with Escape, and returns focus to the element that opened it.
  • CommandShortcut is hidden on small screens.

Notes

  • Styling hooks: data-slot values command, command-input-wrapper, command-input, command-list, command-empty, command-group, command-separator, command-item and command-shortcut.
  • The highlighted item gets data-selected and is filled with the primary color. Disabled items get data-disabled="true".
  • An item with data-checked="true" shows a check mark, unless it contains a CommandShortcut.
  • Inside a dialog, Command drops its own background and rounded corners. The palette uses a translucent, blurred popover background.
NextContext MenuPreviousCombobox

On this page

  1. 01Installation
    • CLI
    • Manual
  2. 02Usage
  3. 03Examples
    • Empty
    • Dialog
    • Dialog open
  4. 04API Reference
    • Command
    • CommandDialog
    • CommandInput
    • CommandList
    • CommandEmpty
    • CommandGroup
    • CommandSeparator
    • CommandItem
    • CommandShortcut
  5. 05Accessibility
  6. 06Notes