UNPKG

@douyinfe/semi-ui

Version:

A modern, comprehensive, flexible design system and UI library. Connect DesignOps & DevOps. Quickly build beautiful React apps. Maintained by Douyin-fe team.

118 lines (117 loc) 3.85 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = require("react"); var _reactDom = require("react-dom"); var _constants = require("@douyinfe/semi-foundation/lib/cjs/base/constants"); var _propTypes = _interopRequireDefault(require("prop-types")); var _classnames = _interopRequireDefault(require("classnames")); var _context = _interopRequireDefault(require("../configProvider/context")); require("@douyinfe/semi-foundation/lib/cjs/_portal/portal.css"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } const defaultGetContainer = () => document.body; class Portal extends _react.PureComponent { constructor(props, context) { var _this; super(props); _this = this; this.initContainer = function (context) { let catchError = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var _a, _b; try { let container = undefined; if (!_this.el || !((_a = _this.state) === null || _a === void 0 ? void 0 : _a.container) || !Array.from(_this.state.container.childNodes).includes(_this.el)) { _this.el = document.createElement('div'); const getContainer = _this.props.getPopupContainer || context.getPopupContainer || defaultGetContainer; const portalContainer = getContainer(); portalContainer.appendChild(_this.el); _this.addStyle(_this.props.style); _this.addClass(_this.props.prefixCls, context, _this.props.className); container = portalContainer; return container; } } catch (e) { if (!catchError) { throw e; } } return (_b = _this.state) === null || _b === void 0 ? void 0 : _b.container; }; this.addStyle = function () { let style = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; if (_this.el) { for (const key of Object.keys(style)) { _this.el.style[key] = style[key]; } } }; this.addClass = function (prefixCls) { let context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _this.context; const { direction } = context; for (var _len = arguments.length, classNames = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { classNames[_key - 2] = arguments[_key]; } const cls = (0, _classnames.default)(prefixCls, ...classNames, { [`${prefixCls}-rtl`]: direction === 'rtl' }); if (_this.el) { _this.el.className = cls; } }; this.state = { container: this.initContainer(context, true) }; } componentDidMount() { const container = this.initContainer(this.context); if (container !== this.state.container) { this.setState({ container }); } } componentDidUpdate(prevProps) { // visible callback const { didUpdate } = this.props; if (didUpdate) { didUpdate(prevProps); } } componentWillUnmount() { const { container } = this.state; if (container) { container.removeChild(this.el); } } render() { const { state, props } = this; if (state.container) { return /*#__PURE__*/(0, _reactDom.createPortal)(props.children, this.el); } return null; } } Portal.contextType = _context.default; Portal.defaultProps = { // getPopupContainer: () => document.body, prefixCls: `${_constants.BASE_CLASS_PREFIX}-portal` }; Portal.propTypes = { children: _propTypes.default.node, prefixCls: _propTypes.default.string, getPopupContainer: _propTypes.default.func, className: _propTypes.default.string, didUpdate: _propTypes.default.func }; var _default = exports.default = Portal;