Spaces:
Paused
Paused
File size: 1,880 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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | import { createContext, useCallback, useContext, useState, type ReactNode } from "react";
const STORAGE_KEY = "paperclip:panel-visible";
interface PanelContextValue {
panelContent: ReactNode | null;
panelVisible: boolean;
openPanel: (content: ReactNode) => void;
closePanel: () => void;
setPanelVisible: (visible: boolean) => void;
togglePanelVisible: () => void;
}
const PanelContext = createContext<PanelContextValue | null>(null);
function readPreference(): boolean {
try {
const raw = localStorage.getItem(STORAGE_KEY);
return raw === null ? true : raw === "true";
} catch {
return true;
}
}
function writePreference(visible: boolean) {
try {
localStorage.setItem(STORAGE_KEY, String(visible));
} catch {
// Ignore storage failures.
}
}
export function PanelProvider({ children }: { children: ReactNode }) {
const [panelContent, setPanelContent] = useState<ReactNode | null>(null);
const [panelVisible, setPanelVisibleState] = useState(readPreference);
const openPanel = useCallback((content: ReactNode) => {
setPanelContent(content);
}, []);
const closePanel = useCallback(() => {
setPanelContent(null);
}, []);
const setPanelVisible = useCallback((visible: boolean) => {
setPanelVisibleState(visible);
writePreference(visible);
}, []);
const togglePanelVisible = useCallback(() => {
setPanelVisibleState((prev) => {
const next = !prev;
writePreference(next);
return next;
});
}, []);
return (
<PanelContext.Provider
value={{ panelContent, panelVisible, openPanel, closePanel, setPanelVisible, togglePanelVisible }}
>
{children}
</PanelContext.Provider>
);
}
export function usePanel() {
const ctx = useContext(PanelContext);
if (!ctx) {
throw new Error("usePanel must be used within PanelProvider");
}
return ctx;
}
|