UNPKG

@coin-voyage/paykit

Version:

Seamless crypto payments. Onboard users from any chain, any coin into your app with one click.

35 lines (34 loc) 1.47 kB
import { useLayoutEffect, useState } from "react"; import { createPortal } from "react-dom"; import { paykitVersion } from "../../../utils/version"; const Portal = ({ selector = "__COIN_VOYAGE__", children }) => { const [portalTarget, setPortalTarget] = useState(null); // useLayoutEffect is used here to synchronously set up the portal target // before the component renders. This is the standard pattern for portals. useLayoutEffect(() => { let divCreated = false; const selectorPrefixed = `#${selector.replace(/^#/, "")}`; let element = document.querySelector(selectorPrefixed); if (!element) { const div = document.createElement("div"); div.setAttribute("id", selector); div.setAttribute("data-pay", paykitVersion); document.body.appendChild(div); element = div; divCreated = true; } // Setting state here is intentional - we need to trigger a re-render // after the DOM element is available for the portal to render into // eslint-disable-next-line react-hooks/set-state-in-effect setPortalTarget(element); return () => { if (divCreated && element?.parentNode) { element.parentNode.removeChild(element); } }; }, [selector]); if (!portalTarget) return null; return createPortal(children, portalTarget); }; export default Portal;