Initial commit
This commit is contained in:
commit
bcca176137
88 files changed
+8725
No files matched your search
@@ -0,0 +1,106 @@
|
||||
"use client";
|
||||
|
||||
import type { FC, MouseEvent } from "react";
|
||||
import { useRef } from "react";
|
||||
import Link from "next/link";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { useHeightVar } from "@/hooks/useHeightVar";
|
||||
import { useIsDesktop } from "@/hooks/useIsDesktop";
|
||||
|
||||
import styles from "./NavbarSubMenu.module.css";
|
||||
|
||||
type SubMenuItem = {
|
||||
label: string;
|
||||
to: string;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
id: string;
|
||||
open: boolean;
|
||||
noTransition: boolean;
|
||||
instantSwitch: boolean;
|
||||
setOpenSubmenuId: (id: string | null) => void;
|
||||
closeInstantNoAnim?: () => void;
|
||||
label: string;
|
||||
items: SubMenuItem[];
|
||||
};
|
||||
|
||||
export const NavbarSubMenu: FC<Props> = ({
|
||||
id,
|
||||
open,
|
||||
noTransition,
|
||||
instantSwitch,
|
||||
setOpenSubmenuId,
|
||||
closeInstantNoAnim,
|
||||
label,
|
||||
items,
|
||||
}) => {
|
||||
const pathname = usePathname();
|
||||
const subMenuRef = useRef<HTMLUListElement | null>(null);
|
||||
const isDesktop = useIsDesktop();
|
||||
|
||||
const openMenu = () => setOpenSubmenuId(id);
|
||||
const closeMenu = () => setOpenSubmenuId(null);
|
||||
const toggleMenu = () => setOpenSubmenuId(open ? null : id);
|
||||
|
||||
useHeightVar(subMenuRef, "--submenu-h", "scroll", open);
|
||||
|
||||
const handleSubmenuClick = (e: MouseEvent<HTMLUListElement>) => {
|
||||
const target = e.target as HTMLElement;
|
||||
if (target.closest("a")) {
|
||||
closeInstantNoAnim?.();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<li
|
||||
className={styles["nav-item-with-sub"]}
|
||||
onMouseEnter={isDesktop ? openMenu : undefined}
|
||||
onMouseLeave={isDesktop ? closeMenu : undefined}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
className={styles["nav-sub-toggle"]}
|
||||
onClick={toggleMenu}
|
||||
aria-expanded={open}
|
||||
aria-controls={`submenu-${id}`}
|
||||
>
|
||||
{label}
|
||||
</button>
|
||||
|
||||
<ul
|
||||
ref={subMenuRef}
|
||||
id={`submenu-${id}`}
|
||||
className={[
|
||||
styles["nav-submenu"],
|
||||
open ? styles.open : "",
|
||||
noTransition || instantSwitch ? styles.noTransition : "",
|
||||
].join(" ")}
|
||||
onClick={handleSubmenuClick}
|
||||
>
|
||||
<li className={styles["nav-submenu-inner"]}>
|
||||
<ul className={styles["nav-submenu-list"]}>
|
||||
{items.map((item) => {
|
||||
const isActive =
|
||||
item.to === "/"
|
||||
? pathname === "/"
|
||||
: pathname === item.to || pathname.startsWith(`${item.to}/`);
|
||||
|
||||
return (
|
||||
<li key={item.to}>
|
||||
<Link
|
||||
href={item.to}
|
||||
aria-current={isActive ? "page" : undefined}
|
||||
onClick={closeInstantNoAnim}
|
||||
>
|
||||
{item.label}
|
||||
</Link>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
);
|
||||
};
|
||||
Reference in new issue
Block a user