{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "command-palette",
  "type": "registry:ui",
  "title": "Command Palette",
  "description": "⌘K launcher — Base UI Autocomplete rendered inline and always-open inside a Dialog.",
  "dependencies": [
    "@base-ui/react",
    "lucide-react"
  ],
  "registryDependencies": [
    "https://seamui.dev/r/utils.json",
    "https://seamui.dev/r/motion.json",
    "https://seamui.dev/r/kbd.json"
  ],
  "files": [
    {
      "path": "registry/seam/ui/command-palette.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Autocomplete } from \"@base-ui/react/autocomplete\"\nimport { Dialog as BaseDialog } from \"@base-ui/react/dialog\"\nimport { Search } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { condense } from \"@/lib/motion\"\nimport { Kbd } from \"./kbd\"\n\n// The ⌘K surface: Base UI Autocomplete rendered `inline` + always `open`\n// inside a Dialog (the documented composition — the dialog owns mount/unmount,\n// so filter, highlight, and input reset on close). The palette panel is a\n// modal key rising on condense; the search field is a debossed entry well;\n// shortcut hints are embossed Kbd caps.\n\n// Root: a Dialog that also owns the global ⌘/Ctrl+K binding. Controlled or\n// uncontrolled — the hotkey works either way because open state resolves here.\nfunction CommandPalette({\n  defaultOpen = false,\n  open: openProp,\n  onOpenChange,\n  hotkey = true,\n  ...props\n}: Omit<React.ComponentProps<typeof BaseDialog.Root>, \"onOpenChange\"> & {\n  /** Bind ⌘/Ctrl+K to toggle the palette. */\n  hotkey?: boolean\n  /** Fires on open/close. `eventDetails` is `undefined` for the global-hotkey\n   *  toggle — no Base UI event originates it — and present otherwise. */\n  onOpenChange?: (\n    open: boolean,\n    eventDetails?: Parameters<\n      NonNullable<React.ComponentProps<typeof BaseDialog.Root>[\"onOpenChange\"]>\n    >[1]\n  ) => void\n}) {\n  const [openState, setOpenState] = React.useState(defaultOpen)\n  const open = openProp ?? openState\n\n  const handleOpenChange: React.ComponentProps<\n    typeof BaseDialog.Root\n  >[\"onOpenChange\"] = (next, eventDetails) => {\n    if (openProp === undefined) setOpenState(next)\n    onOpenChange?.(next, eventDetails)\n  }\n\n  React.useEffect(() => {\n    if (!hotkey) return\n    const onKeyDown = (e: KeyboardEvent) => {\n      if (\n        e.key === \"k\" &&\n        (e.metaKey || e.ctrlKey) &&\n        !e.shiftKey &&\n        !e.altKey\n      ) {\n        e.preventDefault()\n        if (openProp === undefined) setOpenState(!open)\n        // no Base UI eventDetails exists for a global-hotkey toggle\n        onOpenChange?.(!open)\n      }\n    }\n    window.addEventListener(\"keydown\", onKeyDown)\n    return () => window.removeEventListener(\"keydown\", onKeyDown)\n  }, [hotkey, open, openProp, onOpenChange])\n\n  return (\n    <BaseDialog.Root open={open} onOpenChange={handleOpenChange} {...props} />\n  )\n}\n\nfunction CommandPaletteTrigger(\n  props: React.ComponentProps<typeof BaseDialog.Trigger>\n) {\n  return <BaseDialog.Trigger data-slot=\"command-palette-trigger\" {...props} />\n}\n\n// The panel: top-aligned modal key + the always-open inline Autocomplete.\n// `items` drives Base UI's built-in filtering; `autoHighlight` keeps the top\n// match ready for Enter, cmdk-style.\nfunction CommandPaletteContent({\n  items,\n  autocomplete,\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof BaseDialog.Popup> & {\n  items: React.ComponentProps<typeof Autocomplete.Root>[\"items\"]\n  /** Escape hatch for the underlying Autocomplete.Root: pass `filter`,\n   *  `value`/`onValueChange`, `itemToStringValue`, `onItemHighlighted`, etc.\n   *  Overrides the palette's tunable defaults (autoHighlight/keepHighlight);\n   *  the `open`/`inline` composition stays locked so the dialog keeps owning\n   *  mount/unmount. */\n  autocomplete?: Omit<\n    React.ComponentProps<typeof Autocomplete.Root>,\n    \"items\" | \"children\" | \"open\" | \"inline\"\n  >\n}) {\n  return (\n    <BaseDialog.Portal>\n      <BaseDialog.Backdrop\n        data-slot=\"command-palette-backdrop\"\n        className={cn(\"fixed inset-0 z-50 bg-black/50\", condense.backdrop)}\n      />\n      <BaseDialog.Popup\n        data-slot=\"command-palette-content\"\n        aria-label=\"Command palette\"\n        className={cn(\n          \"bg-popover text-popover-foreground fixed left-1/2 top-[20%] z-50 flex w-[calc(100vw-2rem)] max-w-lg -translate-x-1/2 flex-col overflow-hidden rounded-xl squircle border shadow-modal outline-none\",\n          condense.surface,\n          className\n        )}\n        {...props}\n      >\n        <Autocomplete.Root\n          autoHighlight=\"always\"\n          keepHighlight\n          items={items}\n          {...autocomplete}\n          open\n          inline\n        >\n          {children}\n        </Autocomplete.Root>\n      </BaseDialog.Popup>\n    </BaseDialog.Portal>\n  )\n}\n\n// The debossed search well the palette opens onto.\nfunction CommandPaletteInput({\n  className,\n  ...props\n}: React.ComponentProps<typeof Autocomplete.Input>) {\n  return (\n    <div className=\"relative m-2 mb-0\">\n      <Search className=\"text-muted-foreground pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2\" />\n      <Autocomplete.Input\n        data-slot=\"command-palette-input\"\n        aria-label=\"Search commands\"\n        className={cn(\n          \"flex h-10 w-full min-w-0 rounded-md squircle border border-border/60 bg-muted py-1 pl-9 pr-3 text-sm shadow-well outline-none\",\n          \"placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground\",\n          \"focus-visible:ring-2 focus-visible:ring-ring/50 focus-visible:border-ring\",\n          className\n        )}\n        {...props}\n      />\n      <BaseDialog.Close className=\"sr-only\">\n        Close command palette\n      </BaseDialog.Close>\n    </div>\n  )\n}\n\nfunction CommandPaletteList({\n  className,\n  ...props\n}: React.ComponentProps<typeof Autocomplete.List>) {\n  return (\n    <Autocomplete.List\n      data-slot=\"command-palette-list\"\n      className={cn(\n        \"max-h-72 overflow-y-auto overscroll-contain p-1.5 outline-none\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandPaletteGroup(\n  props: React.ComponentProps<typeof Autocomplete.Group>\n) {\n  return <Autocomplete.Group data-slot=\"command-palette-group\" {...props} />\n}\n\nfunction CommandPaletteGroupLabel({\n  className,\n  ...props\n}: React.ComponentProps<typeof Autocomplete.GroupLabel>) {\n  return (\n    <Autocomplete.GroupLabel\n      data-slot=\"command-palette-group-label\"\n      className={cn(\n        \"text-muted-foreground px-2 py-1.5 text-xs font-medium select-none\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\n/** Renders the filtered items within a group. */\nconst CommandPaletteCollection = Autocomplete.Collection\n\n// A command row: icon slot, label, optional Kbd shortcut. Highlight is the\n// accent treatment shared with combobox/menu items.\nfunction CommandPaletteItem({\n  shortcut,\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof Autocomplete.Item> & {\n  shortcut?: React.ReactNode\n}) {\n  return (\n    <Autocomplete.Item\n      data-slot=\"command-palette-item\"\n      className={cn(\n        \"flex cursor-default select-none items-center gap-2 rounded-md squircle px-2 py-1.5 text-sm outline-none\",\n        \"data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground\",\n        \"data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n        \"[&_svg:not([class*='size-'])]:size-4 [&_svg]:text-muted-foreground [&_svg]:shrink-0\",\n        className\n      )}\n      {...props}\n    >\n      <span className=\"flex min-w-0 flex-1 items-center gap-2 truncate\">\n        {children}\n      </span>\n      {shortcut ? <Kbd className=\"shrink-0\">{shortcut}</Kbd> : null}\n    </Autocomplete.Item>\n  )\n}\n\nfunction CommandPaletteEmpty({\n  className,\n  ...props\n}: React.ComponentProps<typeof Autocomplete.Empty>) {\n  return (\n    <Autocomplete.Empty\n      data-slot=\"command-palette-empty\"\n      className={cn(\n        \"text-muted-foreground py-6 text-center text-sm empty:py-0\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\n// Hint row of embossed keycaps along the bottom edge.\nfunction CommandPaletteFooter({\n  className,\n  ...props\n}: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"command-palette-footer\"\n      className={cn(\n        \"text-muted-foreground border-border/60 flex items-center gap-3 border-t px-3 py-2 text-xs\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  CommandPalette,\n  CommandPaletteTrigger,\n  CommandPaletteContent,\n  CommandPaletteInput,\n  CommandPaletteList,\n  CommandPaletteGroup,\n  CommandPaletteGroupLabel,\n  CommandPaletteCollection,\n  CommandPaletteItem,\n  CommandPaletteEmpty,\n  CommandPaletteFooter,\n}\n",
      "type": "registry:ui",
      "target": "components/ui/command-palette.tsx"
    }
  ]
}