From d018c6826f4a429875a7ac31ce92c7d0c80c7f32 Mon Sep 17 00:00:00 2001 From: Iqbal Date: Wed, 28 Oct 2026 13:55:27 +0700 Subject: [PATCH] Collapse sidebar nav groups into dropdowns that open on the active page Each group label (Dashboard, Settings) toggles its items; a group starts closed unless it holds the current route, and a manual toggle resets on the next navigation. Mobile keeps every item visible. Co-Authored-By: Claude Opus 5.5 --- src/components/AppLayout.tsx | 27 +++++++++++++++++++-------- src/components/Icon.tsx | 1 + src/styles/theme.css | 13 +++++++++---- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/components/AppLayout.tsx b/src/components/AppLayout.tsx index 8d5f036..2622b38 100644 --- a/src/components/AppLayout.tsx +++ b/src/components/AppLayout.tsx @@ -135,6 +135,9 @@ export function AppLayout() { const { signOut } = useClerk() const { pathname } = useLocation() const current = NAV.find(n => pathname.startsWith(n.to)) + // Nav groups stay closed unless they hold the current page; a click on the label overrides that until the next route. + const [toggled, setToggled] = useState>>({}) + useEffect(() => setToggled({}), [pathname]) const name = user?.fullName || user?.primaryEmailAddress?.emailAddress || '-' return ( @@ -143,14 +146,22 @@ export function AppLayout() {
diff --git a/src/components/Icon.tsx b/src/components/Icon.tsx index 837e1de..04d79d0 100644 --- a/src/components/Icon.tsx +++ b/src/components/Icon.tsx @@ -17,6 +17,7 @@ const paths: Record = { search: '', info: '', check: '', + 'chevron-down': '', 'chevron-updown': '', logout:'', plus: '', diff --git a/src/styles/theme.css b/src/styles/theme.css index 2a35a04..f6ff264 100644 --- a/src/styles/theme.css +++ b/src/styles/theme.css @@ -287,10 +287,15 @@ dialog::backdrop{background:rgba(16,24,40,.45);backdrop-filter:blur(4px)} @keyframes page-in{from{opacity:0;transform:translateY(6px)}} @media (prefers-reduced-motion:reduce){.skel,.app main{animation:none}} -/* Sidebar groups: Dashboard, then Settings */ -.sidebar nav .nav-label{margin:0 12px 6px} -.sidebar nav .nav-label~.nav-label{margin-top:18px} -@media(max-width:700px){.sidebar nav .nav-label{display:none}} +/* Sidebar groups: Dashboard, then Settings, each a dropdown that opens on its active page */ +.sidebar nav button.nav-label{display:flex;align-items:center;justify-content:space-between;width:auto;margin:0 0 2px;padding:6px 12px;border-radius:8px;color:var(--muted);font-size:11px;font-weight:600;box-shadow:none;background:none} +.sidebar nav button.nav-label:hover{background:#f2f7ff;color:var(--ink)} +.sidebar nav button.nav-label svg{width:14px;height:14px;color:inherit;transition:transform .15s} +.sidebar nav button.nav-label[aria-expanded=false] svg{transform:rotate(-90deg)} +.sidebar nav .nav-items~.nav-label{margin-top:12px} +.nav-items{display:contents} +@media(min-width:701px){.nav-items.closed{display:none}} +@media(max-width:700px){.sidebar nav button.nav-label{display:none}} /* Production: the knowledge graph, then the metric row and the latest content */ .prod-metrics{grid-template-columns:repeat(3,minmax(0,1fr));margin-top:24px}