UNPKG

alinea

Version:
51 lines (49 loc) 1.46 kB
import "../../chunks/chunk-NZLE2WMY.js"; // src/ui/util/Slots.tsx import { createContext, useContext, useLayoutEffect, useRef, useState } from "react"; import { createPortal } from "react-dom"; import { useForceUpdate } from "../hook/UseForceUpdate.js"; import { Fragment, jsx } from "react/jsx-runtime"; function createSlots() { const context = createContext(void 0); function Provider({ children }) { const [refs, setRefs] = useState([]); return /* @__PURE__ */ jsx(context.Provider, { value: [refs, setRefs], children }); } function useSlots() { const [refs, setRefs] = useContext(context); return { shown: refs.length > 0 }; } function useSlot() { const ref = useRef(null); const [refs, setRefs] = useContext(context); const redraw = useForceUpdate(); useLayoutEffect(() => { setRefs((refs2) => refs2.concat(ref)); return () => setRefs((refs2) => refs2.filter((r) => r !== ref)); }, []); useLayoutEffect(redraw, [refs]); return ref; } function Slot({ children }) { const ref = useSlot(); if (!ref.current) return null; return createPortal(children, ref.current); } function Portal(props) { const [refs] = useContext(context); return /* @__PURE__ */ jsx(Fragment, { children: refs.map((ref, i) => { return /* @__PURE__ */ jsx("div", { ref, ...props }, i); }) }); } return { Provider, Portal, Slot, useSlots }; } export { createSlots };