Spaces:
Paused
Paused
File size: 1,372 Bytes
b152fd5 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | 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;
}
|