UNPKG

@clayui/shared

Version:

ClayShared component

55 lines (54 loc) 1.88 kB
/** * SPDX-FileCopyrightText: © 2019 Liferay, Inc. <https://liferay.com> * SPDX-License-Identifier: BSD-3-Clause */ import { useProvider } from '@clayui/provider'; import classNames from 'classnames'; import React from 'react'; import { createPortal } from 'react-dom'; const ClayPortalContext = /*#__PURE__*/React.createContext(null); ClayPortalContext.displayName = 'ClayPortalContext'; const createDivElement = (className, id) => { const element = document.createElement('div'); if (className) { element.setAttribute('class', className); } if (id) { element.setAttribute('id', id); } return element; }; export const ClayPortal = _ref => { let { children, className, containerRef, id, subPortalRef } = _ref; 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 ? /*#__PURE__*/createPortal(content, portalRef.current) : content; };