import { createContext, createSignal, type Accessor, type JSX, untrack, useContext, } from "solid-js"; import { Portal } from "solid-js/web"; import { applyUiScale, markUiRoot, type UiScale } from "../ui"; import { createFullscreenController, type FullscreenController, } from "./viewport"; export type OverlayHost = { element: HTMLDivElement; fullscreen: FullscreenController; fullscreenPixelScale: Accessor; setUiScale: (scale: UiScale) => void; }; export function createOverlayHost( parent: HTMLElement, initialUiScale: UiScale, ): OverlayHost { const element = document.createElement("div"); element.dataset.ehpeekOverlayHost = "true"; parent.append(element); markUiRoot(element); let uiScale = initialUiScale; let fullscreenScale = 1; const [fullscreenPixelScale, setFullscreenPixelScale] = createSignal(1); const applyScale = () => applyUiScale(uiScale, element, fullscreenScale); const fullscreen = createFullscreenController(element, (factor) => { fullscreenScale = factor; setFullscreenPixelScale(factor); applyScale(); }); applyScale(); return { element, fullscreen, fullscreenPixelScale, setUiScale: (scale) => { uiScale = scale; applyScale(); }, }; } const OverlayHostContext = createContext(); export function OverlayHostProvider(props: { children: JSX.Element; host: OverlayHost; }) { const host = untrack(() => props.host); return ( {props.children} ); } export function OverlayPortal(props: { children: JSX.Element }) { const host = useOverlayHost(); return {props.children}; } export function useOverlayHost(): OverlayHost { const host = useContext(OverlayHostContext); if (!host) { throw new Error("OverlayHostProvider is required for overlay content."); } return host; }