UNPKG

@ark-ui/solid

Version:

A collection of unstyled, accessible UI components for Solid, utilizing state machines for seamless interaction.

91 lines (86 loc) 2.98 kB
import { composeRefs } from "./PT2CJE3O.jsx"; import { EnvironmentProvider } from "./CGW54HAQ.jsx"; // src/components/frame/frame.tsx import { Show, createEffect as createEffect2, createMemo, createSignal, onCleanup as onCleanup2, splitProps } from "solid-js"; import { Portal } from "solid-js/web"; // src/components/frame/frame-content.tsx import { createEffect, onCleanup } from "solid-js"; var FrameContent = (props) => { const { onMount, onUnmount, children } = props; createEffect(() => { onMount?.(); onCleanup(() => { onUnmount?.(); }); }); return children; }; // src/components/frame/frame.tsx var resetStyle = "<style>*,*::before,*::after { margin: 0; padding: 0; box-sizing: border-box; }</style>"; var initialSrcDoc = `<html><head>${resetStyle}</head><body><div class="frame-root"></div></body></html>`; function getMountNode(frame) { const doc = frame.contentWindow?.document; if (!doc) return null; return doc.body.querySelector(".frame-root") || doc.body; } var Frame = (props) => { const [frameProps, localProps] = splitProps(props, ["children", "head", "onMount", "onUnmount", "srcdoc"]); const srcdoc = createMemo(() => frameProps.srcdoc ?? initialSrcDoc); const [frameRef, setFrameRef] = createSignal(null); const [mountNode, setMountNode] = createSignal(null); createEffect2(() => { const frame = frameRef(); if (!frame) return; const doc = frame.contentWindow?.document; if (!doc) return; doc.open(); doc.write(srcdoc()); doc.close(); setMountNode(getMountNode(frame)); }); createEffect2(() => { const frame = frameRef(); if (!frame || !frame.contentDocument) return; const win = frame.contentWindow; if (!win) return; const node = getMountNode(frame); if (!node) return; const exec = () => { win.requestAnimationFrame(() => { const rootEl = frame.contentDocument?.documentElement; if (!rootEl) return; frame.style.setProperty("--width", `${node.scrollWidth}px`); frame.style.setProperty("--height", `${node.scrollHeight}px`); }); }; const resizeObserver = new win.ResizeObserver(exec); exec(); if (frame.contentDocument) { resizeObserver.observe(node); } onCleanup2(() => { resizeObserver.disconnect(); }); }); return <EnvironmentProvider value={() => frameRef()?.contentDocument ?? document}> <iframe {...localProps} ref={composeRefs(setFrameRef, localProps.ref)}> <Show when={mountNode()}> {(node) => <Portal mount={node()}> <FrameContent onMount={frameProps.onMount} onUnmount={frameProps.onUnmount}> {frameProps.children} </FrameContent> </Portal>} </Show> <Show when={mountNode()}> <Portal mount={frameRef().contentDocument.head}>{frameProps.head}</Portal> </Show> </iframe> </EnvironmentProvider>; }; export { Frame };