import { createContext, useCallback, useContext, useEffect, useMemo, useState, type ReactNode, } from "react"; interface SidebarContextValue { // Mobile drawer + back-compat (existing behavior, unchanged). sidebarOpen: boolean; setSidebarOpen: (open: boolean) => void; toggleSidebar: () => void; isMobile: boolean; // Back-compat collapse API. The global navigation is permanently expanded; // these values remain for callers that have not removed old requests. collapsed: boolean; setCollapsed: (next: boolean) => void; toggleCollapsed: () => void; // Retained compatibility value; always false now that the rail is retired. collapseLocked: boolean; // Retained compatibility value; the retired rail can no longer peek. peeking: boolean; setPeeking: (next: boolean) => void; // Legacy requests remain observable without affecting the global nav. forceCollapsed: boolean; setForceCollapsed: (next: boolean) => void; // Route-requested collapse retained for integration compatibility. routeRequestsCollapsed: boolean; setRouteRequestsCollapsed: (next: boolean) => void; } const SidebarContext = createContext(null); const MOBILE_BREAKPOINT = 768; export function SidebarProvider({ children }: { children: ReactNode }) { const [isMobile, setIsMobile] = useState(() => window.innerWidth < MOBILE_BREAKPOINT); const [sidebarOpen, setSidebarOpen] = useState(() => window.innerWidth >= MOBILE_BREAKPOINT); const [routeRequestsCollapsed, setRouteRequestsCollapsed] = useState(false); const [forceCollapsed, setForceCollapsed] = useState(false); useEffect(() => { const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`); const onChange = (e: MediaQueryListEvent) => { setIsMobile(e.matches); setSidebarOpen(!e.matches); }; mql.addEventListener("change", onChange); return () => mql.removeEventListener("change", onChange); }, []); // The icon rail has been retired. Keep the old API inert so routes and // plugins compiled against it cannot collapse the global navigation. const collapsed = false; const collapseLocked = false; const peeking = false; const setCollapsed = useCallback((_next: boolean) => {}, []); const toggleCollapsed = useCallback(() => {}, []); const setPeeking = useCallback((_next: boolean) => {}, []); const toggleSidebar = useCallback(() => setSidebarOpen((v) => !v), []); const value = useMemo( () => ({ sidebarOpen, setSidebarOpen, toggleSidebar, isMobile, collapsed, setCollapsed, toggleCollapsed, collapseLocked, peeking, setPeeking, forceCollapsed, setForceCollapsed, routeRequestsCollapsed, setRouteRequestsCollapsed, }), [ sidebarOpen, setSidebarOpen, toggleSidebar, isMobile, collapsed, setCollapsed, toggleCollapsed, collapseLocked, peeking, setPeeking, forceCollapsed, setForceCollapsed, routeRequestsCollapsed, setRouteRequestsCollapsed, ], ); return {children}; } export function useSidebar() { const ctx = useContext(SidebarContext); if (!ctx) { throw new Error("useSidebar must be used within SidebarProvider"); } return ctx; }