From acf17015cb00c91b7dff501483cbae936f5c15f6 Mon Sep 17 00:00:00 2001 From: Hugo Lextrait Date: Wed, 2 Apr 2025 16:49:17 +0200 Subject: [PATCH 1/2] feat: implement responsive submenu for better mobile navigation --- src/components/extenders/Menu.tsx | 119 ++++++++++++++++++++++++++---- 1 file changed, 105 insertions(+), 14 deletions(-) diff --git a/src/components/extenders/Menu.tsx b/src/components/extenders/Menu.tsx index c6c44f892..c287cf9e0 100644 --- a/src/components/extenders/Menu.tsx +++ b/src/components/extenders/Menu.tsx @@ -1,14 +1,17 @@ import * as DropdownMenu from "@radix-ui/react-dropdown-menu"; import type { ReactNode } from "react"; -import { useMemo } from "react"; +import { useMemo, useState } from "react"; import { Fragment } from "react"; import { useTheme } from "../../context/Theme.context"; import { mergeClass } from "../../utils/css"; import type { Component, GetSet } from "../../utils/types"; import Box, { type BoxProps } from "../primitives/Box"; +import Collapsible from "../primitives/Collapsible"; import Divider from "../primitives/Divider"; import EventBlocker from "../primitives/EventBlocker"; import Icon from "../primitives/Icon"; +import Space from "../primitives/Space"; +import Text from "../primitives/Text"; import Group from "./Group"; export interface MenuOptions { @@ -29,6 +32,45 @@ const divide = (element: JSX.Element, index: number, arr: JSX.Element[]) => ( ); +export function SubMenuResponsiv({ children, options, size, look, className }: Component) { + const [isOpen, setIsOpen] = useState(false); + + return ( + + + setIsOpen(prev => !prev)}> + { + + {children} + + + } + + + + + {Object.entries(options).map(([key, { label, options: subOptions }]) => { + if (subOptions && Object.keys(subOptions).length > 0) + return ( + + {label} + + ); + return ( + + + {label} + + + ); + })} + + + + + ); +} + export function SubMenu({ children, options, size, look, className }: Component) { const { vars } = useTheme(); @@ -36,7 +78,7 @@ export function SubMenu({ children, options, size, look, className }: Component< - {children} + {children} @@ -74,7 +116,7 @@ export default function Menu({ }: Component) { const { vars } = useTheme(); - const menu = useMemo(() => { + const menuDesktop = useMemo(() => { return Object.entries(options) .map(([key, { label, options: subOptions }]) => { if (subOptions && Object.keys(subOptions).length > 0) @@ -88,22 +130,71 @@ export default function Menu({ .map(divide); }, [options, size, look, className]); + const menuResponsiv = useMemo(() => { + return Object.entries(options) + .map(([key, { label, options: subOptions }]) => { + if (subOptions && Object.keys(subOptions).length > 0) + return ( + + {label} + + ); + return {label}; + }) + .map(divide); + }, [options, size, look, className]); + + // biome-ignore lint/correctness/useExhaustiveDependencies: + const desktopMenu = useMemo(() => { + return ( + + + + {menuDesktop} + + + + ); + }, [options, size, look, className, vars, menuDesktop]); + + // biome-ignore lint/correctness/useExhaustiveDependencies: + const responsivMenu = useMemo(() => { + return ( + + + + {menuResponsiv} + + + + ); + }, [options, size, look, className, vars, menuDesktop]); + return ( {children} - - - - {menu} - - - + { + <> + {desktopMenu} + {responsivMenu} + + } ); From 27db558acbff2c740803ef272aab796220c2502b Mon Sep 17 00:00:00 2001 From: Hugo Lextrait Date: Wed, 2 Apr 2025 16:52:12 +0200 Subject: [PATCH 2/2] refactor: rename menu variables for clarity and consistency --- src/components/extenders/Menu.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/extenders/Menu.tsx b/src/components/extenders/Menu.tsx index c287cf9e0..bf34a9603 100644 --- a/src/components/extenders/Menu.tsx +++ b/src/components/extenders/Menu.tsx @@ -116,7 +116,7 @@ export default function Menu({ }: Component) { const { vars } = useTheme(); - const menuDesktop = useMemo(() => { + const desktopMenuItems = useMemo(() => { return Object.entries(options) .map(([key, { label, options: subOptions }]) => { if (subOptions && Object.keys(subOptions).length > 0) @@ -130,7 +130,7 @@ export default function Menu({ .map(divide); }, [options, size, look, className]); - const menuResponsiv = useMemo(() => { + const responsiveMenuItems = useMemo(() => { return Object.entries(options) .map(([key, { label, options: subOptions }]) => { if (subOptions && Object.keys(subOptions).length > 0) @@ -157,12 +157,12 @@ export default function Menu({ look={look || "soft"} className={mergeClass("animate-drop text-main-12 bg-main-2 min-w-[24ch] m-lg", className)} {...props}> - {menuDesktop} + {desktopMenuItems} ); - }, [options, size, look, className, vars, menuDesktop]); + }, [options, size, look, className, vars, desktopMenuItems]); // biome-ignore lint/correctness/useExhaustiveDependencies: const responsivMenu = useMemo(() => { @@ -177,12 +177,12 @@ export default function Menu({ look={look || "soft"} className={mergeClass("animate-drop text-main-12 bg-main-2 min-w-[100vw] min-h-[92vh] !rounded-0")} {...props}> - {menuResponsiv} + {responsiveMenuItems} ); - }, [options, size, look, className, vars, menuDesktop]); + }, [options, size, look, className, vars, desktopMenuItems]); return (