feat(SW-272) added mega menu
This commit is contained in:
@@ -1,9 +1,16 @@
|
||||
"use client"
|
||||
|
||||
import { useState } from "react"
|
||||
import useDropdownStore from "@/stores/main-menu"
|
||||
|
||||
import { ChevronDownIcon, ChevronRightIcon } from "@/components/Icons"
|
||||
import {
|
||||
ArrowRightIcon,
|
||||
ChevronDownIcon,
|
||||
ChevronRightIcon,
|
||||
} from "@/components/Icons"
|
||||
import Card from "@/components/TempDesignSystem/Card"
|
||||
import Link from "@/components/TempDesignSystem/Link"
|
||||
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
||||
import { useHandleKeyUp } from "@/hooks/useHandleKeyUp"
|
||||
|
||||
import MainMenuButton from "../../MainMenuButton"
|
||||
|
||||
@@ -12,28 +19,93 @@ import styles from "./navigationMenuItem.module.css"
|
||||
import type { NavigationMenuItemProps } from "@/types/components/header/navigationMenuItem"
|
||||
|
||||
export default function MenuItem({ item, isMobile }: NavigationMenuItemProps) {
|
||||
const { submenu, title, link } = item
|
||||
const [isExpanded, setIsExpanded] = useState(false) // TODO: Use store to manage this state when adding the menu itself.
|
||||
const { openMegaMenu, toggleMegaMenu } = useDropdownStore()
|
||||
const { submenu, title, link, seeAllLink, card } = item
|
||||
const isMegaMenuOpen = openMegaMenu === title
|
||||
|
||||
function handleButtonClick() {
|
||||
setIsExpanded((prev) => !prev)
|
||||
useHandleKeyUp((event: KeyboardEvent) => {
|
||||
if (event.key === "Escape" && isMegaMenuOpen) {
|
||||
toggleMegaMenu(false)
|
||||
}
|
||||
})
|
||||
|
||||
function handleLinkClick() {
|
||||
toggleMegaMenu(false)
|
||||
}
|
||||
|
||||
return submenu.length ? (
|
||||
<MainMenuButton
|
||||
onClick={handleButtonClick}
|
||||
className={`${styles.navigationMenuItem} ${isMobile ? styles.mobile : styles.desktop}`}
|
||||
>
|
||||
{title}
|
||||
{isMobile ? (
|
||||
<ChevronRightIcon className={`${styles.chevron}`} color="red" />
|
||||
) : (
|
||||
<ChevronDownIcon
|
||||
className={`${styles.chevron} ${isExpanded ? styles.isExpanded : ""}`}
|
||||
color="red"
|
||||
/>
|
||||
)}
|
||||
</MainMenuButton>
|
||||
<span className={styles.menuWrapper}>
|
||||
<MainMenuButton
|
||||
onClick={() => toggleMegaMenu(title)}
|
||||
className={`${styles.navigationMenuItem} ${isMobile ? styles.mobile : styles.desktop}`}
|
||||
>
|
||||
{title}
|
||||
{isMobile ? (
|
||||
<ChevronRightIcon className={`${styles.chevron}`} color="red" />
|
||||
) : (
|
||||
<ChevronDownIcon
|
||||
className={`${styles.chevron} ${isMegaMenuOpen ? styles.isExpanded : ""}`}
|
||||
color="red"
|
||||
/>
|
||||
)}
|
||||
</MainMenuButton>
|
||||
{isMegaMenuOpen ? (
|
||||
<nav className={styles.megaMenu}>
|
||||
<div className={styles.seeAllLink}>
|
||||
{seeAllLink?.link ? (
|
||||
<Link
|
||||
href={seeAllLink?.link?.url}
|
||||
color="burgundy"
|
||||
variant="icon"
|
||||
onClick={handleLinkClick}
|
||||
>
|
||||
{seeAllLink.title}
|
||||
<ArrowRightIcon color="burgundy" />
|
||||
</Link>
|
||||
) : null}
|
||||
</div>
|
||||
<ul className={styles.submenus}>
|
||||
{submenu.map((item) => (
|
||||
<li key={item.title} className={styles.submenusItem}>
|
||||
<Caption textTransform="uppercase" asChild>
|
||||
<span>{item.title}</span>
|
||||
</Caption>
|
||||
<ul className={styles.submenu}>
|
||||
{item.links.map((link) =>
|
||||
link?.link ? (
|
||||
<li key={link.title} className={styles.submenuItem}>
|
||||
<Link
|
||||
href={link.link?.url}
|
||||
color="burgundy"
|
||||
className={styles.link}
|
||||
onClick={handleLinkClick}
|
||||
>
|
||||
{link.title}
|
||||
</Link>
|
||||
</li>
|
||||
) : null
|
||||
)}
|
||||
</ul>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
{card ? (
|
||||
<Card
|
||||
className={styles.card}
|
||||
backgroundImage={card.backgroundImage}
|
||||
bodyText={card.body_text}
|
||||
heading={card.heading}
|
||||
primaryButton={card.primaryButton}
|
||||
secondaryButton={card.secondaryButton}
|
||||
scriptedTopTitle={card.scripted_top_title}
|
||||
onPrimaryButtonClick={handleLinkClick}
|
||||
onSecondaryButtonClick={handleLinkClick}
|
||||
theme="image"
|
||||
/>
|
||||
) : null}
|
||||
</nav>
|
||||
) : null}
|
||||
</span>
|
||||
) : (
|
||||
<Link
|
||||
className={`${styles.navigationMenuItem} ${isMobile ? styles.mobile : styles.desktop}`}
|
||||
|
||||
@@ -12,3 +12,108 @@
|
||||
.chevron.isExpanded {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.menuWrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.megaMenu {
|
||||
position: absolute;
|
||||
top: var(--Spacing-x5);
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background-color: var(--Base-Surface-Primary-light-Normal);
|
||||
border-radius: var(--Corner-radius-Large);
|
||||
box-shadow: 0 0 14px 6px rgba(0, 0, 0, 0.1);
|
||||
z-index: var(--menu-overlay-z-index);
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr;
|
||||
grid-template-areas:
|
||||
"seeAllLink"
|
||||
"submenus";
|
||||
width: 600px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.megaMenu:has(.card) {
|
||||
width: 900px;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-template-areas:
|
||||
"seeAllLink seeAllLink card"
|
||||
"submenus submenus card";
|
||||
}
|
||||
|
||||
.seeAllLink {
|
||||
grid-area: seeAllLink;
|
||||
display: flex;
|
||||
padding: var(--Spacing-x2) var(--Spacing-x3);
|
||||
align-items: center;
|
||||
gap: var(--Spacing-x1);
|
||||
background-color: var(--Base-Surface-Secondary-light-Normal);
|
||||
}
|
||||
|
||||
.submenus {
|
||||
grid-area: submenus;
|
||||
list-style: none;
|
||||
display: grid;
|
||||
gap: var(--Spacing-x5);
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
padding: var(--Spacing-x2) var(--Spacing-x4);
|
||||
}
|
||||
|
||||
.submenusItem {
|
||||
display: grid;
|
||||
gap: var(--Spacing-x1);
|
||||
align-content: start;
|
||||
}
|
||||
.submenusItem:first-child {
|
||||
border-right: 1px solid var(--Primary-Light-On-Surface-Divider-subtle);
|
||||
}
|
||||
|
||||
.submenu {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.submenuItem {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.link {
|
||||
padding: var(--Spacing-x1) 0;
|
||||
font-weight: var(--typography-Body-Bold-fontWeight);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.megaMenu .card {
|
||||
grid-area: card;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.backgroundImage {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.backgroundImage::after {
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(0, 0, 0, 0) 0%,
|
||||
rgba(0, 0, 0, 0.36) 50%,
|
||||
rgba(0, 0, 0, 0.75) 100%
|
||||
);
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
.image {
|
||||
display: flex;
|
||||
object-fit: cover;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user