| 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 { |
| |
| } |
| } |
|
|
| 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; |
| } |
|
|