import { createContext, useCallback, useContext, useRef, useState } from "react"; import type { ReactNode } from "react"; import { cloneWithoutAnimations } from "./Liftable"; type LiftContextValue = { liftedIds: Set; alwaysLiftedIds: Set; modalOpen: boolean; setLiftedIds: (ids: string[]) => void; registerAlways: (id: string) => void; unregisterAlways: (id: string) => void; registerModal: () => void; beginModalClose: () => void; endModalClose: () => void; portalContainer: HTMLElement | null; setPortalContainer: (el: HTMLElement | null) => void; setCloneContainer: (el: HTMLElement | null) => void; }; const LiftContext = createContext(null); export function useLift(): LiftContextValue { const ctx = useContext(LiftContext); if (!ctx) throw new Error("useLift must be used within LiftProvider"); return ctx; } export function LiftProvider({ children }: { children: ReactNode }) { const [liftedIds, setLiftedIdsRaw] = useState>(new Set()); const [alwaysLiftedIds, setAlwaysLiftedIds] = useState>(new Set()); const [modalOpen, setModalOpen] = useState(false); const [portalContainer, setPortalContainer] = useState(null); const alwaysRef = useRef>(new Set()); const modalCountRef = useRef(0); const cloneContainerRef = useRef(null); const setLiftedIds = useCallback((ids: string[]) => { setLiftedIdsRaw(new Set(ids)); }, []); const registerModal = useCallback(() => { modalCountRef.current++; setModalOpen(true); }, []); const beginModalClose = useCallback(() => { if (portalContainer && cloneContainerRef.current) { cloneWithoutAnimations(portalContainer, cloneContainerRef.current); } modalCountRef.current--; if (modalCountRef.current === 0) { setModalOpen(false); } }, [portalContainer]); const endModalClose = useCallback(() => { if (cloneContainerRef.current) { cloneContainerRef.current.innerHTML = ""; } }, []); const setCloneContainer = useCallback((el: HTMLElement | null) => { cloneContainerRef.current = el; }, []); const registerAlways = useCallback((id: string) => { alwaysRef.current.add(id); setAlwaysLiftedIds(new Set(alwaysRef.current)); }, []); const unregisterAlways = useCallback((id: string) => { alwaysRef.current.delete(id); setAlwaysLiftedIds(new Set(alwaysRef.current)); }, []); return ( {children} ); }