# Cmd+K Searchable Palette

> Command palette wired to a global Cmd+K listener, opening a searchable dialog of grouped commands with Kbd shortcuts and a last-action readout.

A shadcn/ui block from the [@7ovr](https://7ovr.com) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/7ovr/command-palette-3).

- Page, with a live preview: https://shadcn.exchange/r/7ovr/command-palette-3
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/7ovr/command-palette-3-light-b3718e1e8b3a4615.png
- Registry item: https://7ovr.com/r/command-palette-3.json
- Categories: command-palette
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://7ovr.com/r/command-palette-3.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- npm packages: `@base-ui/react`
- Registry items: `button`, `command`, `dialog`, `kbd`

## Files

### `registry/blocks/command-palette/3/command-palette-block.tsx`

```tsx
"use client"

import { useEffect, useState } from "react"
import { Button } from "@/components/ui/button"
import {
  Command,
  CommandDialog,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
  CommandShortcut,
} from "@/components/ui/command"
import { Kbd, KbdGroup } from "@/components/ui/kbd"
import { IconPlaceholder } from "@/components/icons/icon-placeholder"

type IconProps = { className?: string; size?: number | string }

type IconRenderer = (props: IconProps) => React.ReactNode

type PaletteCommand = {
  id: string
  label: string
  group: string
  icon: IconRenderer
  shortcut: string[]
}

const commands: PaletteCommand[] = [
  {
    id: "dashboard",
    label: "Go To Dashboard",
    group: "Navigation",
    icon: (p: IconProps) => (
      <IconPlaceholder
        lucide="LayoutGrid"
        tabler="IconLayoutGrid"
        hugeicons="LayoutGridIcon"
        phosphor="GridFour"
        remixicon="RiLayoutGridLine"
        {...p}
      />
    ),
    shortcut: ["G", "D"],
  },
  {
    id: "projects",
    label: "Open Projects",
    group: "Navigation",
    icon: (p: IconProps) => (
      <IconPlaceholder
        lucide="FileText"
        tabler="IconFileText"
        hugeicons="File01Icon"
        phosphor="FileText"
        remixicon="RiFileTextLine"
        {...p}
      />
    ),
    shortcut: ["G", "P"],
  },
  {
    id: "analytics",
    label: "View Analytics",
    group: "Navigation",
    icon: (p: IconProps) => (
      <IconPlaceholder
        lucide="BarChart"
        tabler="IconChartBar"
        hugeicons="BarChartIcon"
        phosphor="ChartBar"
        remixicon="RiBarChartLine"
        {...p}
      />
    ),
    shortcut: ["G", "A"],
  },
  {
    id: "members",
    label: "Browse Members",
    group: "Navigation",
    icon: (p: IconProps) => (
      <IconPlaceholder
        lucide="Users"
        tabler="IconUsersGroup"
        hugeicons="UserGroupIcon"
        phosphor="UsersThree"
        remixicon="RiTeamLine"
        {...p}
      />
    ),
    shortcut: ["G", "M"],
  },
  {
    id: "new-project",
    label: "Create New Project",
    group: "Actions",
    icon: (p: IconProps) => (
      <IconPlaceholder
        lucide="Plus"
        tabler="IconPlus"
        hugeicons="Add01Icon"
        phosphor="Plus"
        remixicon="RiAddLine"
        {...p}
      />
    ),
    shortcut: ["Ctrl", "N"],
  },
  {
    id: "profile",
    label: "Edit Profile",
    group: "Actions",
    icon: (p: IconProps) => (
      <IconPlaceholder
        lucide="User"
        tabler="IconUser"
        hugeicons="UserIcon"
        phosphor="User"
        remixicon="RiUserLine"
        {...p}
      />
    ),
    shortcut: ["Ctrl", "E"],
  },
  {
    id: "settings",
    label: "Open Settings",
    group: "Actions",
    icon: (p: IconProps) => (
      <IconPlaceholder
        lucide="Settings"
        tabler="IconSettings"
        hugeicons="SettingsIcon"
        phosphor="GearSix"
        remixicon="RiSettings3Line"
        {...p}
      />
    ),
    shortcut: ["Ctrl", ","],
  },
  {
    id: "terminal",
    label: "Open Terminal",
    group: "Actions",
    icon: (p: IconProps) => (
      <IconPlaceholder
        lucide="SquareTerminal"
        tabler="IconTerminal2"
        hugeicons="ComputerTerminal01Icon"
        phosphor="TerminalWindow"
        remixicon="RiTerminalBoxLine"
        {...p}
      />
    ),
    shortcut: ["Ctrl", "`"],
  },
  {
    id: "theme",
    label: "Toggle Dark Mode",
    group: "Preferences",
    icon: (p: IconProps) => (
      <IconPlaceholder
        lucide="Moon"
        tabler="IconMoon"
        hugeicons="MoonIcon"
        phosphor="Moon"
        remixicon="RiMoonLine"
        {...p}
      />
    ),
    shortcut: ["Ctrl", "K", "T"],
  },
]

