@atlaskit/portal
Version:
A wrapper for rendering components in React portals.
31 lines (30 loc) • 1.41 kB
JavaScript
import React, { useEffect, useMemo } from 'react';
import { createPortal } from 'react-dom';
import { ThemeProvider } from '@atlaskit/app-provider/theme-provider';
import { useColorMode } from '@atlaskit/app-provider/use-color-mode';
import { useIsInsideThemeProvider } from '@atlaskit/app-provider/use-is-inside-theme-provider';
import { appendPortalContainerIfNotAppended } from '../utils/append-portal-container-if-not-appended';
import { createContainer } from '../utils/create-container';
import { removePortalContainer } from '../utils/remove-portal-container';
export default function InternalPortal(props) {
const {
zIndex,
children
} = props;
const container = useMemo(() => createContainer(zIndex), [zIndex]);
const colorMode = useColorMode();
const isInsideThemeProvider = useIsInsideThemeProvider();
// This is in the render method instead of useEffect so that
// the portal will be added to the DOM before the children render.
// For any further changes, ensure that the container does not have a
// parent besides the portal parent.
appendPortalContainerIfNotAppended(container);
useEffect(() => {
return () => {
removePortalContainer(container);
};
}, [container]);
return /*#__PURE__*/createPortal(isInsideThemeProvider ? /*#__PURE__*/React.createElement(ThemeProvider, {
defaultColorMode: colorMode
}, children) : children, container);
}