x
This commit is contained in:
1 parent
7b98d41555
commit
996dfdabd0
10 files changed
+959
-252
No files matched your search
@@ -0,0 +1,102 @@
|
||||
"use client"
|
||||
|
||||
import Link from 'next/link'
|
||||
import { useState, useRef } from 'react'
|
||||
import type { MegaMenuPayload } from './menuTypes'
|
||||
import { getLocalizedMenuText } from './menuTypes'
|
||||
|
||||
interface DesktopMegaMenuProps {
|
||||
items: MegaMenuPayload[]
|
||||
lang: string
|
||||
currentPath: string
|
||||
}
|
||||
|
||||
export function DesktopMegaMenu({ items, lang, currentPath }: DesktopMegaMenuProps) {
|
||||
const [openId, setOpenId] = useState<string | null>(null)
|
||||
const closeTimer = useRef<ReturnType<typeof setTimeout> | null>(null)
|
||||
|
||||
const handleOpen = (id: string) => {
|
||||
if (closeTimer.current) clearTimeout(closeTimer.current)
|
||||
setOpenId(id)
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
closeTimer.current = setTimeout(() => setOpenId(null), 150)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="hidden space-x-7 text-sm font-medium uppercase tracking-wide md:flex">
|
||||
{items.map((item, index) => {
|
||||
const uniqueId = item.nodeId || item.id || `menu-${item.url || index}`
|
||||
const isOpen = openId === uniqueId
|
||||
const hasColumns = !!item.columns?.length
|
||||
const isActive = item.url ? currentPath === item.url : false
|
||||
|
||||
return (
|
||||
<div
|
||||
key={uniqueId}
|
||||
className="relative"
|
||||
onMouseEnter={() => handleOpen(uniqueId)}
|
||||
onMouseLeave={handleClose}
|
||||
>
|
||||
<Link
|
||||
href={item.url || '#'}
|
||||
className={`flex items-center gap-1 border-b py-2 transition-colors ${
|
||||
isOpen || isActive
|
||||
? 'border-pop-pink text-pop-black'
|
||||
: 'border-transparent text-pop-black/65 hover:border-pop-pink hover:text-pop-black'
|
||||
}`}
|
||||
>
|
||||
{getLocalizedMenuText(item.label, lang)}
|
||||
{hasColumns && (
|
||||
<svg
|
||||
className={`h-3 w-3 opacity-50 transition-transform duration-300 ${isOpen ? 'rotate-180' : ''}`}
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
|
||||
</svg>
|
||||
)}
|
||||
</Link>
|
||||
|
||||
{hasColumns && (
|
||||
<div
|
||||
className={`fixed left-0 right-0 z-50 transition-opacity duration-200 ${
|
||||
isOpen ? 'pointer-events-auto opacity-100' : 'pointer-events-none opacity-0'
|
||||
}`}
|
||||
style={{ top: 'var(--navbar-bottom, 64px)' }}
|
||||
onMouseEnter={() => handleOpen(uniqueId)}
|
||||
onMouseLeave={handleClose}
|
||||
>
|
||||
<div className="w-full cursor-default border-b border-black/5 bg-white/95 shadow-brutal backdrop-blur-xl">
|
||||
<div className="mx-auto flex max-w-7xl justify-center gap-16 px-6 py-10">
|
||||
{item.columns!.map((column, columnIndex) => (
|
||||
<div key={columnIndex} className="flex min-w-[140px] flex-col text-left">
|
||||
<h4 className="mb-4 text-[10px] font-bold uppercase tracking-widest text-pop-black/50">
|
||||
{getLocalizedMenuText(column.title, lang)}
|
||||
</h4>
|
||||
<ul className="space-y-3">
|
||||
{column.links.map((link, linkIndex) => (
|
||||
<li key={linkIndex}>
|
||||
<Link
|
||||
href={link.url || '#'}
|
||||
className="block text-sm font-normal normal-case tracking-normal text-pop-black/65 transition-colors hover:text-pop-pink"
|
||||
>
|
||||
{getLocalizedMenuText(link.label, lang)}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user