82 lines
2.6 KiB
TypeScript
82 lines
2.6 KiB
TypeScript
"use client";
|
|
|
|
import React, { useState } from "react";
|
|
import Link from "next/link";
|
|
import { ChevronDown } from "lucide-react";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
interface SectionItem {
|
|
label: string;
|
|
href: string;
|
|
description?: string;
|
|
}
|
|
|
|
interface NavSection {
|
|
title: string;
|
|
items: SectionItem[];
|
|
}
|
|
|
|
interface NavDropdownProps {
|
|
label: string;
|
|
triggerHref?: string;
|
|
sections: NavSection[];
|
|
align?: "left" | "right";
|
|
}
|
|
|
|
export function NavDropdown({ label, triggerHref, sections, align = "left" }: NavDropdownProps) {
|
|
const [isOpen, setIsOpen] = useState(false);
|
|
|
|
return (
|
|
<div
|
|
className="relative group"
|
|
onMouseEnter={() => setIsOpen(true)}
|
|
onMouseLeave={() => setIsOpen(false)}
|
|
>
|
|
<div className="flex items-center gap-1 text-sm font-medium text-primary hover:text-accent transition-colors py-2 cursor-pointer">
|
|
{triggerHref ? (
|
|
<Link href={triggerHref}>{label}</Link>
|
|
) : (
|
|
<span>{label}</span>
|
|
)}
|
|
<ChevronDown className={cn("size-4 transition-transform", isOpen && "rotate-180")} />
|
|
</div>
|
|
|
|
<div
|
|
className={cn(
|
|
"absolute top-full z-50 pt-2 transition-all duration-200",
|
|
isOpen ? "opacity-100 translate-y-0 visible" : "opacity-0 translate-y-2 invisible",
|
|
align === "left" ? "left-0" : "right-0"
|
|
)}
|
|
>
|
|
<div className="bg-white border border-border shadow-xl rounded-xl p-4 min-w-[400px] flex gap-6">
|
|
{sections.map((section, sIdx) => (
|
|
<div key={sIdx} className="flex-1 min-w-[200px]">
|
|
<h4 className="text-sm font-bold text-primary mb-3 font-heading uppercase tracking-wider">{section.title}</h4>
|
|
<ul className="flex flex-col gap-2">
|
|
{section.items.map((item, iIdx) => (
|
|
<li key={iIdx}>
|
|
<Link
|
|
href={item.href}
|
|
className="block group/item"
|
|
onClick={() => setIsOpen(false)}
|
|
>
|
|
<div className="text-sm font-medium text-primary group-hover/item:text-accent transition-colors">
|
|
{item.label}
|
|
</div>
|
|
{item.description && (
|
|
<div className="text-xs text-text-muted mt-0.5 group-hover/item:text-text-muted/80">
|
|
{item.description}
|
|
</div>
|
|
)}
|
|
</Link>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|