Components

Base Components

Command

Fast command palette with search and keyboard navigation.

Example

About

The Command component is built on cmdk by Dip. Use it for searchable menus and command palettes (inline or inside CommandDialog).

Installation

Command uses the Dialog component. Add both dialog.tsx and command.tsx.

Install the following dependencies:

npm install cmdknpm install lucide-react

Create a command.tsx file and paste the following code into it.

"use client";import * as React from "react";import { Command as CommandPrimitive } from "cmdk";import { CheckIcon, SearchIcon } from "lucide-react";import { cn } from "@/lib/utils";import {  Dialog,  DialogContent,  DialogDescription,  DialogHeader,  DialogTitle,} from "@/components/ui/dialog";import { InputGroup, InputGroupAddon } from "@/components/ui/input-group";function Command({  className,  ...props}: React.ComponentProps<typeof CommandPrimitive>) {  return (    <CommandPrimitive      data-slot="command"      className={cn(        "flex size-full flex-col overflow-hidden rounded-xl! bg-popover p-1 text-popover-foreground",        className,      )}      {...props}    />  );}function CommandDialog({  title = "Command Palette",  description = "Search for a command to run...",  children,  className,  showCloseButton = false,  ...props}: React.ComponentProps<typeof Dialog> & {  title?: string;  description?: string;  className?: string;  showCloseButton?: boolean;}) {  return (    <Dialog {...props}>      <DialogHeader className="sr-only">        <DialogTitle>{title}</DialogTitle>        <DialogDescription>{description}</DialogDescription>      </DialogHeader>      <DialogContent        className={cn(          "top-1/3 translate-y-0 overflow-hidden rounded-xl! p-0",          className,        )}        showCloseButton={showCloseButton}      >        {children}      </DialogContent>    </Dialog>  );}function CommandInput({  className,  ...props}: React.ComponentProps<typeof CommandPrimitive.Input>) {  return (    <div data-slot="command-input-wrapper" className="p-1 pb-0">      <InputGroup className="h-8! rounded-lg! border-input/30 bg-input/30 shadow-none! *:data-[slot=input-group-addon]:pl-2!">        <CommandPrimitive.Input          data-slot="command-input"          className={cn(            "w-full text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50",            className,          )}          {...props}        />        <InputGroupAddon>          <SearchIcon className="size-4 shrink-0 opacity-50" />        </InputGroupAddon>      </InputGroup>    </div>  );}function CommandList({  className,  ...props}: React.ComponentProps<typeof CommandPrimitive.List>) {  return (    <CommandPrimitive.List      data-slot="command-list"      className={cn(        "no-scrollbar max-h-72 scroll-py-1 overflow-x-hidden overflow-y-auto outline-none",        className,      )}      {...props}    />  );}function CommandEmpty({  className,  ...props}: React.ComponentProps<typeof CommandPrimitive.Empty>) {  return (    <CommandPrimitive.Empty      data-slot="command-empty"      className={cn("py-6 text-center text-sm", className)}      {...props}    />  );}function CommandGroup({  className,  ...props}: React.ComponentProps<typeof CommandPrimitive.Group>) {  return (    <CommandPrimitive.Group      data-slot="command-group"      className={cn(        "overflow-hidden p-1 text-foreground **:[[cmdk-group-heading]]:px-2 **:[[cmdk-group-heading]]:py-1.5 **:[[cmdk-group-heading]]:text-xs **:[[cmdk-group-heading]]:font-medium **:[[cmdk-group-heading]]:text-muted-foreground",        className,      )}      {...props}    />  );}function CommandSeparator({  className,  ...props}: React.ComponentProps<typeof CommandPrimitive.Separator>) {  return (    <CommandPrimitive.Separator      data-slot="command-separator"      className={cn("-mx-1 h-px bg-border", className)}      {...props}    />  );}function CommandItem({  className,  children,  ...props}: React.ComponentProps<typeof CommandPrimitive.Item>) {  return (    <CommandPrimitive.Item      data-slot="command-item"      className={cn(        "group/command-item relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none in-data-[slot=dialog-content]:rounded-lg! data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 aria-selected:bg-muted aria-selected:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 aria-selected:*:[svg]:text-foreground",        className,      )}      {...props}    >      {children}      <CheckIcon className="ml-auto opacity-0 group-has-data-[slot=command-shortcut]/command-item:hidden group-data-[checked=true]/command-item:opacity-100" />    </CommandPrimitive.Item>  );}function CommandShortcut({  className,  ...props}: React.ComponentProps<"span">) {  return (    <span      data-slot="command-shortcut"      className={cn(        "ml-auto text-xs tracking-widest text-muted-foreground group-aria-selected/command-item:text-foreground",        className,      )}      {...props}    />  );}export {  Command,  CommandDialog,  CommandInput,  CommandList,  CommandEmpty,  CommandGroup,  CommandItem,  CommandShortcut,  CommandSeparator,};

Check the import paths to ensure they match your project setup.

Usage

import {
  Command,
  CommandDialog,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
  CommandSeparator,
  CommandShortcut,
} from "@/components/ui/command";
Inline command (popover, card, or sidebar):
<Command className="max-w-sm rounded-lg border">
  <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>
Command dialog (palette): wrap the same structure in CommandDialog and control open / onOpenChange. You can still use the ⌘K (or Ctrl+K) listener pattern from the cmdk docs to open the palette globally.

Examples

Basic

A simple command menu in a dialog (cmdk pattern).

Command Palette

Search for a command to run...

Shortcuts

Items with CommandShortcut for keyboard hints.

Command Palette

Search for a command to run...

Groups

Groups with icons and separators between sections.

Command Palette

Search for a command to run...

Scrollable

Scrollable list when there are many items.

Command Palette

Search for a command to run...

RTL

Right-to-left layout with translated labels.

API Reference

The Command component composes Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandSeparator, CommandShortcut, and CommandDialog. See the cmdk documentation for filtering, value, and keyboard behavior.

On this page