mega menu
This commit is contained in:
@@ -0,0 +1,74 @@
|
|||||||
|
import businessCardMenu from "@/assets/images/business-card-menu.png";
|
||||||
|
import Image from "next/image";
|
||||||
|
import { FC } from "react";
|
||||||
|
|
||||||
|
type CategoryGroup = {
|
||||||
|
title: string;
|
||||||
|
items: string[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const columns: CategoryGroup[][] = [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
title: "کارتهای استاندارد",
|
||||||
|
items: ["مات", "براق", "بدون روکش"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "شکلهای خاص",
|
||||||
|
items: ["گوشه گرد", "مربع", "دایره", "بیضی"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
title: "کارتهای پریمیوم",
|
||||||
|
items: ["بافت طبیعی", "مخملی", "پنبهای", "کتانی (Linen)", "کرافت"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "کارتهای لوکس",
|
||||||
|
items: ["پریمیوم پلاس", "لبه رنگی", "فوقضخیم", "پلاستیکی"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
title: "روکش های ویژه",
|
||||||
|
items: ["فویل تزئینی", "برجسته براق", "فویل برجسته"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "کارتهای ویزیت دیجیتال",
|
||||||
|
items: ["کارت ویزیت دارای کد QR"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
const AllProductsMenu: FC = () => {
|
||||||
|
return (
|
||||||
|
<div className="absolute top-full right-[120px] z-50 mt-2 w-[1099px] rounded-[32px] bg-[#F9FAFB]/90 px-8 pt-8 pb-10">
|
||||||
|
<div className="flex w-full items-start justify-between">
|
||||||
|
{columns.map((groups) => (
|
||||||
|
<div key={groups[0].title} className="flex w-[228px] shrink-0 flex-col gap-6">
|
||||||
|
{groups.map((group) => (
|
||||||
|
<div key={group.title} className="flex flex-col gap-2">
|
||||||
|
<div className="flex h-10 items-center px-4 text-base font-bold text-black">{group.title}</div>
|
||||||
|
{group.items.map((item) => (
|
||||||
|
<button
|
||||||
|
key={item}
|
||||||
|
type="button"
|
||||||
|
className="flex h-6 w-full items-center px-4 text-right text-base font-medium text-[#011E3A] transition-colors hover:text-primary"
|
||||||
|
>
|
||||||
|
{item}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
|
||||||
|
<div className="relative h-[157px] w-[163px] shrink-0 overflow-hidden rounded-2xl">
|
||||||
|
<Image src={businessCardMenu} alt="کارت ویزیت" fill className="object-cover" sizes="163px" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AllProductsMenu;
|
||||||
@@ -1,21 +1,62 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { cn } from "@/app/lib/cn";
|
||||||
import { HamburgerMenu } from "iconsax-reactjs";
|
import { HamburgerMenu } from "iconsax-reactjs";
|
||||||
import { FC } from "react";
|
import { FC, useEffect, useRef, useState } from "react";
|
||||||
|
import AllProductsMenu from "./AllProductsMenu";
|
||||||
|
|
||||||
|
const menuItems = ["کارت ویزیت", "کاتالوگ", "بروشور", "کارت تبریک", "جعبه", "ساک دستی", "هدایای تبلیغاتی"];
|
||||||
|
|
||||||
const HeaderMenu: FC = () => {
|
const HeaderMenu: FC = () => {
|
||||||
|
const [isAllProductsOpen, setIsAllProductsOpen] = useState(false);
|
||||||
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isAllProductsOpen) return;
|
||||||
|
|
||||||
|
const handlePointerDown = (event: MouseEvent) => {
|
||||||
|
if (!containerRef.current?.contains(event.target as Node)) {
|
||||||
|
setIsAllProductsOpen(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleEscape = (event: KeyboardEvent) => {
|
||||||
|
if (event.key === "Escape") {
|
||||||
|
setIsAllProductsOpen(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener("mousedown", handlePointerDown);
|
||||||
|
document.addEventListener("keydown", handleEscape);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener("mousedown", handlePointerDown);
|
||||||
|
document.removeEventListener("keydown", handleEscape);
|
||||||
|
};
|
||||||
|
}, [isAllProductsOpen]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-[72px] w-full flex-1 flex justify-center px-[120px] items-center gap-8">
|
<div ref={containerRef} className="relative h-[72px] w-full flex-1 px-[120px]">
|
||||||
<div className="flex gap-2 items-center">
|
<div className="flex h-full items-center justify-center gap-8">
|
||||||
<HamburgerMenu size={24} color="black" />
|
<button
|
||||||
<div className="font-bold">همه محصولات</div>
|
type="button"
|
||||||
|
className={cn("flex items-center gap-2 font-bold transition-colors", isAllProductsOpen && "text-primary")}
|
||||||
|
onClick={() => setIsAllProductsOpen((open) => !open)}
|
||||||
|
aria-expanded={isAllProductsOpen}
|
||||||
|
aria-haspopup="true"
|
||||||
|
>
|
||||||
|
<HamburgerMenu size={24} color="currentColor" />
|
||||||
|
<span>همه محصولات</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{menuItems.map((item) => (
|
||||||
|
<div key={item} className="font-bold">
|
||||||
|
{item}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="font-bold">کارت ویزیت</div>
|
{isAllProductsOpen && <AllProductsMenu />}
|
||||||
<div className="font-bold">کاتالوگ</div>
|
|
||||||
<div className="font-bold">بروشور</div>
|
|
||||||
<div className="font-bold">کارت تبریک</div>
|
|
||||||
<div className="font-bold">جعبه</div>
|
|
||||||
<div className="font-bold">ساک دستی</div>
|
|
||||||
<div className="font-bold">هدایای تبلیغاتی</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 48 KiB |
Reference in New Issue
Block a user