From 66846a4143244c9b8f445a8f3e3387bdfa0b1fb4 Mon Sep 17 00:00:00 2001 From: Hugo Lovighi Date: Mon, 15 Sep 2025 15:00:44 +0200 Subject: [PATCH] prevent sidebar state reset during Inertia prefetching --- app/Http/Middleware/HandleInertiaRequests.php | 1 - resources/js/components/ui/sidebar.tsx | 33 ++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/app/Http/Middleware/HandleInertiaRequests.php b/app/Http/Middleware/HandleInertiaRequests.php index bd8901335..c987856be 100644 --- a/app/Http/Middleware/HandleInertiaRequests.php +++ b/app/Http/Middleware/HandleInertiaRequests.php @@ -45,7 +45,6 @@ public function share(Request $request): array 'auth' => [ 'user' => $request->user(), ], - 'sidebarOpen' => ! $request->hasCookie('sidebar_state') || $request->cookie('sidebar_state') === 'true', ]; } } diff --git a/resources/js/components/ui/sidebar.tsx b/resources/js/components/ui/sidebar.tsx index ac6bd635f..d0c4e7d15 100644 --- a/resources/js/components/ui/sidebar.tsx +++ b/resources/js/components/ui/sidebar.tsx @@ -51,6 +51,14 @@ function useSidebar() { return context } +function getCookieValue(name: string): string | null { + if (typeof document === 'undefined') return null + const value = `; ${document.cookie}` + const parts = value.split(`; ${name}=`) + if (parts.length === 2) return parts.pop()?.split(';').shift() || null + return null +} + function SidebarProvider({ defaultOpen = true, open: openProp, @@ -67,9 +75,21 @@ function SidebarProvider({ const isMobile = useIsMobile() const [openMobile, setOpenMobile] = React.useState(false) + const [_open, _setOpen] = React.useState(() => { + if (defaultOpen !== undefined) return defaultOpen + + // Check cookie value on client-side initialization + const cookieValue = getCookieValue(SIDEBAR_COOKIE_NAME) + if (cookieValue !== null) { + return cookieValue === 'true' + } + + // Default to true if no cookie is found + return true + }) + // This is the internal state of the sidebar. // We use openProp and setOpenProp for control from outside the component. - const [_open, _setOpen] = React.useState(defaultOpen) const open = openProp ?? _open const setOpen = React.useCallback( (value: boolean | ((value: boolean) => boolean)) => { @@ -86,6 +106,17 @@ function SidebarProvider({ [setOpenProp, open] ) + // Sync with cookie changes (in case of external updates) + React.useEffect(() => { + const cookieValue = getCookieValue(SIDEBAR_COOKIE_NAME) + if (cookieValue !== null && openProp === undefined) { + const cookieOpen = cookieValue === 'true' + if (cookieOpen !== _open) { + _setOpen(cookieOpen) + } + } + }, [_open, openProp]) + // Helper to toggle the sidebar. const toggleSidebar = React.useCallback(() => { return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open)