choerodon-ui
Version:
An enterprise-class UI design language and React-based implementation
774 lines (634 loc) • 22.9 kB
JavaScript
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getContainer = getContainer;
exports.open = open;
exports["default"] = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _tslib = require("tslib");
var _react = _interopRequireWildcard(require("react"));
var _reactDom = require("react-dom");
var _mobx = require("mobx");
var _mobxReact = require("mobx-react");
var _findLast = _interopRequireDefault(require("lodash/findLast"));
var _noop = _interopRequireDefault(require("lodash/noop"));
var _EventManager = _interopRequireDefault(require("../../../lib/_util/EventManager"));
var _measureScrollbar = _interopRequireDefault(require("../../../lib/_util/measureScrollbar"));
var _UnitConvertor = require("../../../lib/_util/UnitConvertor");
var _warning = _interopRequireDefault(require("../../../lib/_util/warning"));
var _configure = require("../../../lib/configure");
var _modalManager = _interopRequireDefault(require("../modal-manager"));
var _Modal = _interopRequireDefault(require("../modal/Modal"));
var _animate = _interopRequireDefault(require("../animate"));
var _Mask = _interopRequireDefault(require("./Mask"));
var _EventManager2 = require("../_util/EventManager");
var _utils = require("../modal/utils");
var _DocumentUtils = require("../_util/DocumentUtils");
function _createSuper(Derived) {
function isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
Date.prototype.toString.call(Reflect.construct(Date, [], function () {}));
return true;
} catch (e) {
return false;
}
}
return function () {
var Super = (0, _getPrototypeOf2["default"])(Derived),
result;
if (isNativeReflectConstruct()) {
var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor;
result = Reflect.construct(Super, arguments, NewTarget);
} else {
result = Super.apply(this, arguments);
}
return (0, _possibleConstructorReturn2["default"])(this, result);
};
}
var containerInstances = _modalManager["default"].containerInstances;
function getArrayIndex(array, index) {
if (array.length > index) {
return array[index];
}
return 0;
}
function getRoot() {
var root = _modalManager["default"].root;
if (typeof window !== 'undefined') {
var doc = (0, _DocumentUtils.getDocument)(window);
if (root) {
if (!root.parentNode) {
doc.body.appendChild(root);
}
} else {
root = doc.createElement('div');
root.className = "".concat((0, _configure.getProPrefixCls)(_utils.suffixCls), "-container");
doc.body.appendChild(root);
_modalManager["default"].root = root;
}
}
return root;
}
/**
* 判断body是否有滚动条
*
* @returns {boolean}
*/
function hasScrollBar(body) {
var scrollHeight = body.scrollHeight,
clientHeight = body.clientHeight;
return scrollHeight > clientHeight;
}
function hideBodyScrollBar(body) {
var style = body.style;
if (!_modalManager["default"].defaultBodyStyle) {
_modalManager["default"].defaultBodyStyle = {
overflow: style.overflow,
paddingRight: style.paddingRight
};
style.overflow = 'hidden';
if (hasScrollBar(body)) {
style.paddingRight = (0, _UnitConvertor.pxToRem)((0, _measureScrollbar["default"])()) || '';
}
}
}
function showBodyScrollBar(body) {
var style = body.style;
if (_modalManager["default"].defaultBodyStyle) {
var _ModalManager$default = _modalManager["default"].defaultBodyStyle,
overflow = _ModalManager$default.overflow,
paddingRight = _ModalManager$default.paddingRight;
_modalManager["default"].defaultBodyStyle = undefined;
style.overflow = overflow;
style.paddingRight = paddingRight;
}
}
var ModalContainer =
/*#__PURE__*/
function (_Component) {
(0, _inherits2["default"])(ModalContainer, _Component);
var _super = _createSuper(ModalContainer);
function ModalContainer(props, context) {
var _this;
(0, _classCallCheck2["default"])(this, ModalContainer);
_this = _super.call(this, props, context);
_this.state = {
modals: []
};
_this.saveMount = function (mount) {
if (mount) {
_this.setState({
mount: mount
});
}
};
_this.handleAnimationEnd = function (modalKey, isEnter) {
if (!isEnter) {
var modals = _this.state.modals;
var index = _this.findIndex(modalKey);
if (index !== -1) {
var _props = modals[index];
modals.splice(index, 1);
if (!_props.destroyOnClose) {
modals.unshift(_props);
}
if (_props.afterClose) {
_props.afterClose();
}
_this.updateModals(modals);
}
}
};
_this.handleMaskClick =
/*#__PURE__*/
(0, _asyncToGenerator2["default"])(
/*#__PURE__*/
_regenerator["default"].mark(function _callee() {
var modals, modal, _modal$close, close, _modal$onCancel, onCancel, _modal$maskClosable, maskClosable, ret;
return _regenerator["default"].wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
modals = _this.state.modals;
modal = (0, _findLast["default"])(modals, function (_ref2) {
var hidden = _ref2.hidden;
return !hidden;
});
if (!modal) {
_context.next = 9;
break;
}
_modal$close = modal.close, close = _modal$close === void 0 ? _noop["default"] : _modal$close, _modal$onCancel = modal.onCancel, onCancel = _modal$onCancel === void 0 ? _noop["default"] : _modal$onCancel, _modal$maskClosable = modal.maskClosable, maskClosable = _modal$maskClosable === void 0 ? (0, _configure.getConfig)('modalMaskClosable') : _modal$maskClosable;
if (!maskClosable) {
_context.next = 9;
break;
}
_context.next = 7;
return onCancel();
case 7:
ret = _context.sent;
if (ret !== false) {
close();
}
case 9:
case "end":
return _context.stop();
}
}
}, _callee);
}));
(0, _mobx.runInAction)(function () {
_this.maskHidden = true;
_this.drawerOffsets = {
'slide-up': [],
'slide-right': [],
'slide-down': [],
'slide-left': []
};
_this.top();
var doc = typeof window === 'undefined' ? undefined : document;
if (doc && !_modalManager["default"].mousePositionEventBound.has(doc)) {
new _EventManager["default"](doc).addEventListener('click', function (e) {
_modalManager["default"].mousePosition = (0, _DocumentUtils.getMousePosition)(e.clientX, e.clientY, window); // 100ms 内发生过点击事件,则从点击位置动画展示
// 否则直接 zoom 展示
// 这样可以兼容非点击方式展开
setTimeout(function () {
return _modalManager["default"].mousePosition = undefined;
}, 100);
}, true);
_modalManager["default"].mousePositionEventBound.add(doc);
}
});
return _this;
}
(0, _createClass2["default"])(ModalContainer, [{
key: "top",
value: function top() {
_modalManager["default"].addInstance(this);
return this;
}
}, {
key: "componentDidUpdate",
value: function componentDidUpdate(prevProps) {
var location = prevProps.location;
var currentLocation = this.props.location;
if (location && currentLocation && location.pathname !== currentLocation.pathname) {
_modalManager["default"].clear(true);
}
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
var modals = this.state.modals;
_modalManager["default"].removeInstance(this);
var current = _modalManager["default"].containerInstances[0];
if (current && modals.length) {
current.mergeModals(modals.reduce(function (list, modal) {
return modal.__deprecate__ && (!modal.hidden || !modal.destroyOnClose) ? list.concat((0, _objectSpread2["default"])({}, modal, {
transitionAppear: false
})) : list;
}, []));
}
}
}, {
key: "updateModals",
value: function updateModals(modals) {
this.top();
var maskHidden = true;
var drawerOffsets = {
'slide-up': [],
'slide-right': [],
'slide-down': [],
'slide-left': []
};
modals.slice().reverse().forEach(function (_ref3) {
var hidden = _ref3.hidden,
drawer = _ref3.drawer,
drawerOffset = _ref3.drawerOffset,
drawerTransitionName = _ref3.drawerTransitionName;
if (!hidden) {
maskHidden = false;
if (drawer && drawerTransitionName) {
var offsets = drawerOffsets[drawerTransitionName];
var offset = offsets[0] || 0;
offsets.unshift(offset + (drawerOffset || 0));
}
}
});
this.drawerOffsets = drawerOffsets;
this.maskHidden = maskHidden; // modals.every(({ hidden }) => hidden);
this.setState({
modals: modals
});
}
}, {
key: "mergeModals",
value: function mergeModals(newModals) {
var modals = this.state.modals;
var map = new Map();
modals.forEach(function (modal) {
if (modal.key) {
map.set(modal.key, modal);
}
});
newModals.forEach(function (modal) {
if (modal.key) {
map.set(modal.key, modal);
}
});
this.updateModals((0, _toConsumableArray2["default"])(map.values()));
}
}, {
key: "findIndex",
value: function findIndex(modalKey) {
var modals = this.state.modals;
return modals.findIndex(function (_ref4) {
var key = _ref4.key;
return key === modalKey;
});
}
}, {
key: "open",
value: function open(props) {
var modals = this.state.modals;
if (!props.key) {
props.key = _modalManager["default"].getKey();
(0, _warning["default"])(!!props.destroyOnClose, "The modal which opened has no key, please provide a key or set the `destroyOnClose` as true.");
} else {
var index = this.findIndex(props.key);
if (index !== -1) {
modals.splice(index, 1);
}
}
modals.push((0, _objectSpread2["default"])({}, props, {
hidden: false
}));
this.updateModals(modals);
}
}, {
key: "close",
value: function close(props) {
var modals = this.state.modals;
var target = modals.find(function (_ref5) {
var key = _ref5.key;
return key === props.key;
});
if (target) {
(0, _extends2["default"])(target, props, {
hidden: true
});
this.updateModals(modals);
}
}
}, {
key: "update",
value: function update(props) {
var originModals = this.state.modals;
var modals = (0, _toConsumableArray2["default"])(originModals);
if (props.key) {
var index = this.findIndex(props.key);
if (index !== -1) {
modals[index] = (0, _objectSpread2["default"])({}, modals[index], {}, props);
this.updateModals(modals);
}
}
}
}, {
key: "clear",
value: function clear(closeByLocationChange) {
var modals = this.state.modals;
this.updateModals(modals.map(function (modal) {
return closeByLocationChange && !modal.closeOnLocationChange ? modal : (0, _objectSpread2["default"])({}, modal, {
destroyOnClose: true,
hidden: true
});
}));
}
}, {
key: "getModalWidth",
value: function getModalWidth(modal) {
return modal && modal.style && modal.style.width || 520;
}
}, {
key: "getComponent",
value: function getComponent(mount) {
var _this2 = this;
var hidden = this.maskHidden,
isTop = this.isTop,
drawerOffsets = this.drawerOffsets,
baseOffsets = this.baseOffsets;
var modals = this.state.modals;
var indexes = {
'slide-up': 1,
'slide-right': 1,
'slide-down': 1,
'slide-left': 1
};
var activeModal;
var maskTransition = true;
var items = modals.map(function (props, index) {
var _props$drawerTransiti = props.drawerTransitionName,
drawerTransitionName = _props$drawerTransiti === void 0 ? (0, _configure.getConfig)('drawerTransitionName') : _props$drawerTransiti,
drawer = props.drawer,
key = props.key,
_props$transitionAppe = props.transitionAppear,
transitionAppear = _props$transitionAppe === void 0 ? true : _props$transitionAppe;
var style = (0, _objectSpread2["default"])({}, props.style);
if (drawer && drawerTransitionName) {
var i = indexes[drawerTransitionName];
indexes[drawerTransitionName] += 1;
var offset = getArrayIndex(drawerOffsets[drawerTransitionName], i) + baseOffsets[drawerTransitionName];
if (offset) {
switch (drawerTransitionName) {
case 'slide-up':
style.marginTop = offset;
break;
case 'slide-down':
style.marginBottom = offset;
break;
case 'slide-left':
style.marginLeft = offset;
break;
default:
style.marginRight = offset;
}
}
}
var active = isTop && index === modals.length - 1;
if (active) {
activeModal = props;
}
if (transitionAppear === false) {
maskTransition = false;
}
return _react["default"].createElement(_animate["default"], {
key: key,
component: "div",
// UED 用类名判断
className: props.drawer ? "".concat((0, _configure.getProPrefixCls)(_utils.suffixCls), "-container-drawer") : "".concat((0, _configure.getProPrefixCls)(_utils.suffixCls), "-container-pristine"),
transitionAppear: transitionAppear,
transitionName: drawer ? drawerTransitionName : 'zoom',
hiddenProp: "hidden",
onEnd: _this2.handleAnimationEnd
}, _react["default"].createElement(_Modal["default"], (0, _extends2["default"])({
key: key,
mousePosition: _modalManager["default"].mousePosition
}, props, {
style: style,
active: active
})));
});
var animationProps = {};
if (mount && mount.ownerDocument) {
var body = mount.ownerDocument.body;
if (containerInstances.every(function (instance) {
return instance.maskHidden;
})) {
animationProps.onEnd = function () {
return showBodyScrollBar(body);
};
} else {
hideBodyScrollBar(body);
}
}
var eventProps = {};
if (activeModal && activeModal.mask) {
var _activeModal = activeModal,
_activeModal$maskClos = _activeModal.maskClosable,
maskClosable = _activeModal$maskClos === void 0 ? (0, _configure.getConfig)('modalMaskClosable') : _activeModal$maskClos;
if (maskClosable === 'dblclick') {
eventProps.onDoubleClick = this.handleMaskClick;
} else {
eventProps.onClick = this.handleMaskClick;
}
}
return _react["default"].createElement(_react["default"].Fragment, null, _react["default"].createElement(_animate["default"], (0, _extends2["default"])({
component: "",
transitionAppear: true,
transitionName: maskTransition ? 'fade' : undefined,
hiddenProp: "hidden"
}, animationProps), activeModal && activeModal.mask ? _react["default"].createElement(_Mask["default"], (0, _extends2["default"])({
style: activeModal.maskStyle,
className: activeModal.maskClassName,
hidden: hidden
}, eventProps, {
onMouseDown: _EventManager2.stopEvent
})) : _react["default"].createElement("div", {
hidden: hidden
})), items, !mount && _react["default"].createElement("span", {
ref: this.saveMount
}));
}
}, {
key: "getContainer",
value: function getContainer() {
var getModalContainer = this.props.getContainer;
if (typeof getModalContainer === 'function') {
return getModalContainer();
}
return getModalContainer;
}
}, {
key: "render",
value: function render() {
var getModalContainer = this.props.getContainer;
if (getModalContainer === false) {
var _mount = this.state.mount;
return this.getComponent(_mount);
}
var mount = this.getContainer();
if (mount) {
return (0, _reactDom.createPortal)(this.getComponent(mount), mount);
}
return null;
}
}, {
key: "baseOffsets",
get: function get() {
var _this3 = this;
var offsets = {
'slide-up': 0,
'slide-right': 0,
'slide-down': 0,
'slide-left': 0
};
containerInstances.some(function (instance) {
if (instance === _this3) {
return true;
}
var drawerOffsets = instance.drawerOffsets,
maskHidden = instance.maskHidden;
if (!maskHidden) {
offsets['slide-up'] += getArrayIndex(drawerOffsets['slide-up'], 0);
offsets['slide-right'] += getArrayIndex(drawerOffsets['slide-right'], 0);
offsets['slide-down'] += getArrayIndex(drawerOffsets['slide-down'], 0);
offsets['slide-left'] += getArrayIndex(drawerOffsets['slide-left'], 0);
}
return false;
});
return offsets;
}
}, {
key: "isTop",
get: function get() {
var _this4 = this;
var is = true;
containerInstances.some(function (instance) {
if (instance !== _this4 && !instance.maskHidden) {
is = false;
return true;
}
if (instance === _this4) {
return true;
}
return false;
});
return is;
}
}]);
return ModalContainer;
}(_react.Component);
ModalContainer.displayName = 'ModalContainer';
ModalContainer.defaultProps = {
getContainer: getRoot
};
(0, _tslib.__decorate)([_mobx.observable], ModalContainer.prototype, "maskHidden", void 0);
(0, _tslib.__decorate)([_mobx.observable], ModalContainer.prototype, "drawerOffsets", void 0);
(0, _tslib.__decorate)([_mobx.computed], ModalContainer.prototype, "baseOffsets", null);
(0, _tslib.__decorate)([_mobx.computed], ModalContainer.prototype, "isTop", null);
(0, _tslib.__decorate)([_mobx.action], ModalContainer.prototype, "top", null);
(0, _tslib.__decorate)([_mobx.action], ModalContainer.prototype, "updateModals", null);
ModalContainer = (0, _tslib.__decorate)([_mobxReact.observer], ModalContainer);
var _default = ModalContainer;
exports["default"] = _default;
function getContainer(loop) {
var length = containerInstances.length;
if (length) {
return containerInstances[0];
}
if (loop !== true) {
var root = getRoot();
if (root) {
(0, _reactDom.render)(_react["default"].createElement(ModalContainer, null), root);
}
return getContainer(true);
}
}
function open(props) {
var container = getContainer();
function getCurrentContainer() {
return containerInstances.includes(container) ? container : getContainer();
}
function close(_x) {
return _close.apply(this, arguments);
}
function _close() {
_close = (0, _asyncToGenerator2["default"])(
/*#__PURE__*/
_regenerator["default"].mark(function _callee2(destroy) {
var _props2, _props2$onClose, onClose;
return _regenerator["default"].wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
_props2 = props, _props2$onClose = _props2.onClose, onClose = _props2$onClose === void 0 ? _noop["default"] : _props2$onClose;
_context2.next = 3;
return onClose();
case 3:
_context2.t0 = _context2.sent;
if (!(_context2.t0 !== false)) {
_context2.next = 6;
break;
}
if (destroy) {
getCurrentContainer().close((0, _objectSpread2["default"])({}, props, {
destroyOnClose: true
}));
} else {
getCurrentContainer().close(props);
}
case 6:
case "end":
return _context2.stop();
}
}
}, _callee2);
}));
return _close.apply(this, arguments);
}
function update(newProps) {
getCurrentContainer().update((0, _objectSpread2["default"])({}, newProps, {
key: props.key
}));
}
props = (0, _objectSpread2["default"])({
__deprecate__: true,
close: close,
update: update
}, _Modal["default"].defaultProps, {}, props);
container.open(props);
function show(newProps) {
getCurrentContainer().open((0, _objectSpread2["default"])({}, props, {}, newProps));
}
return {
close: close,
open: show,
update: update
};
}
//# sourceMappingURL=ModalContainer.js.map