diff --git a/src/shared/Navigation/NavigationItem.tsx b/src/shared/Navigation/NavigationItem.tsx new file mode 100644 index 0000000..da04757 --- /dev/null +++ b/src/shared/Navigation/NavigationItem.tsx @@ -0,0 +1,287 @@ +"use client"; + +import { PathName } from "@/routers/types"; +import { Popover, Transition } from "@headlessui/react"; +import { ChevronDownIcon } from "@heroicons/react/24/solid"; +import Image from "next/image"; +import Link from "next/link"; +import { usePathname } from "next/navigation"; +import React, { FC, Fragment, useEffect, useState } from "react"; + +// <--- NavItemType ---> +export interface MegamenuItem { + id: string; + image: string; + title: string; + items: NavItemType[]; +} +export interface NavItemType { + id: string; + name: string; + isNew?: boolean; + href: PathName; + targetBlank?: boolean; + children?: NavItemType[]; + megaMenu?: MegamenuItem[]; + type?: "dropdown" | "megaMenu" | "none"; +} + +export interface NavigationItemProps { + menuItem: NavItemType; +} + +type NavigationItemWithRouterProps = NavigationItemProps; + +const NavigationItem: FC = ({ menuItem }) => { + const [menuCurrentHovers, setMenuCurrentHovers] = useState([]); + + // CLOSE ALL MENU OPENING WHEN CHANGE HISTORY + const locationPathName = usePathname(); + useEffect(() => { + setMenuCurrentHovers([]); + }, [locationPathName]); + + const onMouseEnterMenu = (id: string) => { + setMenuCurrentHovers((state) => [...state, id]); + }; + + const onMouseLeaveMenu = (id: string) => { + setMenuCurrentHovers((state) => { + return state.filter((item, index) => { + return item !== id && index < state.indexOf(id); + }); + }); + }; + + // ===================== MENU MEGAMENU ===================== + const renderMegaMenu = (menu: NavItemType) => { + const isHover = menuCurrentHovers.includes(menu.id); + + const isFull = menu.megaMenu && menu.megaMenu?.length > 3; + const classPopover = isFull + ? "menu-megamenu--large" + : "menu-megamenu--small relative"; + const classPanel = isFull ? "left-0" : "-translate-x-1/2 left-1/2"; + + return ( + onMouseEnterMenu(menu.id)} + onMouseLeave={() => onMouseLeaveMenu(menu.id)} + > + {() => ( + <> +
{renderMainItem(menu)}
+ + +
+
+ {menu.megaMenu?.map((item) => ( +
+
+
+ +
+
+

+ {item.title} +

+
    + {item.items.map(renderMegaMenuNavlink)} +
+
+ ))} +
+
+
+
+ + )} +
+ ); + }; + + const renderMegaMenuNavlink = (item: NavItemType) => { + return ( +
  • + + {item.name} + +
  • + ); + }; + + // ===================== MENU DROPDOW ===================== + const renderDropdownMenu = (menuDropdown: NavItemType) => { + const isHover = menuCurrentHovers.includes(menuDropdown.id); + return ( + onMouseEnterMenu(menuDropdown.id)} + onMouseLeave={() => onMouseLeaveMenu(menuDropdown.id)} + > + {() => ( + <> +
    {renderMainItem(menuDropdown)}
    + + +
      + {menuDropdown.children?.map((i) => { + if (i.type) { + return renderDropdownMenuNavlinkHasChild(i); + } else { + return ( +
    • + {renderDropdownMenuNavlink(i)} +
    • + ); + } + })} +
    +
    +
    + + )} +
    + ); + }; + + const renderDropdownMenuNavlinkHasChild = (item: NavItemType) => { + const isHover = menuCurrentHovers.includes(item.id); + return ( + onMouseEnterMenu(item.id)} + onMouseLeave={() => onMouseLeaveMenu(item.id)} + > + {() => ( + <> +
    {renderDropdownMenuNavlink(item)}
    + + +
      + {item.children?.map((i) => { + if (i.type) { + return renderDropdownMenuNavlinkHasChild(i); + } else { + return ( +
    • + {renderDropdownMenuNavlink(i)} +
    • + ); + } + })} +
    +
    +
    + + )} +
    + ); + }; + + const renderDropdownMenuNavlink = (item: NavItemType) => { + return ( + + {item.name} + {item.type && ( +