alinea
Version:
Headless git-based CMS
51 lines (49 loc) • 1.46 kB
JavaScript
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
};