change main navbar

This commit is contained in:
Shahed Nasser
2025-03-10 17:19:23 +02:00
parent 0c71bce1e2
commit 0ba63ac29e
17 changed files with 260 additions and 152 deletions
@@ -5,6 +5,7 @@ import clsx from "clsx"
import React, { useRef, useState } from "react"
import { NavigationItemDropdown } from "types"
import { Menu } from "../../../.."
import { MainNavItemLink } from "../Link"
type MainNavItemDropdownProps = {
item: NavigationItemDropdown
@@ -22,13 +23,26 @@ export const MainNavItemDropdown = ({
const [isOpen, setIsOpen] = useState(false)
const ref = useRef<HTMLDivElement>(null)
return (
<div
className={clsx("relative", wrapperClassName)}
ref={ref}
onMouseOver={() => setIsOpen(true)}
onMouseLeave={() => setIsOpen(false)}
>
const getItemContent = () => {
if (item.link) {
return (
<MainNavItemLink
item={{
...item,
link: item.link!,
type: "link",
}}
isActive={isActive}
icon={
<TriangleDownMini
className={clsx("transition-transform", isOpen && "rotate-180")}
/>
}
/>
)
}
return (
<div
className={clsx(
"cursor-pointer flex gap-docs_0.25 items-center",
@@ -46,6 +60,17 @@ export const MainNavItemDropdown = ({
className={clsx("transition-transform", isOpen && "rotate-180")}
/>
</div>
)
}
return (
<div
className={clsx("relative", wrapperClassName)}
ref={ref}
onMouseOver={() => setIsOpen(true)}
onMouseLeave={() => setIsOpen(false)}
>
{getItemContent()}
<div className="absolute top-full -left-docs_0.75 pt-docs_0.25">
<Menu
className={clsx("min-w-[190px]", !isOpen && "hidden")}
@@ -8,18 +8,24 @@ import clsx from "clsx"
type MainNavItemLinkProps = {
item: NavigationItemLink
isActive: boolean
icon?: React.ReactNode
}
export const MainNavItemLink = ({ item, isActive }: MainNavItemLinkProps) => {
export const MainNavItemLink = ({
item,
isActive,
icon,
}: MainNavItemLinkProps) => {
return (
<LinkButton
href={item.path}
href={item.link}
className={clsx(
isActive && "text-medusa-fg-base",
!isActive && "text-medusa-fg-muted hover:text-medusa-fg-subtle"
)}
>
{item.title}
{icon}
</LinkButton>
)
}
@@ -8,11 +8,11 @@ import clsx from "clsx"
import { SelectedMenu } from ".."
type MainNavMobileMainMenu = {
setSelectedMenu: (menu: SelectedMenu) => void
setSelectedMenus: React.Dispatch<React.SetStateAction<SelectedMenu>>
}
export const MainNavMobileMainMenu = ({
setSelectedMenu,
setSelectedMenus: setSelectedMenu,
}: MainNavMobileMainMenu) => {
const { navItems } = useMainNav()
@@ -34,14 +34,17 @@ export const MainNavMobileMainMenu = ({
return
}
setSelectedMenu({
title: item.title,
menu: item.children,
})
setSelectedMenu((prev) => [
...prev,
{
title: item.title,
menu: item.children,
},
])
}}
>
{item.type === "link" && (
<Link href={item.path} className="block w-full">
<Link href={item.link} className="block w-full">
{item.title}
</Link>
)}
@@ -3,19 +3,25 @@
import clsx from "clsx"
import Link from "next/link"
import React, { useMemo } from "react"
import { MenuItem, MenuItemLink } from "types"
import { MenuItem, MenuItemLink, MenuItemSubMenu } from "types"
import { SelectedMenu } from ".."
import { TriangleRightMini } from "@medusajs/icons"
type MainNavMobileSubMenuProps = {
menu: MenuItem[]
title: string
setSelectedMenus: React.Dispatch<React.SetStateAction<SelectedMenu>>
}
export const MainNavMobileSubMenu = ({
menu,
title,
setSelectedMenus,
}: MainNavMobileSubMenuProps) => {
const filteredItems: MenuItemLink[] = useMemo(() => {
return menu.filter((item) => item.type === "link") as MenuItemLink[]
const filteredItems: (MenuItemLink | MenuItemSubMenu)[] = useMemo(() => {
return menu.filter(
(item) => item.type === "link" || item.type === "sub-menu"
) as (MenuItemLink | MenuItemSubMenu)[]
}, [menu])
return (
<div className="flex flex-col gap-[23px]">
@@ -31,9 +37,28 @@ export const MainNavMobileSubMenu = ({
"flex justify-between gap-docs_1"
)}
>
<Link href={item.link} className="block w-full">
{item.title}
</Link>
{item.type === "link" && (
<Link href={item.link} className="block w-full">
{item.title}
</Link>
)}
{item.type === "sub-menu" && (
<div
className="w-full flex justify-between gap-docs_1"
onClick={() =>
setSelectedMenus((prev) => [
...prev,
{
title: item.title,
menu: item.items,
},
])
}
>
<span>{item.title}</span>
<TriangleRightMini />
</div>
)}
</li>
))}
</ul>
@@ -13,11 +13,11 @@ import { MainNavMobileSubMenu } from "./SubMenu"
export type SelectedMenu = {
title: string
menu: MenuItem[]
}
}[]
export const MainNavMobileMenu = () => {
const [isOpen, setIsOpen] = useState(false)
const [selectedMenu, setSelectedMenu] = useState<SelectedMenu>()
const [selectedMenus, setSelectedMenus] = useState<SelectedMenu>([])
const ref = useRef(null)
return (
@@ -40,7 +40,11 @@ export const MainNavMobileMenu = () => {
>
<SwitchTransition>
<CSSTransition
key={!selectedMenu ? "main" : "sub"}
key={
!selectedMenus.length
? "main"
: selectedMenus[selectedMenus.length - 1].title
}
classNames={{
enter: "animate-fadeInLeft animate-fast",
exit: "animate-fadeOutRight animate-fast",
@@ -49,10 +53,10 @@ export const MainNavMobileMenu = () => {
timeout={250}
>
<div ref={ref} className="w-full px-docs_1.5">
{!selectedMenu && (
<MainNavMobileMainMenu setSelectedMenu={setSelectedMenu} />
{selectedMenus.length === 0 && (
<MainNavMobileMainMenu setSelectedMenus={setSelectedMenus} />
)}
{selectedMenu && (
{selectedMenus.length > 0 && (
<>
<div
className={clsx(
@@ -61,12 +65,21 @@ export const MainNavMobileMenu = () => {
"cursor-pointer"
)}
tabIndex={-1}
onClick={() => setSelectedMenu(undefined)}
onClick={() =>
setSelectedMenus((prev) => {
const temp = [...prev]
temp.pop()
return temp
})
}
>
<ArrowUturnLeft />
<span className="text-h1">Back</span>
</div>
<MainNavMobileSubMenu {...selectedMenu} />
<MainNavMobileSubMenu
{...selectedMenus[selectedMenus.length - 1]}
setSelectedMenus={setSelectedMenus}
/>
</>
)}
</div>