@atlaskit/portal
Version:
A wrapper for rendering components in React portals.
63 lines (62 loc) • 2.56 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import React, { Suspense, useState } from 'react';
import { createPortal } from 'react-dom';
import { ThemeProvider, useColorMode } from '@atlaskit/app-provider';
import { fg } from '@atlaskit/platform-feature-flags';
import { useIsomorphicLayoutEffect } from '../hooks/use-isomorphic-layout-effect';
import { createAtlaskitPortal, createPortalParent, removePortalParent } from '../utils/portal-dom-utils';
export default function InternalPortalNew(props) {
var zIndex = props.zIndex,
children = props.children,
isClosed = props.isClosed;
var _useState = useState(null),
_useState2 = _slicedToArray(_useState, 2),
atlaskitPortal = _useState2[0],
setAtlaskitPortal = _useState2[1];
var colorMode = useColorMode();
useIsomorphicLayoutEffect(function () {
if (fg('import_into_jsm_in_template_gallery_killswitch')) {
if (!isClosed) {
var tempPortalContainer = createAtlaskitPortal(zIndex);
setAtlaskitPortal(tempPortalContainer);
var portalParent = createPortalParent();
if (!tempPortalContainer || !portalParent) {
return;
}
portalParent.appendChild(tempPortalContainer);
return function () {
if (portalParent) {
portalParent.removeChild(tempPortalContainer);
!portalParent.hasChildNodes() && removePortalParent(portalParent);
}
setAtlaskitPortal(null);
};
}
} else {
var _tempPortalContainer = createAtlaskitPortal(zIndex);
setAtlaskitPortal(_tempPortalContainer);
var _portalParent = createPortalParent();
if (!_tempPortalContainer || !_portalParent) {
return;
}
_portalParent.appendChild(_tempPortalContainer);
return function () {
if (_tempPortalContainer) {
_portalParent.removeChild(_tempPortalContainer);
}
setAtlaskitPortal(null);
};
}
}, [zIndex, isClosed, fg]);
/**
* We wrap portal children with a Suspense boundary because in React 18 concurrent,
* if you suspend from _within_ a portal to a Suspense boundary _outside_ the portal,
* our portal gets in an infinite loop of rendering.
*/
var suspendedChildren = /*#__PURE__*/React.createElement(Suspense, {
fallback: null
}, colorMode ? /*#__PURE__*/React.createElement(ThemeProvider, {
defaultColorMode: colorMode
}, children) : children);
return atlaskitPortal ? /*#__PURE__*/createPortal(suspendedChildren, atlaskitPortal) : null;
}