Command Palette

Keyboard-first command menu for pages, actions, and theme switching.

Installation

npx shadcn@latest add @iconiq/command-palette

File Structure

Usage

"use client";

import { Search, Copy, FileText, Home, Layers, LogOut } from "lucide-react";

import {
  CommandPalette,
  type CommandMenuGroupDef,
} from "@/components/ui/command-palette";

const groups: CommandMenuGroupDef[] = [
  {
    heading: "Pages",
    items: [
      {
        label: "Overview",
        id: "overview",
        href: "/",
        icon: Home,
        description: "Return to the docs home page.",
        keywords: ["home", "start"],
        shortcut: "G H",
      },
      {
        label: "Installation",
        id: "installation",
        href: "/installation",
        icon: FileText,
        description: "Add Iconiq components to your project.",
        keywords: ["setup", "shadcn", "registry"],
      }
    ],
  },
  {
    heading: "Components",
    items: [
      {
        label: "Button",
        id: "button",
        href: "/buttons-and-actions/button",
        icon: Layers,
        description: "Primary action control with motion variants.",
        keywords: ["cta", "action"],
      },
      {
        label: "Dialog",
        id: "dialog",
        href: "/overlay-and-popups/dialog",
        icon: Layers,
        description: "Modal surface for focused tasks and confirmations.",
        keywords: ["modal", "overlay"],
        disabled: true,
      }
    ],
  },
  {
    heading: "Actions",
    items: [
      {
        label: "Copy page link",
        id: "copy-link",
        icon: Copy,
        description: "Copy the current docs URL to the clipboard.",
        keywords: ["share", "clipboard"],
        shortcut: "⌘C",
        action: () => {},
      },
      {
        label: "Sign out",
        id: "sign-out",
        icon: LogOut,
        description: "Demo action item without navigation.",
        keywords: ["logout", "session"],
        action: () => {},
      }
    ],
  }
];

export function CommandPalettePreview() {
  return (
    <CommandPalette
      groups={groups}
      placeholder="Search pages, components, actions…"
      showThemeGroup
      showRecentGroup
      enableGlobalShortcut={false}
      triggerProps={{
    className: "w-full max-w-md",
    label: "Open command palette",
  }}
    />
  );
}

Props

Props
Description

CommandPalette

groups

Grouped command items. Each group has a heading and an items array with label, optional href or action, icon, keywords, description, shortcut, disabled, id, and value.

Type CommandMenuGroupDef[]·Default []

showThemeGroup

When true, appends a theme group that calls next-themes setTheme. Requires ThemeProvider. Override with themeGroup for custom items.

Type boolean·Default false

themeGroup

Optional custom theme group. Used when showThemeGroup is true instead of the built-in Light, Dark, and System actions.

Type CommandMenuGroupDef

themeGroupHeading

Heading for the built-in theme group when themeGroup is not provided.

Type string·Default "Theme"

showRecentGroup

When true, shows recently selected commands from localStorage or the recentItems seed list.

Type boolean·Default false

recentItems

Optional seed list for the Recent group. Selections are also persisted to localStorage.

Type CommandMenuItemDef[]

maxRecentItems

Maximum number of recent commands to keep.

Type number·Default 5

placeholder

Placeholder copy for the search field.

Type string·Default "Search components, pages, actions…"

shortcutKey

Letter used with Cmd on macOS or Ctrl elsewhere to toggle the palette globally.

Type string·Default "k"

enableGlobalShortcut

When false, disables the document-level Cmd/Ctrl shortcut listener.

Type boolean·Default true

open

Controlled open state for the dialog.

Type boolean

onOpenChange

Called when the dialog open state changes.

Type (open: boolean) => void

onSelect

Called when a command is selected, before navigation or action execution.

Type (item: CommandMenuItemDef) => void

onNavigate

Custom navigation handler. When provided, replaces the default Next.js router.push behavior for href items.

Type (href: string, item: CommandMenuItemDef) => void

onSearch

Async search callback. Returned groups are merged with static groups and debounced by searchDebounceMs.

Type (query: string) => Promise<CommandMenuGroupDef[]>

searchDebounceMs

Debounce delay used when onSearch is provided.

Type number·Default 200

filter

Custom filter function. When omitted, ranked substring matching is used across label, keywords, and description.

Type (item: CommandMenuItemDef, query: string) => boolean

contentDelay

Milliseconds to wait before revealing the results panel after the dialog opens.

Type number·Default 0

trigger

Custom trigger node. When provided, it replaces the default search button and receives merged open handlers plus aria-expanded.

Type React.ReactNode

triggerProps

Props for the default trigger button, including label, shortcut badge visibility, and className.

Type CommandMenuTriggerProps

className

Merged onto the dialog content panel.

Type string

overlayClassName

Merged onto the dialog overlay.

Type string

positionClassName

Overrides the default dialog positioning classes. The default uses portable CSS variables with optional nav offset fallbacks.

Type string

themed

When true, applies the self-contained Iconiq theme token scope to the dialog surface.

Type boolean·Default false

showFooterHints

Shows keyboard hint badges for navigate, select, and close actions.

Type boolean·Default true

emptyMessage

Copy shown when the current query matches no items.

Type string·Default "No results found."

noQueryMessage

Copy shown when the query is empty and no items are visible.

Type string·Default "Start typing to search commands."

loadingMessage

Copy shown while onSearch is in flight.

Type string·Default "Searching…"

currentPath

Optional current route override used for the Current page badge. Defaults to usePathname when available.

Type string

closeOnRouteChange

When true, closes the palette automatically on pathname changes in Next.js App Router apps.

Type boolean·Default true

Registry bundle

Install the exact registry entry shown on the right when you want the component file and its declared runtime dependencies together.

Dependencies: @radix-ui/react-dialog, lucide-react, motion, next-themes.

Contact

Additionally, if you find any bug or issue, feel free to raise an issue.