mirror of
https://github.com/hanzoai/shadcn.git
synced 2026-11-03 03:18:52 +00:00
14 lines
3.6 KiB
JSON
14 lines
3.6 KiB
JSON
{
|
|
"name": "limelight-nav",
|
|
"description": "Animated navigation with limelight effect",
|
|
"dependencies": [
|
|
"motion"
|
|
],
|
|
"files": [
|
|
{
|
|
"name": "limelight-nav.tsx",
|
|
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Command, Search } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/registry/default/ui/button\"\nimport { Input } from \"@/registry/default/ui/input\"\n\nexport interface LimelightNavProps extends React.HTMLAttributes<HTMLElement> {\n items?: Array<{ label: string; href: string }>\n}\n\nconst LimelightNav = React.forwardRef<HTMLElement, LimelightNavProps>(\n ({ className, items = [], ...props }, ref) => {\n const [isOpen, setIsOpen] = React.useState(false)\n const [search, setSearch] = React.useState(\"\")\n\n React.useEffect(() => {\n const down = (e: KeyboardEvent) => {\n if (e.key === \"k\" && (e.metaKey || e.ctrlKey)) {\n e.preventDefault()\n setIsOpen((open) => !open)\n }\n }\n document.addEventListener(\"keydown\", down)\n return () => document.removeEventListener(\"keydown\", down)\n }, [])\n\n const filteredItems = items.filter((item) =>\n item.label.toLowerCase().includes(search.toLowerCase())\n )\n\n return (\n <>\n <nav\n ref={ref}\n className={cn(\"flex items-center gap-4\", className)}\n {...props}\n >\n <Button\n variant=\"outline\"\n onClick={() => setIsOpen(true)}\n className=\"relative w-64 justify-start\"\n >\n <Search className=\"mr-2 h-4 w-4\" />\n <span className=\"text-muted-foreground\">Search...</span>\n <kbd className=\"pointer-events-none absolute right-2 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 <Command className=\"h-3 w-3\" />K\n </kbd>\n </Button>\n {items.slice(0, 4).map((item) => (\n <a\n key={item.href}\n href={item.href}\n className=\"text-sm font-medium transition-colors hover:text-primary\"\n >\n {item.label}\n </a>\n ))}\n </nav>\n\n {isOpen && (\n <div\n className=\"fixed inset-0 z-50 bg-background/80 backdrop-blur-sm\"\n onClick={() => setIsOpen(false)}\n >\n <div\n className=\"fixed left-1/2 top-1/2 z-50 w-full max-w-lg -translate-x-1/2 -translate-y-1/2 rounded-lg border bg-card p-6 shadow-lg\"\n onClick={(e) => e.stopPropagation()}\n >\n <Input\n placeholder=\"Search navigation...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n autoFocus\n className=\"mb-4\"\n />\n <div className=\"max-h-96 space-y-1 overflow-auto\">\n {filteredItems.map((item) => (\n <a\n key={item.href}\n href={item.href}\n className=\"block rounded-md px-4 py-2 hover:bg-accent\"\n onClick={() => setIsOpen(false)}\n >\n {item.label}\n </a>\n ))}\n </div>\n </div>\n </div>\n )}\n </>\n )\n }\n)\nLimelightNav.displayName = \"LimelightNav\"\n\nexport { LimelightNav }\n"
|
|
}
|
|
],
|
|
"type": "components:ui"
|
|
} |