UNPKG

20.5 kBJavaScriptView Raw
1import _extends from "@babel/runtime/helpers/esm/extends";
2import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
3import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
4import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
5import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
6import _createClass from "@babel/runtime/helpers/esm/createClass";
7import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized";
8import _inherits from "@babel/runtime/helpers/esm/inherits";
9import _createSuper from "@babel/runtime/helpers/esm/createSuper";
10var _excluded = ["className", "children", "style", "width", "height", "defaultOpen", "open", "prefixCls", "placement", "level", "levelMove", "ease", "duration", "getContainer", "handler", "onChange", "afterVisibleChange", "showMask", "maskClosable", "maskStyle", "onClose", "onHandleClick", "keyboard", "getOpenCount", "scrollLocker", "contentWrapperStyle"];
11import * as React from 'react';
12import classnames from 'classnames';
13import getScrollBarSize from "rc-util/es/getScrollBarSize";
14import KeyCode from "rc-util/es/KeyCode";
15import omit from "rc-util/es/omit";
16import { addEventListener, dataToArray, getTouchParentScroll, isNumeric, removeEventListener, transformArguments, transitionEnd, transitionStr, windowIsUndefined } from './utils';
17var currentDrawer = {};
18
19var DrawerChild = /*#__PURE__*/function (_React$Component) {
20 _inherits(DrawerChild, _React$Component);
21
22 var _super = _createSuper(DrawerChild);
23
24 function DrawerChild(props) {
25 var _this;
26
27 _classCallCheck(this, DrawerChild);
28
29 _this = _super.call(this, props);
30 _this.levelDom = void 0;
31 _this.dom = void 0;
32 _this.contentWrapper = void 0;
33 _this.contentDom = void 0;
34 _this.maskDom = void 0;
35 _this.handlerDom = void 0;
36 _this.drawerId = void 0;
37 _this.timeout = void 0;
38 _this.passive = void 0;
39 _this.startPos = void 0;
40
41 _this.domFocus = function () {
42 if (_this.dom) {
43 _this.dom.focus();
44 }
45 };
46
47 _this.removeStartHandler = function (e) {
48 if (e.touches.length > 1) {
49 // need clear the startPos when another touch event happens
50 _this.startPos = null;
51 return;
52 }
53
54 _this.startPos = {
55 x: e.touches[0].clientX,
56 y: e.touches[0].clientY
57 };
58 };
59
60 _this.removeMoveHandler = function (e) {
61 // the startPos may be null or undefined
62 if (e.changedTouches.length > 1 || !_this.startPos) {
63 return;
64 }
65
66 var currentTarget = e.currentTarget;
67 var differX = e.changedTouches[0].clientX - _this.startPos.x;
68 var differY = e.changedTouches[0].clientY - _this.startPos.y;
69
70 if ((currentTarget === _this.maskDom || currentTarget === _this.handlerDom || currentTarget === _this.contentDom && getTouchParentScroll(currentTarget, e.target, differX, differY)) && e.cancelable) {
71 e.preventDefault();
72 }
73 };
74
75 _this.transitionEnd = function (e) {
76 var dom = e.target;
77 removeEventListener(dom, transitionEnd, _this.transitionEnd);
78 dom.style.transition = '';
79 };
80
81 _this.onKeyDown = function (e) {
82 if (e.keyCode === KeyCode.ESC) {
83 var onClose = _this.props.onClose;
84 e.stopPropagation();
85
86 if (onClose) {
87 onClose(e);
88 }
89 }
90 };
91
92 _this.onWrapperTransitionEnd = function (e) {
93 var _this$props = _this.props,
94 open = _this$props.open,
95 afterVisibleChange = _this$props.afterVisibleChange;
96
97 if (e.target === _this.contentWrapper && e.propertyName.match(/transform$/)) {
98 _this.dom.style.transition = '';
99
100 if (!open && _this.getCurrentDrawerSome()) {
101 document.body.style.overflowX = '';
102
103 if (_this.maskDom) {
104 _this.maskDom.style.left = '';
105 _this.maskDom.style.width = '';
106 }
107 }
108
109 if (afterVisibleChange) {
110 afterVisibleChange(!!open);
111 }
112 }
113 };
114
115 _this.openLevelTransition = function () {
116 var _this$props2 = _this.props,
117 open = _this$props2.open,
118 width = _this$props2.width,
119 height = _this$props2.height;
120
121 var _this$getHorizontalBo = _this.getHorizontalBoolAndPlacementName(),
122 isHorizontal = _this$getHorizontalBo.isHorizontal,
123 placementName = _this$getHorizontalBo.placementName;
124
125 var contentValue = _this.contentDom ? _this.contentDom.getBoundingClientRect()[isHorizontal ? 'width' : 'height'] : 0;
126 var value = (isHorizontal ? width : height) || contentValue;
127
128 _this.setLevelAndScrolling(open, placementName, value);
129 };
130
131 _this.setLevelTransform = function (open, placementName, value, right) {
132 var _this$props3 = _this.props,
133 placement = _this$props3.placement,
134 levelMove = _this$props3.levelMove,
135 duration = _this$props3.duration,
136 ease = _this$props3.ease,
137 showMask = _this$props3.showMask; // router 切换时可能会导至页面失去滚动条,所以需要时时获取。
138
139 _this.levelDom.forEach(function (dom) {
140 dom.style.transition = "transform ".concat(duration, " ").concat(ease);
141 addEventListener(dom, transitionEnd, _this.transitionEnd);
142 var levelValue = open ? value : 0;
143
144 if (levelMove) {
145 var $levelMove = transformArguments(levelMove, {
146 target: dom,
147 open: open
148 });
149 levelValue = open ? $levelMove[0] : $levelMove[1] || 0;
150 }
151
152 var $value = typeof levelValue === 'number' ? "".concat(levelValue, "px") : levelValue;
153 var placementPos = placement === 'left' || placement === 'top' ? $value : "-".concat($value);
154 placementPos = showMask && placement === 'right' && right ? "calc(".concat(placementPos, " + ").concat(right, "px)") : placementPos;
155 dom.style.transform = levelValue ? "".concat(placementName, "(").concat(placementPos, ")") : '';
156 });
157 };
158
159 _this.setLevelAndScrolling = function (open, placementName, value) {
160 var onChange = _this.props.onChange;
161
162 if (!windowIsUndefined) {
163 var right = document.body.scrollHeight > (window.innerHeight || document.documentElement.clientHeight) && window.innerWidth > document.body.offsetWidth ? getScrollBarSize(true) : 0;
164
165 _this.setLevelTransform(open, placementName, value, right);
166
167 _this.toggleScrollingToDrawerAndBody(right);
168 }
169
170 if (onChange) {
171 onChange(open);
172 }
173 };
174
175 _this.toggleScrollingToDrawerAndBody = function (right) {
176 var _this$props4 = _this.props,
177 getContainer = _this$props4.getContainer,
178 showMask = _this$props4.showMask,
179 open = _this$props4.open;
180 var container = getContainer && getContainer(); // 处理 body 滚动
181
182 if (container && container.parentNode === document.body && showMask) {
183 var eventArray = ['touchstart'];
184 var domArray = [document.body, _this.maskDom, _this.handlerDom, _this.contentDom];
185
186 if (open && document.body.style.overflow !== 'hidden') {
187 if (right) {
188 _this.addScrollingEffect(right);
189 }
190
191 document.body.style.touchAction = 'none'; // 手机禁滚
192
193 domArray.forEach(function (item, i) {
194 if (!item) {
195 return;
196 }
197
198 addEventListener(item, eventArray[i] || 'touchmove', i ? _this.removeMoveHandler : _this.removeStartHandler, _this.passive);
199 });
200 } else if (_this.getCurrentDrawerSome()) {
201 document.body.style.touchAction = '';
202
203 if (right) {
204 _this.remScrollingEffect(right);
205 } // 恢复事件
206
207
208 domArray.forEach(function (item, i) {
209 if (!item) {
210 return;
211 }
212
213 removeEventListener(item, eventArray[i] || 'touchmove', i ? _this.removeMoveHandler : _this.removeStartHandler, _this.passive);
214 });
215 }
216 }
217 };
218
219 _this.addScrollingEffect = function (right) {
220 var _this$props5 = _this.props,
221 placement = _this$props5.placement,
222 duration = _this$props5.duration,
223 ease = _this$props5.ease;
224 var widthTransition = "width ".concat(duration, " ").concat(ease);
225 var transformTransition = "transform ".concat(duration, " ").concat(ease);
226 _this.dom.style.transition = 'none';
227
228 switch (placement) {
229 case 'right':
230 _this.dom.style.transform = "translateX(-".concat(right, "px)");
231 break;
232
233 case 'top':
234 case 'bottom':
235 _this.dom.style.width = "calc(100% - ".concat(right, "px)");
236 _this.dom.style.transform = 'translateZ(0)';
237 break;
238
239 default:
240 break;
241 }
242
243 clearTimeout(_this.timeout);
244 _this.timeout = setTimeout(function () {
245 if (_this.dom) {
246 _this.dom.style.transition = "".concat(transformTransition, ",").concat(widthTransition);
247 _this.dom.style.width = '';
248 _this.dom.style.transform = '';
249 }
250 });
251 };
252
253 _this.remScrollingEffect = function (right) {
254 var _this$props6 = _this.props,
255 placement = _this$props6.placement,
256 duration = _this$props6.duration,
257 ease = _this$props6.ease;
258
259 if (transitionStr) {
260 document.body.style.overflowX = 'hidden';
261 }
262
263 _this.dom.style.transition = 'none';
264 var heightTransition;
265 var widthTransition = "width ".concat(duration, " ").concat(ease);
266 var transformTransition = "transform ".concat(duration, " ").concat(ease);
267
268 switch (placement) {
269 case 'left':
270 {
271 _this.dom.style.width = '100%';
272 widthTransition = "width 0s ".concat(ease, " ").concat(duration);
273 break;
274 }
275
276 case 'right':
277 {
278 _this.dom.style.transform = "translateX(".concat(right, "px)");
279 _this.dom.style.width = '100%';
280 widthTransition = "width 0s ".concat(ease, " ").concat(duration);
281
282 if (_this.maskDom) {
283 _this.maskDom.style.left = "-".concat(right, "px");
284 _this.maskDom.style.width = "calc(100% + ".concat(right, "px)");
285 }
286
287 break;
288 }
289
290 case 'top':
291 case 'bottom':
292 {
293 _this.dom.style.width = "calc(100% + ".concat(right, "px)");
294 _this.dom.style.height = '100%';
295 _this.dom.style.transform = 'translateZ(0)';
296 heightTransition = "height 0s ".concat(ease, " ").concat(duration);
297 break;
298 }
299
300 default:
301 break;
302 }
303
304 clearTimeout(_this.timeout);
305 _this.timeout = setTimeout(function () {
306 if (_this.dom) {
307 _this.dom.style.transition = "".concat(transformTransition, ",").concat(heightTransition ? "".concat(heightTransition, ",") : '').concat(widthTransition);
308 _this.dom.style.transform = '';
309 _this.dom.style.width = '';
310 _this.dom.style.height = '';
311 }
312 });
313 };
314
315 _this.getCurrentDrawerSome = function () {
316 return !Object.keys(currentDrawer).some(function (key) {
317 return currentDrawer[key];
318 });
319 };
320
321 _this.getLevelDom = function (_ref) {
322 var level = _ref.level,
323 getContainer = _ref.getContainer;
324
325 if (windowIsUndefined) {
326 return;
327 }
328
329 var container = getContainer && getContainer();
330 var parent = container ? container.parentNode : null;
331 _this.levelDom = [];
332
333 if (level === 'all') {
334 var children = parent ? Array.prototype.slice.call(parent.children) : [];
335 children.forEach(function (child) {
336 if (child.nodeName !== 'SCRIPT' && child.nodeName !== 'STYLE' && child.nodeName !== 'LINK' && child !== container) {
337 _this.levelDom.push(child);
338 }
339 });
340 } else if (level) {
341 dataToArray(level).forEach(function (key) {
342 document.querySelectorAll(key).forEach(function (item) {
343 _this.levelDom.push(item);
344 });
345 });
346 }
347 };
348
349 _this.getHorizontalBoolAndPlacementName = function () {
350 var placement = _this.props.placement;
351 var isHorizontal = placement === 'left' || placement === 'right';
352 var placementName = "translate".concat(isHorizontal ? 'X' : 'Y');
353 return {
354 isHorizontal: isHorizontal,
355 placementName: placementName
356 };
357 };
358
359 _this.state = {
360 _self: _assertThisInitialized(_this)
361 };
362 return _this;
363 }
364
365 _createClass(DrawerChild, [{
366 key: "componentDidMount",
367 value: function componentDidMount() {
368 var _this2 = this;
369
370 if (!windowIsUndefined) {
371 var passiveSupported = false;
372
373 try {
374 window.addEventListener('test', null, Object.defineProperty({}, 'passive', {
375 get: function get() {
376 passiveSupported = true;
377 return null;
378 }
379 }));
380 } catch (err) {}
381
382 this.passive = passiveSupported ? {
383 passive: false
384 } : false;
385 }
386
387 var _this$props7 = this.props,
388 open = _this$props7.open,
389 getContainer = _this$props7.getContainer,
390 showMask = _this$props7.showMask,
391 autoFocus = _this$props7.autoFocus;
392 var container = getContainer && getContainer();
393 this.drawerId = "drawer_id_".concat(Number((Date.now() + Math.random()).toString().replace('.', Math.round(Math.random() * 9).toString())).toString(16));
394 this.getLevelDom(this.props);
395
396 if (open) {
397 if (container && container.parentNode === document.body) {
398 currentDrawer[this.drawerId] = open;
399 } // 默认打开状态时推出 level;
400
401
402 this.openLevelTransition();
403 this.forceUpdate(function () {
404 if (autoFocus) {
405 _this2.domFocus();
406 }
407 });
408
409 if (showMask) {
410 var _this$props$scrollLoc;
411
412 (_this$props$scrollLoc = this.props.scrollLocker) === null || _this$props$scrollLoc === void 0 ? void 0 : _this$props$scrollLoc.lock();
413 }
414 }
415 }
416 }, {
417 key: "componentDidUpdate",
418 value: function componentDidUpdate(prevProps) {
419 var _this$props8 = this.props,
420 open = _this$props8.open,
421 getContainer = _this$props8.getContainer,
422 scrollLocker = _this$props8.scrollLocker,
423 showMask = _this$props8.showMask,
424 autoFocus = _this$props8.autoFocus;
425 var container = getContainer && getContainer();
426
427 if (open !== prevProps.open) {
428 if (container && container.parentNode === document.body) {
429 currentDrawer[this.drawerId] = !!open;
430 }
431
432 this.openLevelTransition();
433
434 if (open) {
435 if (autoFocus) {
436 this.domFocus();
437 }
438
439 if (showMask) {
440 scrollLocker === null || scrollLocker === void 0 ? void 0 : scrollLocker.lock();
441 }
442 } else {
443 scrollLocker === null || scrollLocker === void 0 ? void 0 : scrollLocker.unLock();
444 }
445 }
446 }
447 }, {
448 key: "componentWillUnmount",
449 value: function componentWillUnmount() {
450 var _this$props9 = this.props,
451 open = _this$props9.open,
452 scrollLocker = _this$props9.scrollLocker;
453 delete currentDrawer[this.drawerId];
454
455 if (open) {
456 this.setLevelTransform(false);
457 document.body.style.touchAction = '';
458 }
459
460 scrollLocker === null || scrollLocker === void 0 ? void 0 : scrollLocker.unLock();
461 }
462 }, {
463 key: "render",
464 value: // tslint:disable-next-line:member-ordering
465 function render() {
466 var _classnames,
467 _this3 = this;
468
469 var _this$props10 = this.props,
470 className = _this$props10.className,
471 children = _this$props10.children,
472 style = _this$props10.style,
473 width = _this$props10.width,
474 height = _this$props10.height,
475 defaultOpen = _this$props10.defaultOpen,
476 $open = _this$props10.open,
477 prefixCls = _this$props10.prefixCls,
478 placement = _this$props10.placement,
479 level = _this$props10.level,
480 levelMove = _this$props10.levelMove,
481 ease = _this$props10.ease,
482 duration = _this$props10.duration,
483 getContainer = _this$props10.getContainer,
484 handler = _this$props10.handler,
485 onChange = _this$props10.onChange,
486 afterVisibleChange = _this$props10.afterVisibleChange,
487 showMask = _this$props10.showMask,
488 maskClosable = _this$props10.maskClosable,
489 maskStyle = _this$props10.maskStyle,
490 onClose = _this$props10.onClose,
491 onHandleClick = _this$props10.onHandleClick,
492 keyboard = _this$props10.keyboard,
493 getOpenCount = _this$props10.getOpenCount,
494 scrollLocker = _this$props10.scrollLocker,
495 contentWrapperStyle = _this$props10.contentWrapperStyle,
496 props = _objectWithoutProperties(_this$props10, _excluded); // 首次渲染都将是关闭状态。
497
498
499 var open = this.dom ? $open : false;
500 var wrapperClassName = classnames(prefixCls, (_classnames = {}, _defineProperty(_classnames, "".concat(prefixCls, "-").concat(placement), true), _defineProperty(_classnames, "".concat(prefixCls, "-open"), open), _defineProperty(_classnames, className || '', !!className), _defineProperty(_classnames, 'no-mask', !showMask), _classnames));
501
502 var _this$getHorizontalBo2 = this.getHorizontalBoolAndPlacementName(),
503 placementName = _this$getHorizontalBo2.placementName; // 百分比与像素动画不同步,第一次打用后全用像素动画。
504 // const defaultValue = !this.contentDom || !level ? '100%' : `${value}px`;
505
506
507 var placementPos = placement === 'left' || placement === 'top' ? '-100%' : '100%';
508 var transform = open ? '' : "".concat(placementName, "(").concat(placementPos, ")");
509 var handlerChildren = handler && /*#__PURE__*/React.cloneElement(handler, {
510 onClick: function onClick(e) {
511 if (handler.props.onClick) {
512 handler.props.onClick();
513 }
514
515 if (onHandleClick) {
516 onHandleClick(e);
517 }
518 },
519 ref: function ref(c) {
520 _this3.handlerDom = c;
521 }
522 });
523 return /*#__PURE__*/React.createElement("div", _extends({}, omit(props, ['switchScrollingEffect', 'autoFocus']), {
524 tabIndex: -1,
525 className: wrapperClassName,
526 style: style,
527 ref: function ref(c) {
528 _this3.dom = c;
529 },
530 onKeyDown: open && keyboard ? this.onKeyDown : undefined,
531 onTransitionEnd: this.onWrapperTransitionEnd
532 }), showMask && /*#__PURE__*/React.createElement("div", {
533 className: "".concat(prefixCls, "-mask"),
534 onClick: maskClosable ? onClose : undefined,
535 style: maskStyle,
536 ref: function ref(c) {
537 _this3.maskDom = c;
538 }
539 }), /*#__PURE__*/React.createElement("div", {
540 className: "".concat(prefixCls, "-content-wrapper"),
541 style: _objectSpread({
542 transform: transform,
543 msTransform: transform,
544 width: isNumeric(width) ? "".concat(width, "px") : width,
545 height: isNumeric(height) ? "".concat(height, "px") : height
546 }, contentWrapperStyle),
547 ref: function ref(c) {
548 _this3.contentWrapper = c;
549 }
550 }, /*#__PURE__*/React.createElement("div", {
551 className: "".concat(prefixCls, "-content"),
552 ref: function ref(c) {
553 _this3.contentDom = c;
554 }
555 }, children), handlerChildren));
556 }
557 }], [{
558 key: "getDerivedStateFromProps",
559 value: function getDerivedStateFromProps(props, _ref2) {
560 var prevProps = _ref2.prevProps,
561 _self = _ref2._self;
562 var nextState = {
563 prevProps: props
564 };
565
566 if (prevProps !== undefined) {
567 var placement = props.placement,
568 level = props.level;
569
570 if (placement !== prevProps.placement) {
571 // test 的 bug, 有动画过场,删除 dom
572 _self.contentDom = null;
573 }
574
575 if (level !== prevProps.level) {
576 _self.getLevelDom(props);
577 }
578 }
579
580 return nextState;
581 }
582 }]);
583
584 return DrawerChild;
585}(React.Component);
586
587export default DrawerChild;
\No newline at end of file