Spaces:
Paused
Paused
| import { createContext, useCallback, useContext, useState, useEffect, type ReactNode } from "react"; | |
| interface SidebarContextValue { | |
| sidebarOpen: boolean; | |
| setSidebarOpen: (open: boolean) => void; | |
| toggleSidebar: () => void; | |
| isMobile: boolean; | |
| } | |
| const SidebarContext = createContext<SidebarContextValue | null>(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); | |
| 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); | |
| }, []); | |
| const toggleSidebar = useCallback(() => setSidebarOpen((v) => !v), []); | |
| return ( | |
| <SidebarContext.Provider value={{ sidebarOpen, setSidebarOpen, toggleSidebar, isMobile }}> | |
| {children} | |
| </SidebarContext.Provider> | |
| ); | |
| } | |
| export function useSidebar() { | |
| const ctx = useContext(SidebarContext); | |
| if (!ctx) { | |
| throw new Error("useSidebar must be used within SidebarProvider"); | |
| } | |
| return ctx; | |
| } | |