UNPKG

choerodon-ui

Version:

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

640 lines (523 loc) 18.1 kB
import _extends from "@babel/runtime/helpers/extends"; import _objectSpread from "@babel/runtime/helpers/objectSpread2"; import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _createSuper from "@babel/runtime/helpers/createSuper"; import React, { Component } from 'react'; import { findDOMNode } from 'react-dom'; import { EventManager } from 'choerodon-ui/dataset'; import Animate from '../../animate'; import LazyRenderBox from './LazyRenderBox'; import KeyCode from '../../_util/KeyCode'; import contains from '../util/Dom/contains'; import getScrollBarSize from '../util/getScrollBarSize'; import Icon from '../../icon'; 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) { _inherits(Dialog, _Component); var _super = _createSuper(Dialog); function Dialog() { var _this; _classCallCheck(this, Dialog); _this = _super.apply(this, arguments); _this.center = function () { var center = _this.props.center; var dialogNode = 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 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.ESC) { e.stopPropagation(); _this.close(e); return; } // keep focus inside dialog if (props.visible) { if (e.keyCode === KeyCode.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 = props.width; } if (props.height !== undefined) { dest.height = props.height; } var footer; if (props.footer) { footer = /*#__PURE__*/React.createElement("div", { className: "".concat(prefixCls, "-footer"), ref: _this.saveRef('footer') }, props.footer); } var header; if (props.title) { header = /*#__PURE__*/React.createElement("div", { onMouseDown: _this.handleHeaderMouseDown, className: "".concat(prefixCls, "-header"), ref: _this.saveRef('header') }, /*#__PURE__*/React.createElement("div", { className: "".concat(prefixCls, "-title"), id: _this.titleId }, props.title)); } var closer; if (closable) { closer = /*#__PURE__*/React.createElement("button", { type: "button", onClick: _this.close, "aria-label": "Close", className: "".concat(prefixCls, "-close") }, props.closeIcon || /*#__PURE__*/React.createElement(Icon, { className: "".concat(prefixCls, "-close-x"), type: "close" })); } var style = _objectSpread(_objectSpread({}, props.style), dest); var transitionName = _this.getTransitionName(); var dialogElement = /*#__PURE__*/React.createElement(LazyRenderBox, { key: "dialog-element", role: "document", ref: _this.saveRef('dialog'), style: style, className: "".concat(prefixCls, " ").concat(props.className || ''), hidden: !props.visible }, /*#__PURE__*/React.createElement("div", { ref: _this.saveRef('content'), className: "".concat(prefixCls, "-content") }, closer, header, /*#__PURE__*/React.createElement("div", _extends({ className: "".concat(prefixCls, "-body"), style: props.bodyStyle, ref: _this.saveRef('body') }, props.bodyProps), props.children), footer), /*#__PURE__*/React.createElement("div", { tabIndex: 0, ref: _this.saveRef('sentinel'), style: { width: 0, height: 0, overflow: 'hidden' } }, "sentinel")); return /*#__PURE__*/React.createElement(Animate, { 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 = _assertThisInitialized(_this), wrap = _assertThisInitialize.wrap, movable = _assertThisInitialize.props.movable; var _assertThisInitialize2 = _assertThisInitialized(_this), content = _assertThisInitialize2.content; var dialogNode = findDOMNode(_this.dialog); if (wrap && content && dialogNode && movable) { var clientX = downEvent.clientX, clientY = 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 = _assertThisInitialized(_this), moveEvent = _assertThisInitialize3.moveEvent; if (!moveEvent) { moveEvent = new EventManager(typeof window === 'undefined' ? undefined : document); _this.moveEvent = moveEvent; } moveEvent.addEventListener('mousemove', function (moveEvent) { var moveX = moveEvent.clientX, moveY = 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; _extends(dialogNode.style, { margin: "0rem", top: "0px" }); _extends(wrap.style, { left: "".concat(left, "px"), top: "".concat(top, "px"), overflow: "hidden" }); } _extends(dialogNode.style, { margin: "0rem", top: "0px" }); _extends(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 _objectSpread(_objectSpread({}, _this.getZIndexStyle()), wrapStyle); }; _this.getMaskStyle = function () { var maskStyle = _this.props.maskStyle; return _objectSpread(_objectSpread({}, _this.getZIndexStyle()), maskStyle); }; _this.getMaskElement = function () { var props = _this.props; var maskElement; if (props.mask) { var maskTransition = _this.getMaskTransitionName(); maskElement = /*#__PURE__*/React.createElement(LazyRenderBox, _extends({ 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.createElement(Animate, { 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 = getScrollBarSize(); } }; _this.resetScrollbar = function () { document.body.style.paddingRight = ''; }; _this.adjustDialog = function () { var _assertThisInitialize4 = _assertThisInitialized(_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 = _assertThisInitialized(_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; } _createClass(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 = 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 = 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) { _extends(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 (!contains(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.createElement("div", null, this.getMaskElement(), /*#__PURE__*/React.createElement("div", _extends({ 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; }(Component); export { Dialog as default }; Dialog.defaultProps = { className: '', mask: true, visible: false, keyboard: true, closable: true, maskClosable: true, destroyOnClose: false, prefixCls: 'rc-dialog', center: false }; //# sourceMappingURL=Dialog.js.map