const groupOrder = ["Navigation", "Actions", "Preferences"]

const COMMAND_GROUP_CLASS =
  "p-1.5 **:[[cmdk-group-heading]]:px-3 **:[[cmdk-group-heading]]:font-medium **:[[cmdk-group-heading]]:tracking-wide"
const COMMAND_ITEM_CLASS = "gap-2.5 px-3 py-2.5 text-sm"

export default function CommandPaletteBlock() {
  const [open, setOpen] = useState(false)
  const [ranLabel, setRanLabel] = useState<string | null>(null)

  useEffect(() => {
    function onKeyDown(event: KeyboardEvent) {
      if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "k") {
        event.preventDefault()
        setOpen((prev) => !prev)
      }
    }
    window.addEventListener("keydown", onKeyDown)
    return () => window.removeEventListener("keydown", onKeyDown)
  }, [])

  function run(cmd: PaletteCommand) {
    setRanLabel(cmd.label)
    setOpen(false)
  }

  return (
    <section className="flex min-h-svh w-full flex-col items-center justify-center gap-6 bg-muted/30 px-6 py-16 text-foreground">
      <div className="flex w-full max-w-md flex-col items-center gap-4 text-center">
        <span className="text-xs font-semibold tracking-widest text-muted-foreground uppercase">
          Acme Console
        </span>
        <h2 className="font-heading text-2xl font-semibold tracking-tight">
          Jump to anything
        </h2>
        <p className="text-sm text-muted-foreground">
          Search projects, run actions, and navigate without leaving the
          keyboard.
        </p>
        <Button
          type="button"
          variant="outline"
          onClick={() => setOpen(true)}
          className="w-full justify-between font-normal text-muted-foreground"
        >
          <span className="flex items-center gap-2">
            <IconPlaceholder
              lucide="Search"
              tabler="IconSearch"
              hugeicons="SearchIcon"
              phosphor="MagnifyingGlass"
              remixicon="RiSearchLine"
              data-icon="inline-start"
              className="size-4"
            />
            Search commands…
          </span>
          <KbdGroup>
            <Kbd>Ctrl</Kbd>
            <Kbd>K</Kbd>
          </KbdGroup>
        </Button>
        {ranLabel ? (
          <p className="text-xs text-muted-foreground">
            Last action:{" "}
            <span className="font-medium text-foreground">{ranLabel}</span>
          </p>
        ) : null}
      </div>

      <CommandDialog open={open} onOpenChange={setOpen}>
        <Command>
          <CommandInput
            aria-label="Type a command or search"
            placeholder="Type a command or search…"
            className="text-sm"
          />
          <CommandList>
            <CommandEmpty className="text-sm">No results found.</CommandEmpty>
            {groupOrder.map((group) => (
              <CommandGroup
                key={group}
                heading={group}
                className={COMMAND_GROUP_CLASS}
              >
                {commands
                  .filter((cmd) => cmd.group === group)
                  .map((cmd) => (
                    <CommandItem
                      key={cmd.id}
                      value={cmd.label}
                      onSelect={() => run(cmd)}
                      className={COMMAND_ITEM_CLASS}
                    >
                      <cmd.icon aria-hidden="true" />
                      <span className="flex-1 truncate">{cmd.label}</span>
                      <CommandShortcut>
                        <KbdGroup>
                          {cmd.shortcut.map((key) => (
                            <Kbd key={key}>{key}</Kbd>
                          ))}
                        </KbdGroup>
                      </CommandShortcut>
                    </CommandItem>
                  ))}
              </CommandGroup>
            ))}
          </CommandList>

          <div className="flex items-center justify-between border-t border-border px-4 py-2.5 text-xs text-muted-foreground">
            <div className="flex items-center gap-3">
              <span className="flex items-center gap-1.5">
                <KbdGroup>
                  <Kbd>↑</Kbd>
                  <Kbd>↓</Kbd>
                </KbdGroup>
                Navigate
              </span>
              <span className="flex items-center gap-1.5">
                <Kbd>
                  <IconPlaceholder
                    lucide="CornerDownLeft"
                    tabler="IconCornerDownLeft"
                    hugeicons="CornerDownLeftIcon"
                    phosphor="ArrowElbowDownLeft"
                    remixicon="RiCornerDownLeftLine"
                    className="size-3"
                  />
                </Kbd>
                Select
              </span>
            </div>
            <span className="hidden items-center gap-1.5 sm:flex">
              <span className="size-2 rounded-full bg-primary" />
              Acme
            </span>
          </div>
        </Command>
      </CommandDialog>
    </section>
  )
}
```
