Organize/components/board/board-view-provider.tsx

46 lines
1.4 KiB
TypeScript

"use client";
import { createContext, useContext, useEffect, useState } from "react";
const STORAGE_KEY = "organize:board-view";
// A plain string union rather than an enum -- adding a future view is just
// one more literal here plus one more radio item in ViewSwitcher.
export type BoardView = "default" | "compact";
interface BoardViewContextValue {
view: BoardView;
setView: (view: BoardView) => void;
}
const BoardViewContext = createContext<BoardViewContextValue | null>(null);
export function BoardViewProvider({ children }: { children: React.ReactNode }) {
// Default to "default" on both server and first client render to avoid a
// hydration mismatch; the real persisted value is applied right after
// mount, trading a one-frame flash for zero hydration warnings.
const [view, setViewState] = useState<BoardView>("default");
useEffect(() => {
const stored = localStorage.getItem(STORAGE_KEY);
if (stored === "default" || stored === "compact") setViewState(stored);
}, []);
function setView(next: BoardView) {
setViewState(next);
localStorage.setItem(STORAGE_KEY, next);
}
return (
<BoardViewContext.Provider value={{ view, setView }}>
{children}
</BoardViewContext.Provider>
);
}
export function useBoardView() {
const ctx = useContext(BoardViewContext);
if (!ctx) throw new Error("useBoardView must be used within a BoardViewProvider");
return ctx;
}