choerodon-ui
Version:
An enterprise-class UI design language and React-based implementation
640 lines (523 loc) • 18.1 kB
JavaScript
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