From f5524eb45ac6ce9de2a7dfeb3273760f67d594d2 Mon Sep 17 00:00:00 2001 From: Steven RYDELL Date: Sat, 1 Aug 2026 23:07:48 +0200 Subject: [PATCH] fix(ui): close sidebar group when picking a link outside it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plain links (not wrapped in a collapsible) are siblings of collapsible groups within the same AccordionLevel, but their onClick never touched that level's openId — so a group left expanded stayed expanded even after navigating to an unrelated top-level page, or to a sibling link outside any group. Both SidebarTopItem and SidebarSubItem's link branches now read the AccordionLevelContext they're rendered in and call setOpenId(null) before navigating. For a link inside its own group, this is immediately overridden by AccordionCollapsible's existing containsActive effect (which reopens the branch that now contains the active page), so nested navigation is unaffected — only a truly unrelated group gets collapsed. Verified: opening Directory (showing Groups), then clicking Cluster (a plain top-level link) now collapses Directory instead of leaving it expanded. --- src/components/layout/Sidebar.tsx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/components/layout/Sidebar.tsx b/src/components/layout/Sidebar.tsx index 73493f1..741fa1f 100644 --- a/src/components/layout/Sidebar.tsx +++ b/src/components/layout/Sidebar.tsx @@ -159,6 +159,11 @@ interface SidebarSubItemProps { } function SidebarSubItem({ item, depth, sectionName, currentPath, navigate, edition, onUpsell }: SidebarSubItemProps) { + // Picking a plain link closes any sibling group left open at this same + // accordion level — it's not part of a collapsible, so nothing should + // stay expanded on its account once it's the one that's active. + const level = useContext(AccordionLevelContext); + if (item.type === 'link') { if (!checkLinkVisible(item.viewName)) return null; @@ -185,6 +190,7 @@ function SidebarSubItem({ item, depth, sectionName, currentPath, navigate, editi if (isLocked) { onUpsell(); } else { + level?.setOpenId(null); setLastVisitedSection(sectionName, item.viewName); navigate(path); } @@ -245,6 +251,11 @@ interface SidebarTopItemProps { } function SidebarTopItem({ item, sectionName, currentPath, navigate, edition, onUpsell }: SidebarTopItemProps) { + // Picking a plain link closes any sibling group left open at this same + // accordion level — it's not part of a collapsible, so nothing should + // stay expanded on its account once it's the one that's active. + const level = useContext(AccordionLevelContext); + if ('link' in item) { const { name, icon, viewName } = item.link; @@ -271,6 +282,7 @@ function SidebarTopItem({ item, sectionName, currentPath, navigate, edition, onU if (isLocked) { onUpsell(); } else { + level?.setOpenId(null); setLastVisitedSection(sectionName, viewName); navigate(path); }