For the complete documentation index, see llms.txt. Markdown variants are available by appending .md to any URL or sending an Accept: text/markdown header. An agent skill is available at /.well-known/agent-skills/site-skill.md.
Home

Command

A fast, composable command palette for searching, navigating, and triggering actions.

import { Calculator, Calendar, CreditCard, Settings, Smile, User } from "lucide-react";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut } from "@/components/ui/command";

export const CommandDemo = () => (
    <Command className="rounded-lg border shadow-md w-full max-w-sm">
      <CommandInput placeholder="Type a command or search..." />
      <CommandList>
        <CommandEmpty>No results found.</CommandEmpty>
        <CommandGroup heading="Suggestions">
          <CommandItem>
            <Calendar className="size-4" />
            <span>Calendar</span>
          </CommandItem>
          <CommandItem>
            <Smile className="size-4" />
            <span>Search Emoji</span>
          </CommandItem>
          <CommandItem>
            <Calculator className="size-4" />
            <span>Calculator</span>
          </CommandItem>
        </CommandGroup>
        <CommandSeparator />
        <CommandGroup heading="Settings">
          <CommandItem>
            <User className="size-4" />
            <span>Profile</span>
            <CommandShortcut>⌘P</CommandShortcut>
          </CommandItem>
          <CommandItem>
            <CreditCard className="size-4" />
            <span>Billing</span>
            <CommandShortcut>⌘B</CommandShortcut>
          </CommandItem>
          <CommandItem>
            <Settings className="size-4" />
            <span>Settings</span>
            <CommandShortcut>⌘S</CommandShortcut>
          </CommandItem>
        </CommandGroup>
      </CommandList>
    </Command>
  );

With Dialog

Wrap Command in CommandDialog to open it as a modal. Typically triggered with ⌘K.

"use client";
 
import { useEffect, useState } from "react";
import {
  CommandDialog,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
} from "@/components/ui/command";
 
export function CommandDialogDemo() {
  const [open, setOpen] = useState(false);
 
  useEffect(() => {
    const down = (e: KeyboardEvent) => {
      if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
        e.preventDefault();
        setOpen((prev) => !prev);
      }
    };
    document.addEventListener("keydown", down);
    return () => document.removeEventListener("keydown", down);
  }, []);
 
  return (
    <CommandDialog open={open} onOpenChange={setOpen}>
      <CommandInput placeholder="Type a command or search..." />
      <CommandList>
        <CommandEmpty>No results found.</CommandEmpty>
        <CommandGroup heading="Pages">
          <CommandItem>Home</CommandItem>
          <CommandItem>Components</CommandItem>
          <CommandItem>Settings</CommandItem>
        </CommandGroup>
      </CommandList>
    </CommandDialog>
  );
}

Inline (no dialog)

Use Command directly in the page — no popover, no dialog. Useful for embedded search panels or sidebars.

With Separator

Use CommandSeparator to visually divide groups without headings.

Props

Command

PropTypeDefaultDescription
valuestring—Controlled selected item value
onValueChange(value: string) => void—Callback when selection changes
shouldFilterbooleantrueSet to false for server-side filtering
filter(value, search) => number—Custom filter function
classNamestring—Additional CSS classes

CommandDialog

PropTypeDefaultDescription
openboolean—Controlled open state
onOpenChange(open: boolean) => void—Callback when open state changes
titlestring"Command Palette"Screen reader title (sr-only)
descriptionstring"Search for a command..."Screen reader description
showCloseButtonbooleantrueShow the × close button

CommandInput

PropTypeDefaultDescription
placeholderstring—Input placeholder text
valuestring—Controlled input value
onValueChange(value: string) => void—Callback on input change

CommandItem

PropTypeDefaultDescription
valuestring—Unique identifier used for filtering
onSelect(value: string) => void—Callback when item is selected
disabledbooleanfalsePrevents selection
keywordsstring[]—Extra search terms for this item

Usage

import {
  Command,
  CommandDialog,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
  CommandSeparator,
  CommandShortcut,
} from "@/components/ui/command";
 
// Inline panel
<Command className="rounded-lg border">
  <CommandInput placeholder="Search..." />
  <CommandList>
    <CommandEmpty>No results found.</CommandEmpty>
    <CommandGroup heading="Pages">
      <CommandItem value="home" onSelect={() => router.push("/")}>
        Home
      </CommandItem>
    </CommandGroup>
  </CommandList>
