lucid-ui
Version:
A UI component library from Xandr.
71 lines • 2.35 kB
JavaScript
import React from 'react';
import { omit } from 'lodash';
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom';
import { lucidClassNames } from '../../util/style-helpers';
import classNames from 'classnames';
const cx = lucidClassNames.bind('&-Portal');
const { any, node, string } = PropTypes;
class Portal extends React.Component {
constructor() {
super(...arguments);
this.state = {
isReady: false,
};
this.manuallyCreatedPortal = false;
this.portalElement = document.createElement('div');
}
componentDidMount() {
const { portalId } = this.props;
let portalElement;
if (portalId) {
portalElement = document.getElementById(portalId);
}
if (!portalElement) {
this.manuallyCreatedPortal = true;
portalElement = document.createElement('div');
portalElement.id = portalId;
document.body.appendChild(portalElement);
}
this.portalElement = portalElement;
this.setState({ isReady: true });
}
componentWillUnmount() {
if (this.manuallyCreatedPortal) {
this.portalElement.remove();
}
}
render() {
return this.state.isReady
? ReactDOM.createPortal(React.createElement("div", { "data-test-id": this.props.className, className: classNames(cx('&'), this.props.className), ...omit(this.props, [
'className',
'children',
'portalId',
'initialState',
'callbackId',
]) }, this.props.children), this.portalElement)
: null;
}
}
Portal.displayName = 'Portal';
Portal.peek = {
description: `A \`Portal\` component is used to render content in a container that is appended to \`document.body\`.`,
categories: ['utility'],
};
Portal.propTypes = {
/**
any valid React children
*/
children: node,
/**
Appended to the component-specific class names set on the root element.
Value is run through the \`classnames\` library.
*/
className: any,
/**
The \`id\` of the portal element that is appended to \`document.body\`.
*/
portalId: string,
};
export default Portal;
//# sourceMappingURL=Portal.js.map