58 lines
1.7 KiB
TypeScript
58 lines
1.7 KiB
TypeScript
|
|
import { createContext, useCallback, useContext, useRef, useState } from "react";
|
||
|
|
import type { ReactNode } from "react";
|
||
|
|
|
||
|
|
type LiftContextValue = {
|
||
|
|
liftedIds: Set<string>;
|
||
|
|
alwaysLiftedIds: Set<string>;
|
||
|
|
setLiftedIds: (ids: string[]) => void;
|
||
|
|
registerAlways: (id: string) => void;
|
||
|
|
unregisterAlways: (id: string) => void;
|
||
|
|
portalContainer: HTMLElement | null;
|
||
|
|
setPortalContainer: (el: HTMLElement | null) => void;
|
||
|
|
};
|
||
|
|
|
||
|
|
const LiftContext = createContext<LiftContextValue | null>(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<Set<string>>(new Set());
|
||
|
|
const [alwaysLiftedIds, setAlwaysLiftedIds] = useState<Set<string>>(new Set());
|
||
|
|
const [portalContainer, setPortalContainer] = useState<HTMLElement | null>(null);
|
||
|
|
const alwaysRef = useRef<Set<string>>(new Set());
|
||
|
|
|
||
|
|
const setLiftedIds = useCallback((ids: string[]) => {
|
||
|
|
setLiftedIdsRaw(new Set(ids));
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
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 (
|
||
|
|
<LiftContext
|
||
|
|
value={{
|
||
|
|
liftedIds,
|
||
|
|
alwaysLiftedIds,
|
||
|
|
setLiftedIds,
|
||
|
|
registerAlways,
|
||
|
|
unregisterAlways,
|
||
|
|
portalContainer,
|
||
|
|
setPortalContainer,
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
{children}
|
||
|
|
</LiftContext>
|
||
|
|
);
|
||
|
|
}
|