fix(ui): keep mobile sidebar open when switching sections

Tapping Management/Settings/Account in the sidebar footer navigated to
that section's default page, which triggered the same effect that
closes the sidebar after picking a leaf page on mobile — so the
sidebar snapped shut right after switching sections, forcing users to
reopen it just to browse the new section's pages.

Have handleSectionClick flag the navigation as section-only via a ref;
the mobile auto-close effect consumes that flag and skips closing for
that one navigation, leaving normal leaf-page navigation unaffected.

Verified on a mobile viewport: switching sections now keeps the
sidebar open, while picking a specific page still closes it as before.
This commit is contained in:
Steven RYDELL
2026-08-01 19:07:22 +02:00
parent 18264a5b76
commit 7fab3540ea
+13 -1
View File
@@ -334,6 +334,11 @@ export function Sidebar() {
const hasPermission = useAccountStore((s) => s.hasPermission); const hasPermission = useAccountStore((s) => s.hasPermission);
const [upsellOpen, setUpsellOpen] = useState(false); const [upsellOpen, setUpsellOpen] = useState(false);
const navRef = useRef<HTMLElement>(null); const navRef = useRef<HTMLElement>(null);
// Set by handleSectionClick right before navigating: switching sections
// from the footer should keep the sidebar open so the new section's pages
// are still browsable, instead of closing right back up like a leaf-page
// navigation would.
const skipCloseOnNavigateRef = useRef(false);
// Build the permission checks from the permissions array itself: the store // Build the permission checks from the permissions array itself: the store
// accessors are stable refs, so depending on them alone would keep a stale // accessors are stable refs, so depending on them alone would keep a stale
@@ -346,6 +351,10 @@ export function Sidebar() {
useEffect(() => { useEffect(() => {
if (typeof window === 'undefined') return; if (typeof window === 'undefined') return;
if (skipCloseOnNavigateRef.current) {
skipCloseOnNavigateRef.current = false;
return;
}
if (window.matchMedia('(max-width: 767px)').matches) { if (window.matchMedia('(max-width: 767px)').matches) {
setSidebarOpen(false); setSidebarOpen(false);
} }
@@ -371,7 +380,10 @@ export function Sidebar() {
last ?? last ??
findFirstAccessibleLinkInLayout(schema, target, edition, canGet, hasPermission) ?? findFirstAccessibleLinkInLayout(schema, target, edition, canGet, hasPermission) ??
findFirstVisibleLinkInLayout(schema, target, edition, canGet, hasPermission); findFirstVisibleLinkInLayout(schema, target, edition, canGet, hasPermission);
if (first) navigate(`/${target.name}/${first}`); if (first) {
skipCloseOnNavigateRef.current = true;
navigate(`/${target.name}/${first}`);
}
}; };
return ( return (