From b1b632e28bee3fcb22b8208fac664725e1908c82 Mon Sep 17 00:00:00 2001 From: mlogclub Date: Sat, 30 May 2026 20:58:25 +0800 Subject: [PATCH] feat: implement dropdown menu in NavMain for collapsed state with hover functionality --- web/components/nav-main.test.mjs | 9 ++++++ web/components/nav-main.tsx | 53 ++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/web/components/nav-main.test.mjs b/web/components/nav-main.test.mjs index e8525d4..a36d9a8 100644 --- a/web/components/nav-main.test.mjs +++ b/web/components/nav-main.test.mjs @@ -9,3 +9,12 @@ test("dashboard nav items expose full labels when visual text is truncated", () assert.match(source, /tooltip=\{item\.title\}/) assert.match(source, /\{item\.title\}<\/span>/) }) + +test("collapsed dashboard nav sections expose submenu flyouts on hover", () => { + assert.match(source, /useSidebar/) + assert.match(source, /state === "collapsed" && !isMobile/) + assert.match(source, /\}/) + assert.match(source, /[\s\S]* }) { const pathname = usePathname() + const { isMobile, state } = useSidebar() const storageKey = getDashboardNavSectionStorageKey(sectionKey) const [open, setOpen] = useState(() => { if (typeof window === "undefined") { @@ -54,6 +64,49 @@ export function NavMain({ window.localStorage.setItem(storageKey, String(nextOpen)) } + if (state === "collapsed" && !isMobile) { + return ( + + + + + } + > + {icon} + {title} + + + + + {title} + + {items.map((item) => ( + } + className="cursor-pointer" + > + + {item.title} + + + ))} + + + + + + + ) + } + return (