UNPKG

choerodon-ui

Version:

An enterprise-class UI design language and React-based implementation

669 lines (533 loc) 20 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard")["default"]; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"]; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _createSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/createSuper")); var _react = _interopRequireWildcard(require("react")); var _reactDom = require("react-dom"); var _isNumber = _interopRequireDefault(require("lodash/isNumber")); var _dataset = require("choerodon-ui/dataset"); var _util = require("choerodon-ui/shared/util"); var _animate = _interopRequireDefault(require("../../animate")); var _LazyRenderBox = _interopRequireDefault(require("./LazyRenderBox")); var _KeyCode = _interopRequireDefault(require("../../_util/KeyCode")); var _contains = _interopRequireDefault(require("../util/Dom/contains")); var _getScrollBarSize = _interopRequireDefault(require("../util/getScrollBarSize")); var _icon = _interopRequireDefault(require("../../icon")); var _UnitConvertor = require("../../_util/UnitConvertor"); var uuid = 0; var openCount = 0; /* eslint react/no-is-mounted:0 */ function getScroll(w, top) { var ret = w["page".concat(top ? 'Y' : 'X', "Offset")]; var method = "scroll".concat(top ? 'Top' : 'Left'); if (typeof ret !== 'number') { var d = w.document; ret = d.documentElement[method]; if (typeof ret !== 'number') { ret = d.body[method]; } } return ret; } function setTransformOrigin(node, value) { var style = node.style; ['Webkit', 'Moz', 'Ms', 'ms'].forEach(function (prefix) { style["".concat(prefix, "TransformOrigin")] = value; }); style.transformOrigin = value; } function offset(el) { var rect = el.getBoundingClientRect(); var pos = { left: rect.left, top: rect.top }; var doc = el.ownerDocument; var w = doc.defaultView || doc.parentWindow; pos.left += getScroll(w); pos.top += getScroll(w, true); return pos; } function getLeftTop(content) { var t = 0; var l = 0; /* tslint:disable */ for (t = content.offsetTop, l = content.offsetLeft, content = content.offsetParent; content;) { t += content.offsetTop; l += content.offsetLeft; content = content.offsetParent; } /* tslint:enable */ return { top: t, left: l }; } var Dialog = /*#__PURE__*/function (_Component) { (0, _inherits2["default"])(Dialog, _Component); var _super = (0, _createSuper2["default"])(Dialog); function Dialog() { var _this; (0, _classCallCheck2["default"])(this, Dialog); _this = _super.apply(this, arguments); _this.center = function () { var center = _this.props.center; var dialogNode = (0, _reactDom.findDOMNode)(_this.dialog); if (center && dialogNode && typeof window !== 'undefined') { var _window$document$docu = window.document.documentElement, docWidth = _window$document$docu.clientWidth, docHeight = _window$document$docu.clientHeight; var width = dialogNode.offsetWidth, height = dialogNode.offsetHeight, style = dialogNode.style; style.left = "".concat(Math.max((docWidth - width) / 2, 0), "px"); style.top = "".concat(Math.max((docHeight - height) / 2, 0), "px"); } }; _this.onEventListener = function () { if (typeof window !== 'undefined') { _this.resizeEvent = new _dataset.EventManager(window).addEventListener('resize', _this.center); } }; _this.removeEventListener = function () { if (_this.resizeEvent) { _this.resizeEvent.clear(); } if (_this.moveEvent) { _this.moveEvent.clear(); } }; _this.onAnimateLeave = function () { var afterClose = _this.props.afterClose; // need demo? // https://github.com/react-component/dialog/pull/28 if (_this.wrap) { _this.wrap.style.display = 'none'; } _this.inTransition = false; _this.removeScrollingEffect(); if (afterClose) { afterClose(); } }; _this.onAnimateEnd = function () { var animationEnd = _this.props.animationEnd; if (animationEnd) { animationEnd(); } }; _this.onMaskClick = function (e) { // android trigger click on open (fastclick??) if (Date.now() - _this.openTime < 300) { return; } if (e.target === e.currentTarget) { _this.close(e); } }; _this.onKeyDown = function (e) { var props = _this.props; if (props.keyboard && e.keyCode === _KeyCode["default"].ESC) { e.stopPropagation(); _this.close(e); return; } // keep focus inside dialog if (props.visible) { if (e.keyCode === _KeyCode["default"].TAB) { var activeElement = document.activeElement; var dialogRoot = _this.wrap; if (e.shiftKey) { if (activeElement === dialogRoot) { _this.sentinel.focus(); } } else if (activeElement === _this.sentinel) { dialogRoot.focus(); } } } }; _this.getDialogElement = function () { var props = _this.props; var closable = props.closable; var prefixCls = props.prefixCls; var dest = {}; if (props.width !== undefined) { dest.width = (0, _isNumber["default"])(props.width) ? (0, _UnitConvertor.pxToRem)(props.width) : props.width; } if (props.height !== undefined) { dest.height = (0, _isNumber["default"])(props.height) ? (0, _UnitConvertor.pxToRem)(props.height) : props.height; } var footer; if (props.footer) { footer = /*#__PURE__*/_react["default"].createElement("div", { className: "".concat(prefixCls, "-footer"), ref: _this.saveRef('footer') }, props.footer); } var header; if (props.title) { header = /*#__PURE__*/_react["default"].createElement("div", { onMouseDown: _this.handleHeaderMouseDown, className: "".concat(prefixCls, "-header"), ref: _this.saveRef('header') }, /*#__PURE__*/_react["default"].createElement("div", { className: "".concat(prefixCls, "-title"), id: _this.titleId }, props.title)); } var closer; if (closable) { closer = /*#__PURE__*/_react["default"].createElement("button", { type: "button", onClick: _this.close, "aria-label": "Close", className: "".concat(prefixCls, "-close") }, props.closeIcon || /*#__PURE__*/_react["default"].createElement(_icon["default"], { className: "".concat(prefixCls, "-close-x"), type: "close" })); } var style = (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, props.style), dest); var transitionName = _this.getTransitionName(); var dialogElement = /*#__PURE__*/_react["default"].createElement(_LazyRenderBox["default"], { key: "dialog-element", role: "document", ref: _this.saveRef('dialog'), style: style, className: "".concat(prefixCls, " ").concat(props.className || ''), hidden: !props.visible }, /*#__PURE__*/_react["default"].createElement("div", { ref: _this.saveRef('content'), className: "".concat(prefixCls, "-content") }, closer, header, /*#__PURE__*/_react["default"].createElement("div", (0, _extends2["default"])({ className: "".concat(prefixCls, "-body"), style: props.bodyStyle, ref: _this.saveRef('body') }, props.bodyProps), props.children), footer), /*#__PURE__*/_react["default"].createElement("div", { tabIndex: 0, ref: _this.saveRef('sentinel'), style: { width: 0, height: 0, overflow: 'hidden' } }, "sentinel")); return /*#__PURE__*/_react["default"].createElement(_animate["default"], { key: "dialog", hiddenProp: "hidden", onEnd: _this.onAnimateEnd, onLeave: _this.onAnimateLeave, transitionName: transitionName, component: "", transitionAppear: true }, props.visible || !props.destroyOnClose ? dialogElement : null); }; _this.handleHeaderMouseDown = function (downEvent) { var _assertThisInitialize = (0, _assertThisInitialized2["default"])(_this), wrap = _assertThisInitialize.wrap, movable = _assertThisInitialize.props.movable; var _assertThisInitialize2 = (0, _assertThisInitialized2["default"])(_this), content = _assertThisInitialize2.content; var dialogNode = (0, _reactDom.findDOMNode)(_this.dialog); if (wrap && content && dialogNode && movable) { var clientX = (0, _util.transformZoomData)(downEvent.clientX); var clientY = (0, _util.transformZoomData)(downEvent.clientY); var offsetLeft = wrap.offsetLeft, offsetTop = wrap.offsetTop; if (dialogNode.style.margin !== '0rem') { var _getLeftTop = getLeftTop(content), left = _getLeftTop.left, top = _getLeftTop.top; offsetLeft = left; offsetTop = top; } var _assertThisInitialize3 = (0, _assertThisInitialized2["default"])(_this), moveEvent = _assertThisInitialize3.moveEvent; if (!moveEvent) { moveEvent = new _dataset.EventManager(typeof window === 'undefined' ? undefined : document); _this.moveEvent = moveEvent; } moveEvent.addEventListener('mousemove', function (moveEvent) { var moveX = (0, _util.transformZoomData)(moveEvent.clientX); var moveY = (0, _util.transformZoomData)(moveEvent.clientY); var left = Math.max(offsetLeft + moveX - clientX, 0); var top = Math.max(offsetTop + moveY - clientY, 0); if (dialogNode.style.margin !== '0rem') { offsetLeft = left; offsetTop = top; (0, _extends2["default"])(dialogNode.style, { margin: "0rem", top: "0px" }); (0, _extends2["default"])(wrap.style, { left: "".concat(left, "px"), top: "".concat(top, "px"), overflow: "hidden" }); } (0, _extends2["default"])(dialogNode.style, { margin: "0rem", top: "0px" }); (0, _extends2["default"])(wrap.style, { left: "".concat(left, "px"), top: "".concat(top, "px") }); }).addEventListener('mouseup', function () { if (moveEvent) { moveEvent.clear(); } }); } }; _this.getZIndexStyle = function () { var style = {}; var props = _this.props; if (props.zIndex !== undefined) { style.zIndex = props.zIndex; } return style; }; _this.getWrapStyle = function () { var wrapStyle = _this.props.wrapStyle; return (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, _this.getZIndexStyle()), wrapStyle); }; _this.getMaskStyle = function () { var maskStyle = _this.props.maskStyle; return (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, _this.getZIndexStyle()), maskStyle); }; _this.getMaskElement = function () { var props = _this.props; var maskElement; if (props.mask) { var maskTransition = _this.getMaskTransitionName(); maskElement = /*#__PURE__*/_react["default"].createElement(_LazyRenderBox["default"], (0, _extends2["default"])({ style: _this.getMaskStyle(), key: "mask", className: "".concat(props.prefixCls, "-mask"), hiddenClassName: "".concat(props.prefixCls, "-mask-hidden"), hidden: !props.visible }, props.maskProps)); if (maskTransition) { maskElement = /*#__PURE__*/_react["default"].createElement(_animate["default"], { key: "mask", hiddenProp: "hidden", transitionAppear: true, component: "", transitionName: maskTransition }, maskElement); } } return maskElement; }; _this.getMaskTransitionName = function () { var props = _this.props; var transitionName = props.maskTransitionName; var animation = props.maskAnimation; if (!transitionName && animation) { transitionName = "".concat(props.prefixCls, "-").concat(animation); } return transitionName; }; _this.getTransitionName = function () { var props = _this.props; var transitionName = props.transitionName; var animation = props.animation; if (!transitionName && animation) { transitionName = "".concat(props.prefixCls, "-").concat(animation); } return transitionName; }; _this.setScrollbar = function () { if (_this.bodyIsOverflowing && _this.scrollbarWidth !== undefined) { document.body.style.paddingRight = "".concat(_this.scrollbarWidth, "px"); } }; _this.addScrollingEffect = function () { openCount++; if (openCount !== 1) { return; } _this.checkScrollbar(); _this.setScrollbar(); document.body.style.overflow = 'hidden'; // this.adjustDialog(); }; _this.removeScrollingEffect = function () { openCount--; if (openCount !== 0) { return; } document.body.style.overflow = ''; _this.resetScrollbar(); // this.resetAdjustments(); }; _this.close = function (e) { var onClose = _this.props.onClose; if (onClose) { onClose(e); } }; _this.checkScrollbar = function () { var fullWindowWidth = window.innerWidth; if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8 var documentElementRect = document.documentElement.getBoundingClientRect(); fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left); } _this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth; if (_this.bodyIsOverflowing) { _this.scrollbarWidth = (0, _getScrollBarSize["default"])(); } }; _this.resetScrollbar = function () { document.body.style.paddingRight = ''; }; _this.adjustDialog = function () { var _assertThisInitialize4 = (0, _assertThisInitialized2["default"])(_this), wrap = _assertThisInitialize4.wrap; if (wrap && _this.scrollbarWidth !== undefined) { var modalIsOverflowing = wrap.scrollHeight > document.documentElement.clientHeight; wrap.style.paddingLeft = "".concat(!_this.bodyIsOverflowing && modalIsOverflowing ? _this.scrollbarWidth : '', "px"); wrap.style.paddingRight = "".concat(_this.bodyIsOverflowing && !modalIsOverflowing ? _this.scrollbarWidth : '', "px"); } }; _this.resetAdjustments = function () { var _assertThisInitialize5 = (0, _assertThisInitialized2["default"])(_this), wrap = _assertThisInitialize5.wrap; if (wrap) { var style = wrap.style; style.paddingLeft = ''; style.paddingRight = ''; } }; _this.saveRef = function (name) { return function (node) { _this[name] = node; }; }; return _this; } (0, _createClass2["default"])(Dialog, [{ key: "componentWillMount", value: function componentWillMount() { this.inTransition = false; this.titleId = "rcDialogTitle".concat(uuid++); } }, { key: "componentDidMount", value: function componentDidMount() { var center = this.props.center; var dialogNode = (0, _reactDom.findDOMNode)(this.dialog); if (center && dialogNode) { var style = dialogNode.style; this.center(); style.margin = '0'; style.padding = '0'; this.onEventListener(); } this.componentDidUpdate({}); } }, { key: "componentDidUpdate", value: function componentDidUpdate(prevProps) { var _this$props = this.props, mousePosition = _this$props.mousePosition, visible = _this$props.visible, mask = _this$props.mask, movable = _this$props.movable; if (visible) { // first show if (!prevProps.visible) { this.center(); this.openTime = Date.now(); this.lastOutSideFocusNode = document.activeElement; this.addScrollingEffect(); this.tryFocus(); var dialogNode = (0, _reactDom.findDOMNode)(this.dialog); if (mousePosition) { var elOffset = offset(dialogNode); setTransformOrigin(dialogNode, "".concat(mousePosition.x - elOffset.left, "px ").concat(mousePosition.y - elOffset.top, "px")); } else { setTransformOrigin(dialogNode, ''); } } } else if (prevProps.visible) { this.inTransition = true; if (mask && this.lastOutSideFocusNode) { try { this.lastOutSideFocusNode.focus(); } catch (e) { this.lastOutSideFocusNode = null; } this.lastOutSideFocusNode = null; } } if (this.header && movable) { (0, _extends2["default"])(this.header.style, { cursor: 'move' }); } } }, { key: "componentWillUnmount", value: function componentWillUnmount() { var visible = this.props.visible; if (visible || this.inTransition) { this.removeScrollingEffect(); } this.removeEventListener(); } }, { key: "tryFocus", value: function tryFocus() { if (!(0, _contains["default"])(this.wrap, document.activeElement)) { this.lastOutSideFocusNode = document.activeElement; this.wrap.focus(); } } }, { key: "render", value: function render() { var props = this.props; var prefixCls = props.prefixCls, maskClosable = props.maskClosable; var style = this.getWrapStyle(); // clear hide display // and only set display after async anim, not here for hide if (props.visible) { style.display = null; } return /*#__PURE__*/_react["default"].createElement("div", null, this.getMaskElement(), /*#__PURE__*/_react["default"].createElement("div", (0, _extends2["default"])({ tabIndex: -1, onKeyDown: this.onKeyDown, className: "".concat(prefixCls, "-wrap ").concat(props.wrapClassName || ''), ref: this.saveRef('wrap'), onClick: maskClosable ? this.onMaskClick : undefined, role: "dialog", "aria-labelledby": props.title ? this.titleId : null, style: style }, props.wrapProps), this.getDialogElement())); } }]); return Dialog; }(_react.Component); exports["default"] = Dialog; Dialog.defaultProps = { className: '', mask: true, visible: false, keyboard: true, closable: true, maskClosable: true, destroyOnClose: false, prefixCls: 'rc-dialog', center: false }; //# sourceMappingURL=Dialog.js.map