UNPKG

@shopify/polaris

Version:

Shopify’s product component library

47 lines (46 loc) 1.77 kB
import React from 'react'; import { createPortal } from 'react-dom'; import { createUniqueIDFactory } from '@shopify/javascript-utilities/other'; import { ThemeContext } from '../../utilities/theme'; const getUniqueID = createUniqueIDFactory('portal-'); export class Portal extends React.PureComponent { constructor() { super(...arguments); this.state = { isMounted: false }; this.portalId = this.props.idPrefix !== '' ? `${this.props.idPrefix}-${getUniqueID()}` : getUniqueID(); } componentDidMount() { this.portalNode = document.createElement('div'); this.portalNode.setAttribute('data-portal-id', this.portalId); if (this.context != null) { /* eslint-disable babel/camelcase */ const { UNSTABLE_cssCustomProperties = '' } = this.context; this.portalNode.setAttribute('style', UNSTABLE_cssCustomProperties); } document.body.appendChild(this.portalNode); this.setState({ isMounted: true }); } componentDidUpdate(_, prevState) { const { onPortalCreated = noop } = this.props; if (this.context != null) { const { UNSTABLE_cssCustomProperties = '' } = this.context; this.portalNode.setAttribute('style', UNSTABLE_cssCustomProperties); } if (!prevState.isMounted && this.state.isMounted) { onPortalCreated(); } } componentWillUnmount() { document.body.removeChild(this.portalNode); } render() { return this.state.isMounted ? createPortal(this.props.children, this.portalNode) : null; } } Portal.defaultProps = { idPrefix: '' }; Portal.contextType = ThemeContext; function noop() { }