UNPKG

14.4 kBJavaScriptView Raw
1"use strict";
2
3var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
4
5var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
6
7Object.defineProperty(exports, "__esModule", {
8 value: true
9});
10exports.default = void 0;
11
12var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
13
14var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
15
16var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
17
18var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
19
20var _createSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/createSuper"));
21
22var React = _interopRequireWildcard(require("react"));
23
24var ReactDOM = _interopRequireWildcard(require("react-dom"));
25
26var _KeyCode = _interopRequireDefault(require("rc-util/lib/KeyCode"));
27
28var _contains = _interopRequireDefault(require("rc-util/lib/Dom/contains"));
29
30var _rcAnimate = _interopRequireDefault(require("rc-animate"));
31
32var _LazyRenderBox = _interopRequireDefault(require("./LazyRenderBox"));
33
34var uuid = 0;
35/* eslint react/no-is-mounted:0 */
36
37function getScroll(w, top) {
38 var ret = w["page".concat(top ? 'Y' : 'X', "Offset")];
39 var method = "scroll".concat(top ? 'Top' : 'Left');
40
41 if (typeof ret !== 'number') {
42 var d = w.document;
43 ret = d.documentElement[method];
44
45 if (typeof ret !== 'number') {
46 ret = d.body[method];
47 }
48 }
49
50 return ret;
51}
52
53function setTransformOrigin(node, value) {
54 var style = node.style;
55 ['Webkit', 'Moz', 'Ms', 'ms'].forEach(function (prefix) {
56 style["".concat(prefix, "TransformOrigin")] = value;
57 });
58 style.transformOrigin = value;
59}
60
61function offset(el) {
62 var rect = el.getBoundingClientRect();
63 var pos = {
64 left: rect.left,
65 top: rect.top
66 };
67 var doc = el.ownerDocument;
68 var w = doc.defaultView || doc.parentWindow;
69 pos.left += getScroll(w);
70 pos.top += getScroll(w, true);
71 return pos;
72}
73
74var Dialog = /*#__PURE__*/function (_React$Component) {
75 (0, _inherits2.default)(Dialog, _React$Component);
76
77 var _super = (0, _createSuper2.default)(Dialog);
78
79 function Dialog(props) {
80 var _this;
81
82 (0, _classCallCheck2.default)(this, Dialog);
83 _this = _super.call(this, props);
84 _this.inTransition = false;
85
86 _this.onAnimateLeave = function () {
87 var _this$props = _this.props,
88 afterClose = _this$props.afterClose,
89 getOpenCount = _this$props.getOpenCount,
90 focusTriggerAfterClose = _this$props.focusTriggerAfterClose,
91 mask = _this$props.mask; // need demo?
92 // https://github.com/react-component/dialog/pull/28
93
94 if (_this.wrap) {
95 _this.wrap.style.display = 'none';
96 }
97
98 _this.inTransition = false; // 如果没有打开的状态,则清除 effect 和 overflow: hidden;
99 // https://github.com/ant-design/ant-design/issues/21539
100
101 if (!getOpenCount()) {
102 _this.switchScrollingEffect();
103 }
104
105 if (mask && _this.lastOutSideFocusNode && focusTriggerAfterClose) {
106 try {
107 _this.lastOutSideFocusNode.focus();
108 } catch (e) {
109 _this.lastOutSideFocusNode = null;
110 }
111
112 _this.lastOutSideFocusNode = null;
113 }
114
115 if (afterClose) {
116 afterClose();
117 }
118 };
119
120 _this.onDialogMouseDown = function () {
121 _this.dialogMouseDown = true;
122 };
123
124 _this.onMaskMouseUp = function () {
125 if (_this.dialogMouseDown) {
126 _this.timeoutId = setTimeout(function () {
127 _this.dialogMouseDown = false;
128 }, 0);
129 }
130 };
131
132 _this.onMaskClick = function (e) {
133 // android trigger click on open (fastclick??)
134 if (Date.now() - _this.openTime < 300) {
135 return;
136 }
137
138 if (e.target === e.currentTarget && !_this.dialogMouseDown) {
139 _this.close(e);
140 }
141 };
142
143 _this.onKeyDown = function (e) {
144 var _this$props2 = _this.props,
145 keyboard = _this$props2.keyboard,
146 visible = _this$props2.visible;
147
148 if (keyboard && e.keyCode === _KeyCode.default.ESC) {
149 e.stopPropagation();
150
151 _this.close(e);
152
153 return;
154 } // keep focus inside dialog
155
156
157 if (visible) {
158 if (e.keyCode === _KeyCode.default.TAB) {
159 var _document = document,
160 activeElement = _document.activeElement;
161
162 if (e.shiftKey) {
163 if (activeElement === _this.sentinelStart) {
164 _this.sentinelEnd.focus();
165 }
166 } else if (activeElement === _this.sentinelEnd) {
167 _this.sentinelStart.focus();
168 }
169 }
170 }
171 };
172
173 _this.getDialogElement = function () {
174 var _this$props3 = _this.props,
175 closable = _this$props3.closable,
176 prefixCls = _this$props3.prefixCls,
177 width = _this$props3.width,
178 height = _this$props3.height,
179 footer = _this$props3.footer,
180 title = _this$props3.title,
181 closeIcon = _this$props3.closeIcon,
182 style = _this$props3.style,
183 className = _this$props3.className,
184 visible = _this$props3.visible,
185 forceRender = _this$props3.forceRender,
186 bodyStyle = _this$props3.bodyStyle,
187 bodyProps = _this$props3.bodyProps,
188 children = _this$props3.children,
189 destroyOnClose = _this$props3.destroyOnClose,
190 modalRender = _this$props3.modalRender;
191 var dest = {};
192
193 if (width !== undefined) {
194 dest.width = width;
195 }
196
197 if (height !== undefined) {
198 dest.height = height;
199 }
200
201 var footerNode;
202
203 if (footer) {
204 footerNode = React.createElement("div", {
205 className: "".concat(prefixCls, "-footer"),
206 ref: _this.saveRef('footer')
207 }, footer);
208 }
209
210 var headerNode;
211
212 if (title) {
213 headerNode = React.createElement("div", {
214 className: "".concat(prefixCls, "-header"),
215 ref: _this.saveRef('header')
216 }, React.createElement("div", {
217 className: "".concat(prefixCls, "-title"),
218 id: _this.titleId
219 }, title));
220 }
221
222 var closer;
223
224 if (closable) {
225 closer = React.createElement("button", {
226 type: "button",
227 onClick: _this.close,
228 "aria-label": "Close",
229 className: "".concat(prefixCls, "-close")
230 }, closeIcon || React.createElement("span", {
231 className: "".concat(prefixCls, "-close-x")
232 }));
233 }
234
235 var content = React.createElement("div", {
236 className: "".concat(prefixCls, "-content")
237 }, closer, headerNode, React.createElement("div", Object.assign({
238 className: "".concat(prefixCls, "-body"),
239 style: bodyStyle,
240 ref: _this.saveRef('body')
241 }, bodyProps), children), footerNode);
242 var styleBox = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, style), dest);
243 var sentinelStyle = {
244 width: 0,
245 height: 0,
246 overflow: 'hidden',
247 outline: 'none'
248 };
249
250 var transitionName = _this.getTransitionName();
251
252 var dialogElement = React.createElement(_LazyRenderBox.default, {
253 key: "dialog-element",
254 role: "document",
255 ref: _this.saveRef('dialog'),
256 style: styleBox,
257 className: "".concat(prefixCls, " ").concat(className || ''),
258 visible: visible,
259 forceRender: forceRender,
260 onMouseDown: _this.onDialogMouseDown
261 }, React.createElement("div", {
262 tabIndex: 0,
263 ref: _this.saveRef('sentinelStart'),
264 style: sentinelStyle,
265 "aria-hidden": "true"
266 }), modalRender ? modalRender(content) : content, React.createElement("div", {
267 tabIndex: 0,
268 ref: _this.saveRef('sentinelEnd'),
269 style: sentinelStyle,
270 "aria-hidden": "true"
271 }));
272 return React.createElement(_rcAnimate.default, {
273 key: "dialog",
274 showProp: "visible",
275 onLeave: _this.onAnimateLeave,
276 transitionName: transitionName,
277 component: "",
278 transitionAppear: true
279 }, visible || !destroyOnClose ? dialogElement : null);
280 };
281
282 _this.getZIndexStyle = function () {
283 var style = {};
284 var zIndex = _this.props.zIndex;
285
286 if (zIndex !== undefined) {
287 style.zIndex = zIndex;
288 }
289
290 return style;
291 };
292
293 _this.getWrapStyle = function () {
294 return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, _this.getZIndexStyle()), _this.props.wrapStyle);
295 };
296
297 _this.getMaskStyle = function () {
298 return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, _this.getZIndexStyle()), _this.props.maskStyle);
299 };
300
301 _this.getMaskElement = function () {
302 var _this$props4 = _this.props,
303 mask = _this$props4.mask,
304 prefixCls = _this$props4.prefixCls,
305 visible = _this$props4.visible,
306 maskProps = _this$props4.maskProps;
307 var maskElement;
308
309 if (mask) {
310 var maskTransition = _this.getMaskTransitionName();
311
312 maskElement = React.createElement(_LazyRenderBox.default, Object.assign({
313 style: _this.getMaskStyle(),
314 key: "mask",
315 className: "".concat(prefixCls, "-mask"),
316 hiddenClassName: "".concat(prefixCls, "-mask-hidden"),
317 visible: visible
318 }, maskProps));
319
320 if (maskTransition) {
321 maskElement = React.createElement(_rcAnimate.default, {
322 key: "mask",
323 showProp: "visible",
324 transitionAppear: true,
325 component: "",
326 transitionName: maskTransition
327 }, maskElement);
328 }
329 }
330
331 return maskElement;
332 };
333
334 _this.getMaskTransitionName = function () {
335 var _this$props5 = _this.props,
336 maskTransitionName = _this$props5.maskTransitionName,
337 maskAnimation = _this$props5.maskAnimation,
338 prefixCls = _this$props5.prefixCls;
339 var transitionName = maskTransitionName;
340 var animation = maskAnimation;
341
342 if (!transitionName && animation) {
343 transitionName = "".concat(prefixCls, "-").concat(animation);
344 }
345
346 return transitionName;
347 };
348
349 _this.getTransitionName = function () {
350 var _this$props6 = _this.props,
351 transitionName = _this$props6.transitionName,
352 animation = _this$props6.animation,
353 prefixCls = _this$props6.prefixCls;
354 var transitionNameResult = transitionName;
355
356 if (!transitionName && animation) {
357 transitionNameResult = "".concat(prefixCls, "-").concat(animation);
358 }
359
360 return transitionNameResult;
361 };
362
363 _this.close = function (e) {
364 var onClose = _this.props.onClose;
365
366 if (onClose) {
367 onClose(e);
368 }
369 };
370
371 _this.saveRef = function (name) {
372 return function (node) {
373 _this[name] = node;
374 };
375 };
376
377 _this.titleId = "rcDialogTitle".concat(uuid);
378 uuid += 1;
379
380 _this.switchScrollingEffect = props.switchScrollingEffect || function () {};
381
382 return _this;
383 }
384
385 (0, _createClass2.default)(Dialog, [{
386 key: "componentDidMount",
387 value: function componentDidMount() {
388 this.componentDidUpdate({}); // if forceRender is true, set element style display to be none;
389
390 if (this.props.forceRender && this.props.visible) {
391 return;
392 }
393
394 if ((this.props.forceRender || this.props.getContainer === false && !this.props.visible) && this.wrap) {
395 this.wrap.style.display = 'none';
396 }
397 }
398 }, {
399 key: "componentDidUpdate",
400 value: function componentDidUpdate(prevProps) {
401 var _this$props7 = this.props,
402 visible = _this$props7.visible,
403 mousePosition = _this$props7.mousePosition;
404
405 if (visible) {
406 // first show
407 if (!prevProps.visible) {
408 this.openTime = Date.now();
409 this.switchScrollingEffect();
410 this.tryFocus(); // eslint-disable-next-line react/no-find-dom-node
411
412 var dialogNode = ReactDOM.findDOMNode(this.dialog);
413
414 if (mousePosition) {
415 var elOffset = offset(dialogNode);
416 setTransformOrigin(dialogNode, "".concat(mousePosition.x - elOffset.left, "px ").concat(mousePosition.y - elOffset.top, "px"));
417 } else {
418 setTransformOrigin(dialogNode, '');
419 }
420 }
421 } else if (prevProps.visible) {
422 this.inTransition = true;
423 }
424 }
425 }, {
426 key: "componentWillUnmount",
427 value: function componentWillUnmount() {
428 var _this$props8 = this.props,
429 visible = _this$props8.visible,
430 getOpenCount = _this$props8.getOpenCount;
431
432 if ((visible || this.inTransition) && !getOpenCount()) {
433 this.switchScrollingEffect();
434 }
435
436 clearTimeout(this.timeoutId);
437 }
438 }, {
439 key: "tryFocus",
440 value: function tryFocus() {
441 if (!(0, _contains.default)(this.wrap, document.activeElement)) {
442 this.lastOutSideFocusNode = document.activeElement;
443 this.sentinelStart.focus();
444 }
445 }
446 }, {
447 key: "render",
448 value: function render() {
449 var props = this.props;
450 var prefixCls = props.prefixCls,
451 maskClosable = props.maskClosable;
452 var style = this.getWrapStyle(); // clear hide display
453 // and only set display after async anim, not here for hide
454
455 if (props.visible) {
456 style.display = null;
457 }
458
459 return React.createElement("div", {
460 className: "".concat(prefixCls, "-root")
461 }, this.getMaskElement(), React.createElement("div", Object.assign({
462 tabIndex: -1,
463 onKeyDown: this.onKeyDown,
464 className: "".concat(prefixCls, "-wrap ").concat(props.wrapClassName || ''),
465 ref: this.saveRef('wrap'),
466 onClick: maskClosable ? this.onMaskClick : null,
467 onMouseUp: maskClosable ? this.onMaskMouseUp : null,
468 role: "dialog",
469 "aria-labelledby": props.title ? this.titleId : null,
470 style: style
471 }, props.wrapProps), this.getDialogElement()));
472 }
473 }]);
474 return Dialog;
475}(React.Component);
476
477exports.default = Dialog;
478Dialog.defaultProps = {
479 className: '',
480 mask: true,
481 visible: false,
482 keyboard: true,
483 closable: true,
484 maskClosable: true,
485 destroyOnClose: false,
486 prefixCls: 'rc-dialog',
487 focusTriggerAfterClose: true
488};
\No newline at end of file