This commit is contained in:
Your Name committed 2026-07-14 19:26:20 -04:00
1 parent f6c188bd93
commit b78c9467bc
9 files changed
+656 -49

No files matched your search

@@ -5,19 +5,24 @@ import Image from 'next/image'
import { useState, useRef } from 'react'
import {
ArrowRight,
Award,
Box,
ChevronRight,
Gift,
Leaf,
Package,
ShoppingBag,
Sparkles,
Star,
type LucideIcon,
Sparkles,
Box,
} from 'lucide-react'
import type { MegaMenuPayload, MenuColumn } from './menuTypes'
import { getLocalizedMenuText } from './menuTypes'
import { ICON_REGISTRY, type AvailableIcons } from './iconRegistry'
function DynamicIcon({ iconName, defaultIcon: DefaultIcon, className, strokeWidth }: { iconName?: string, defaultIcon: any, className?: string, strokeWidth?: number }) {
const IconComponent = (iconName && ICON_REGISTRY[iconName as AvailableIcons])
? ICON_REGISTRY[iconName as AvailableIcons]
: DefaultIcon;
return <IconComponent className={className} strokeWidth={strokeWidth} />;
}
interface DesktopMegaMenuProps {
items: MegaMenuPayload[]
@@ -25,14 +30,7 @@ interface DesktopMegaMenuProps {
currentPath: string
}
const MENU_ICONS: LucideIcon[] = [
ShoppingBag,
Sparkles,
Leaf,
Package,
Gift,
Award,
]
const MAX_TOP_LEVEL_LINKS = 5
const MAX_INLINE_CHILD_LINKS = 3
@@ -52,11 +50,13 @@ function MenuImage({
alt,
placeholder,
className = '',
style,
}: {
src?: string | null
alt: string
placeholder?: string
className?: string
style?: React.CSSProperties
}) {
const [loaded, setLoaded] = useState(false)
@@ -74,6 +74,7 @@ function MenuImage({
fill
sizes="(max-width: 1024px) 0px, 224px"
className={`object-cover transition-opacity duration-300 ${loaded ? 'opacity-100' : 'opacity-0'} ${className}`}
style={style}
onLoad={() => setLoaded(true)}
loading="lazy"
/>
@@ -120,6 +121,8 @@ export function DesktopMegaMenu({ items, lang, currentPath }: DesktopMegaMenuPro
const showFeatured = featuredConfig?.enabled !== false
const configuredImage = featuredConfig?.imageUrl || null
const featuredImage = hoveredLinkImage ?? configuredImage ?? featuredLink?.imageUrl ?? item.rootImageUrl
const focalPoint = featuredConfig?.focalPoint
const objectPosition = focalPoint ? `${focalPoint.x} ${focalPoint.y}` : 'center'
const featuredHeading = getLocalizedMenuText(featuredConfig?.sectionTitle, lang) || 'Featured'
const featuredBadge = getLocalizedMenuText(featuredConfig?.badge, lang) || 'Recommended'
const featuredTitle = getLocalizedMenuText(featuredConfig?.title, lang)
@@ -179,15 +182,16 @@ export function DesktopMegaMenu({ items, lang, currentPath }: DesktopMegaMenuPro
className={`pr-8 ${columnIndex > 0 ? 'border-l border-line-primary/15 pl-8' : ''}`}
>
<h4 className="mb-5 flex items-center gap-3 text-xs font-bold normal-case tracking-normal text-text-main">
{(() => {
const HeadingIcon = MENU_ICONS[columnIndex] ?? Sparkles
return <HeadingIcon className="h-4 w-4 text-brand-primary" strokeWidth={1.5} />
})()}
<DynamicIcon
iconName={column.icon}
defaultIcon={Sparkles}
className="h-4 w-4 text-brand-primary"
strokeWidth={1.5}
/>
{getLocalizedMenuText(column.title, lang)}
</h4>
<ul className="space-y-2">
{column.links.slice(0, MAX_TOP_LEVEL_LINKS).map((link, linkIndex) => {
const RowIcon = MENU_ICONS[(columnIndex * 3 + linkIndex + 1) % MENU_ICONS.length] ?? Box
const hasNestedLinks = !!link.links?.length
const visibleChildLinks = link.links?.slice(0, MAX_INLINE_CHILD_LINKS) ?? []
const hiddenChildCount = Math.max((link.links?.length ?? 0) - MAX_INLINE_CHILD_LINKS, 0)
@@ -205,7 +209,12 @@ export function DesktopMegaMenu({ items, lang, currentPath }: DesktopMegaMenuPro
className="group flex items-center gap-4 rounded-md px-1 py-2.5 text-left transition-colors hover:bg-surface-muted"
>
<span className="flex h-9 w-9 shrink-0 items-center justify-center rounded-md border border-line-primary/20 bg-surface-page text-brand-primary transition-colors group-hover:border-brand-primary/40">
<RowIcon className="h-5 w-5" strokeWidth={1.35} />
<DynamicIcon
iconName={link.icon}
defaultIcon={Box}
className="h-5 w-5"
strokeWidth={1.35}
/>
</span>
<span className="min-w-0 flex-1">
<span className="block text-sm font-bold normal-case tracking-normal text-text-main">
@@ -275,6 +284,8 @@ export function DesktopMegaMenu({ items, lang, currentPath }: DesktopMegaMenuPro
src={featuredImage}
alt={featuredTitle}
placeholder={getLocalizedMenuText(item.label, lang)}
className="h-full w-full object-cover transition-transform duration-700 group-hover:scale-105"
style={{ objectPosition }}
/>
</div>
<div className="space-y-2 p-4">