@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
JavaScript
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;
;