{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "search-dialog",
  "type": "registry:component",
  "title": "Search Dialog",
  "description": "Full-screen search dialog with keyboard navigation.",
  "dependencies": [
    "@vllnt/ui@^0.2.1"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/default/search-dialog/search-dialog.tsx",
      "content": "\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\nimport { Search } from \"lucide-react\";\n\nimport { cn } from \"@vllnt/ui\";\nimport { Button } from \"@vllnt/ui\";\nimport {\n  CommandDialog,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n} from \"@vllnt/ui\";\n\ntype SearchItem = {\n  description?: string;\n  id: string;\n  keywords?: string;\n  title: string;\n};\n\nfunction useKeyboardShortcut(callback: () => void) {\n  useEffect(() => {\n    const down = (event: KeyboardEvent) => {\n      if (\n        (event.key === \"k\" || event.key === \"K\") &&\n        (event.metaKey || event.ctrlKey)\n      ) {\n        const target = event.target as HTMLElement | null;\n        if (\n          target &&\n          (target.tagName === \"INPUT\" ||\n            target.tagName === \"TEXTAREA\" ||\n            target.isContentEditable)\n        ) {\n          return;\n        }\n\n        event.preventDefault();\n        event.stopPropagation();\n        event.stopImmediatePropagation();\n        callback();\n      }\n    };\n\n    window.addEventListener(\"keydown\", down, { capture: true, passive: false });\n    return () => {\n      window.removeEventListener(\"keydown\", down, { capture: true });\n    };\n  }, [callback]);\n}\n\ntype SearchDialogProps = {\n  buttonText?: string;\n  buttonTextMobile?: string;\n  emptyText?: string;\n  enableKeyboardShortcut?: boolean;\n  groupHeading?: string;\n  items: SearchItem[];\n  onSelect: (item: SearchItem) => void;\n  searchPlaceholder?: string;\n};\n\nexport function SearchDialog({\n  buttonText = \"Search...\",\n  buttonTextMobile = \"Search...\",\n  emptyText = \"No results found.\",\n  enableKeyboardShortcut = true,\n  groupHeading,\n  items,\n  onSelect,\n  searchPlaceholder = \"Search...\",\n}: SearchDialogProps) {\n  const [open, setOpen] = useState(false);\n\n  const sortedItems = [...items].sort((a, b) => a.title.localeCompare(b.title));\n\n  useKeyboardShortcut(() => {\n    if (enableKeyboardShortcut) {\n      setOpen((previous) => !previous);\n    }\n  });\n\n  const handleSelect = (item: SearchItem) => {\n    setOpen(false);\n    onSelect(item);\n  };\n\n  return (\n    <>\n      <Button\n        className={cn(\n          \"relative h-9 w-full justify-start text-sm text-muted-foreground sm:pr-12 md:w-40 lg:w-64\",\n        )}\n        onClick={() => {\n          setOpen(true);\n        }}\n        variant=\"outline\"\n      >\n        <Search className=\"mr-2 size-4\" />\n        <span className=\"hidden lg:inline-flex\">{buttonText}</span>\n        <span className=\"inline-flex lg:hidden\">{buttonTextMobile}</span>\n        <kbd className=\"pointer-events-none absolute right-1.5 top-1.5 hidden h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium opacity-100 sm:flex\">\n          <span className=\"text-xs\">⌘</span>K\n        </kbd>\n      </Button>\n      <CommandDialog onOpenChange={setOpen} open={open}>\n        <CommandInput placeholder={searchPlaceholder} />\n        <CommandList>\n          <CommandEmpty>{emptyText}</CommandEmpty>\n          <CommandGroup heading={groupHeading}>\n            {sortedItems.map((item) => (\n              <CommandItem\n                key={item.id}\n                onSelect={() => {\n                  handleSelect(item);\n                }}\n                value={`${item.title} ${item.description || \"\"} ${item.keywords || \"\"} ${item.id}`}\n              >\n                <div className=\"flex flex-col\">\n                  <span className=\"font-medium\">{item.title}</span>\n                  {item.description ? (\n                    <span className=\"text-xs text-muted-foreground\">\n                      {item.description}\n                    </span>\n                  ) : null}\n                </div>\n              </CommandItem>\n            ))}\n          </CommandGroup>\n        </CommandList>\n      </CommandDialog>\n    </>\n  );\n}\n",
      "type": "registry:component"
    }
  ],
  "version": "0.2.1",
  "stability": "stable"
}
