{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "glass-command-palette",
  "title": "Glass Command Palette",
  "description": "A spotlight-style command palette with keyboard navigation, search filtering, customizable positioning, and glass morphism styling.",
  "dependencies": [
    "lucide-react"
  ],
  "files": [
    {
      "path": "registry/innovative/glass-command-palette.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Command, Search, File, Settings, User, Home, Layers, Moon, Sun, ArrowRight } from \"lucide-react\"\nimport { cn } from \"@/lib/utils\"\n\ninterface CommandItem {\n  id: string\n  label: string\n  description?: string\n  icon?: React.ReactNode\n  shortcut?: string\n  action?: () => void\n  href?: string\n}\n\ninterface CommandGroup {\n  label: string\n  items: CommandItem[]\n}\n\ntype CommandPalettePosition = \"center\" | \"top\" | \"bottom\" | \"left\" | \"right\"\n\ninterface GlassCommandPaletteProps {\n  open?: boolean\n  onOpenChange?: (open: boolean) => void\n  groups?: CommandGroup[]\n  placeholder?: string\n  position?: CommandPalettePosition\n}\n\nconst defaultGroups: CommandGroup[] = [\n  {\n    label: \"Navigation\",\n    items: [\n      { id: \"home\", label: \"Home\", icon: <Home className=\"w-4 h-4\" />, shortcut: \"G H\", href: \"/\" },\n      { id: \"docs\", label: \"Documentation\", icon: <File className=\"w-4 h-4\" />, shortcut: \"G D\", href: \"/docs\" },\n      {\n        id: \"components\",\n        label: \"Components\",\n        icon: <Layers className=\"w-4 h-4\" />,\n        shortcut: \"G C\",\n        href: \"/docs/components/cards\",\n      },\n    ],\n  },\n  {\n    label: \"Actions\",\n    items: [\n      { id: \"settings\", label: \"Settings\", icon: <Settings className=\"w-4 h-4\" />, shortcut: \"G S\" },\n      { id: \"profile\", label: \"Profile\", icon: <User className=\"w-4 h-4\" />, shortcut: \"G P\" },\n    ],\n  },\n  {\n    label: \"Theme\",\n    items: [\n      { id: \"light\", label: \"Light Mode\", icon: <Sun className=\"w-4 h-4\" /> },\n      { id: \"dark\", label: \"Dark Mode\", icon: <Moon className=\"w-4 h-4\" /> },\n    ],\n  },\n]\n\nconst positionStyles: Record<CommandPalettePosition, { container: string; animation: string; wrapper: string }> = {\n  center: {\n    container: \"items-start justify-center pt-[20vh]\",\n    animation: \"animate-in fade-in slide-in-from-top-4 duration-200\",\n    wrapper: \"w-full max-w-xl mx-4\",\n  },\n  top: {\n    container: \"items-start justify-center pt-4\",\n    animation: \"animate-in fade-in slide-in-from-top-full duration-300\",\n    wrapper: \"w-full max-w-2xl mx-4\",\n  },\n  bottom: {\n    container: \"items-end justify-center pb-4\",\n    animation: \"animate-in fade-in slide-in-from-bottom-full duration-300\",\n    wrapper: \"w-full max-w-2xl mx-4\",\n  },\n  left: {\n    container: \"items-center justify-start\",\n    animation: \"animate-in fade-in slide-in-from-left-full duration-300\",\n    wrapper: \"w-full max-w-md h-[80vh] flex flex-col pl-4 pr-4 sm:pr-0\",\n  },\n  right: {\n    container: \"items-center justify-end\",\n    animation: \"animate-in fade-in slide-in-from-right-full duration-300\",\n    wrapper: \"w-full max-w-md h-[80vh] flex flex-col pr-4 pl-4 sm:pl-0\",\n  },\n}\n\nconst GlassCommandPalette = React.forwardRef<HTMLDivElement, GlassCommandPaletteProps>(\n  (\n    {\n      open = false,\n      onOpenChange,\n      groups = defaultGroups,\n      placeholder = \"Type a command or search...\",\n      position = \"center\",\n    },\n    ref,\n  ) => {\n    const [isOpen, setIsOpen] = React.useState(open)\n    const [search, setSearch] = React.useState(\"\")\n    const [selectedIndex, setSelectedIndex] = React.useState(0)\n    const inputRef = React.useRef<HTMLInputElement>(null)\n\n    const positionConfig = positionStyles[position]\n    const isVertical = position === \"left\" || position === \"right\"\n\n    const filteredGroups = React.useMemo(() => {\n      if (!search) return groups\n      return groups\n        .map((group) => ({\n          ...group,\n          items: group.items.filter(\n            (item) =>\n              item.label.toLowerCase().includes(search.toLowerCase()) ||\n              item.description?.toLowerCase().includes(search.toLowerCase()),\n          ),\n        }))\n        .filter((group) => group.items.length > 0)\n    }, [groups, search])\n\n    const allItems = React.useMemo(() => filteredGroups.flatMap((group) => group.items), [filteredGroups])\n\n    React.useEffect(() => {\n      setIsOpen(open)\n    }, [open])\n\n    React.useEffect(() => {\n      if (isOpen) {\n        inputRef.current?.focus()\n        setSearch(\"\")\n        setSelectedIndex(0)\n      }\n    }, [isOpen])\n\n    React.useEffect(() => {\n      const handleKeyDown = (e: KeyboardEvent) => {\n        if (e.key === \"k\" && (e.metaKey || e.ctrlKey)) {\n          e.preventDefault()\n          const newState = !isOpen\n          setIsOpen(newState)\n          onOpenChange?.(newState)\n        }\n        if (!isOpen) return\n\n        if (e.key === \"Escape\") {\n          setIsOpen(false)\n          onOpenChange?.(false)\n        }\n        if (e.key === \"ArrowDown\") {\n          e.preventDefault()\n          setSelectedIndex((prev) => (prev + 1) % allItems.length)\n        }\n        if (e.key === \"ArrowUp\") {\n          e.preventDefault()\n          setSelectedIndex((prev) => (prev - 1 + allItems.length) % allItems.length)\n        }\n        if (e.key === \"Enter\" && allItems[selectedIndex]) {\n          const item = allItems[selectedIndex]\n          if (item.href) {\n            window.location.href = item.href\n          }\n          item.action?.()\n          setIsOpen(false)\n          onOpenChange?.(false)\n        }\n      }\n\n      window.addEventListener(\"keydown\", handleKeyDown)\n      return () => window.removeEventListener(\"keydown\", handleKeyDown)\n    }, [isOpen, onOpenChange, allItems, selectedIndex])\n\n    if (!isOpen) return null\n\n    let itemIndex = -1\n\n    return (\n      <div className={cn(\"fixed inset-0 z-50 flex\", positionConfig.container)}>\n        {/* Backdrop */}\n        <div\n          className=\"absolute inset-0 bg-black/60 backdrop-blur-sm animate-in fade-in duration-200\"\n          onClick={() => {\n            setIsOpen(false)\n            onOpenChange?.(false)\n          }}\n          aria-hidden=\"true\"\n        />\n\n        {/* Command Palette */}\n        <div ref={ref} className={cn(\"relative\", positionConfig.wrapper, positionConfig.animation)}>\n          <div className=\"absolute -inset-3 rounded-2xl bg-linear-to-r from-cyan-500/20 via-blue-500/20 to-purple-500/20 blur-2xl opacity-80\" />\n          <div className=\"absolute -inset-1 rounded-2xl bg-linear-to-b from-white/10 to-white/5 blur-md\" />\n\n          {/* Main container with enhanced glass effect */}\n          <div\n            className={cn(\n              \"relative rounded-2xl border border-white/30\",\n              \"bg-white/10 backdrop-blur-3xl\",\n              \"shadow-[0_25px_50px_-12px_rgba(0,0,0,0.5),inset_0_1px_1px_rgba(255,255,255,0.2)]\",\n              \"overflow-hidden\",\n              isVertical && \"h-full flex flex-col\",\n            )}\n          >\n            {/* Glass highlight layers */}\n            <div className=\"absolute inset-0 rounded-2xl bg-linear-to-b from-white/15 via-transparent to-transparent pointer-events-none\" />\n            <div className=\"absolute inset-0 rounded-2xl bg-linear-to-tr from-transparent via-white/5 to-white/10 pointer-events-none\" />\n\n            {/* Search input */}\n            <div className=\"relative flex items-center border-b border-white/15 px-4\">\n              <Search className=\"w-5 h-5 text-white/50\" aria-hidden=\"true\" />\n              <input\n                ref={inputRef}\n                type=\"text\"\n                value={search}\n                onChange={(e) => {\n                  setSearch(e.target.value)\n                  setSelectedIndex(0)\n                }}\n                placeholder={placeholder}\n                aria-label=\"Search commands\"\n                className={cn(\n                  \"flex-1 bg-transparent border-none outline-none\",\n                  \"px-3 py-4 text-white placeholder:text-white/40\",\n                  \"text-base\",\n                )}\n              />\n              <kbd className=\"hidden sm:flex items-center gap-1 px-2 py-1 rounded-lg bg-white/10 text-white/60 text-xs border border-white/10\">\n                <Command className=\"w-3 h-3\" />K\n              </kbd>\n            </div>\n\n            {/* Results - scrollable area */}\n            <div className={cn(\"overflow-y-auto py-2\", isVertical ? \"flex-1\" : \"max-h-80\")}>\n              {filteredGroups.length === 0 ? (\n                <div className=\"px-4 py-8 text-center text-white/40\">No results found for &quot;{search}&quot;</div>\n              ) : (\n                filteredGroups.map((group) => (\n                  <div key={group.label} className=\"mb-2\" role=\"group\" aria-label={group.label}>\n                    <div className=\"px-4 py-2 text-xs font-medium text-white/40 uppercase tracking-wider\">\n                      {group.label}\n                    </div>\n                    {group.items.map((item) => {\n                      itemIndex++\n                      const isSelected = itemIndex === selectedIndex\n                      const currentIndex = itemIndex\n\n                      return (\n                        <button\n                          key={item.id}\n                          onClick={() => {\n                            if (item.href) {\n                              window.location.href = item.href\n                            }\n                            item.action?.()\n                            setIsOpen(false)\n                            onOpenChange?.(false)\n                          }}\n                          onMouseEnter={() => setSelectedIndex(currentIndex)}\n                          aria-selected={isSelected}\n                          role=\"option\"\n                          className={cn(\n                            \"w-full flex items-center gap-3 px-4 py-3\",\n                            \"text-left transition-all duration-150\",\n                            isSelected\n                              ? \"bg-white/15 text-white shadow-[inset_0_1px_0_rgba(255,255,255,0.1)]\"\n                              : \"text-white/70 hover:bg-white/10\",\n                          )}\n                        >\n                          <span\n                            className={cn(\n                              \"flex items-center justify-center w-8 h-8 rounded-xl\",\n                              \"border border-white/10 transition-all duration-150\",\n                              isSelected\n                                ? \"bg-linear-to-br from-cyan-500/40 to-blue-500/40 border-cyan-400/30\"\n                                : \"bg-white/5\",\n                            )}\n                          >\n                            {item.icon}\n                          </span>\n                          <div className=\"flex-1 min-w-0\">\n                            <div className=\"font-medium truncate\">{item.label}</div>\n                            {item.description && (\n                              <div className=\"text-sm text-white/40 truncate\">{item.description}</div>\n                            )}\n                          </div>\n                          {item.shortcut && (\n                            <div className=\"flex items-center gap-1\">\n                              {item.shortcut.split(\" \").map((key, i) => (\n                                <kbd\n                                  key={i}\n                                  className=\"px-1.5 py-0.5 rounded-md bg-white/10 text-white/50 text-xs font-mono border border-white/10\"\n                                >\n                                  {key}\n                                </kbd>\n                              ))}\n                            </div>\n                          )}\n                          {isSelected && <ArrowRight className=\"w-4 h-4 text-white/40\" />}\n                        </button>\n                      )\n                    })}\n                  </div>\n                ))\n              )}\n            </div>\n\n            {/* Footer */}\n            <div className=\"border-t border-white/15 px-4 py-2.5 flex items-center justify-between text-xs text-white/50 bg-white/5\">\n              <div className=\"flex items-center gap-4\">\n                <span className=\"flex items-center gap-1\">\n                  <kbd className=\"px-1.5 py-0.5 rounded-md bg-white/10 border border-white/10\">↑↓</kbd> Navigate\n                </span>\n                <span className=\"flex items-center gap-1\">\n                  <kbd className=\"px-1.5 py-0.5 rounded-md bg-white/10 border border-white/10\">↵</kbd> Select\n                </span>\n              </div>\n              <span className=\"flex items-center gap-1\">\n                <kbd className=\"px-1.5 py-0.5 rounded-md bg-white/10 border border-white/10\">Esc</kbd> Close\n              </span>\n            </div>\n          </div>\n        </div>\n      </div>\n    )\n  },\n)\nGlassCommandPalette.displayName = \"GlassCommandPalette\"\n\n// Trigger button component\nconst GlassCommandTrigger = React.forwardRef<HTMLButtonElement, React.ButtonHTMLAttributes<HTMLButtonElement>>(\n  ({ className, ...props }, ref) => (\n    <button\n      ref={ref}\n      className={cn(\n        \"flex items-center gap-2 px-3 py-2 rounded-xl\",\n        \"bg-white/10 backdrop-blur-xl border border-white/20\",\n        \"text-white/60 text-sm\",\n        \"hover:bg-white/15 hover:text-white/80 transition-all\",\n        \"focus:outline-none focus:ring-2 focus:ring-white/20\",\n        className,\n      )}\n      {...props}\n    >\n      <Search className=\"w-4 h-4\" />\n      <span className=\"hidden sm:inline\">Search...</span>\n      <kbd className=\"hidden sm:flex items-center gap-0.5 px-1.5 py-0.5 rounded bg-white/10 text-xs\">\n        <Command className=\"w-3 h-3\" />K\n      </kbd>\n    </button>\n  ),\n)\nGlassCommandTrigger.displayName = \"GlassCommandTrigger\"\n\nexport { GlassCommandPalette, GlassCommandTrigger }\nexport type { CommandItem, CommandGroup, CommandPalettePosition }\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:component"
}