</Command>
 
// ⌘K dialog
<CommandDialog open={open} onOpenChange={setOpen}>
  <CommandInput placeholder="Type a command..." />
  <CommandList>
    <CommandEmpty>No results found.</CommandEmpty>
    <CommandGroup heading="Actions">
      <CommandItem value="settings" onSelect={openSettings}>
        <Settings className="size-4" />
        Settings
        <CommandShortcut>⌘,</CommandShortcut>
      </CommandItem>
    </CommandGroup>
  </CommandList>
</CommandDialog>

Specs

# Mint — Command Specs
 
## Component
- name: command
- file: registry/mint/command.tsx
- installs to: components/ui/command.tsx
- dependencies: cmdk, lucide-react
- registryDependencies: dialog
 
## What is it
A keyboard-driven command palette and search interface built on the cmdk primitive.
Use it as an inline search panel, a ⌘K modal, or as the dropdown layer inside a
Combobox. Avoid using Command for simple single-select dropdowns — prefer Select
or a plain list when keyboard-first navigation and fuzzy filtering are not needed.
 
## Visual identity
Popover-surface background (--popover) with matching foreground gives Command a
floating, elevated feel. Compact row height and xs group headings keep density
high. Selected items use the accent fill, consistent with other interactive
surfaces in Mint.
 
## Design tokens
--popover: oklch(1 0 0) / oklch(0.269 0 0)           — root surface background
--popover-foreground: oklch(0.145 0 0) / oklch(0.985 0 0) — root text
--accent: oklch(0.92 0.05 155) / oklch(0.26 0.05 155) — selected item background
--accent-foreground: oklch(0.32 0.1 155) / oklch(0.88 0.06 155)  — selected item text
--muted-foreground: oklch(0.52 0.06 155) / oklch(0.6 0.06 155)   — group headings, placeholder, shortcut text, search icon
--border: oklch(0.88 0.04 155 / 60%) / oklch(0.32 0.05 155 / 40%)       — CommandInput bottom border, CommandSeparator
--foreground: oklch(0.145 0 0) / oklch(0.985 0 0)     — CommandGroup item text
 
## Sub-components
- Command          → root container; manages cmdk filtering and keyboard selection state
- CommandDialog    → wraps Command in a Dialog modal (⌘K pattern); adds sr-only title/description
- CommandInput     → search field with SearchIcon prefix and border-b separator
- CommandList      → scrollable results container, max-h-[300px]
- CommandEmpty     → zero-results message; rendered automatically by cmdk when list is empty
- CommandGroup     → named section with optional xs heading
- CommandSeparator → full-width horizontal rule (bg-border) between groups
- CommandItem      → selectable row; auto-filtered against CommandInput value
- CommandShortcut  → right-aligned keyboard hint (ml-auto, xs, tracking-widest)
 
## External dependencies
- cmdk: headless command palette primitive — filtering, keyboard navigation, empty state
 
## States
- data-[selected=true]: CommandItem receives --accent background and --accent-foreground text
- data-[disabled=true]: CommandItem becomes pointer-events-none, opacity-50
- disabled (input):     CommandInput cursor changes to not-allowed, opacity-50
 
## Conventions
- Always include CommandEmpty — cmdk hides it automatically when results exist
- Match CommandItem value to the searchable identifier, not just the visible label
- Add keywords={["alias"]} to CommandItem to match on alternative terms without showing them
- CommandShortcut is display-only — wire actual keyboard shortcuts separately via useEffect
- For ⌘K: listen for metaKey+k in a useEffect keydown listener and toggle open state
- For Combobox: wrap Command in Popover and set PopoverContent className="p-0"
- CommandDialog title and description are sr-only — always provide meaningful values for screen readers
- showCloseButton={false} on CommandDialog removes the × button for a cleaner modal look
- Sub-components expose data-slot attributes for CSS targeting:
  "command", "command-input-wrapper", "command-input", "command-list",
  "command-empty", "command-group", "command-separator", "command-item", "command-shortcut"

Installation

GIN Design Plugin
$ npx shadcn add https://gin-design.vercel.app/command