UNPKG

@clayui/shared

Version:
57 lines (56 loc) 1.74 kB
import { useProvider } from "@clayui/provider"; import classNames from "classnames"; import React from "react"; import { createPortal } from "react-dom"; const ClayPortalContext = React.createContext(null); ClayPortalContext.displayName = "ClayPortalContext"; function createDivElement(className, id) { const element = document.createElement("div"); if (className) { element.setAttribute("class", className); } if (id) { element.setAttribute("id", id); } return element; } function ClayPortal({ children, className, containerRef, id, subPortalRef }) { const { theme } = useProvider(); const parentPortalRef = React.useContext(ClayPortalContext); const portalRef = React.useRef( typeof document !== "undefined" ? createDivElement(classNames(theme, className), id) : null ); React.useEffect(() => { const closestParent = parentPortalRef && parentPortalRef.current ? parentPortalRef.current : document.body; const elToMountTo = containerRef && containerRef.current ? containerRef.current : closestParent; if (elToMountTo && portalRef.current) { elToMountTo.appendChild(portalRef.current); } return () => { if (portalRef.current) { if (typeof portalRef.current.remove === "function") { portalRef.current.remove(); } else if (elToMountTo) { elToMountTo.removeChild(portalRef.current); } } }; }, [containerRef, parentPortalRef]); const content = /* @__PURE__ */ React.createElement( ClayPortalContext.Provider, { value: subPortalRef ? subPortalRef : portalRef }, children ); return portalRef.current ? createPortal(content, portalRef.current) : content; } export { ClayPortal };