react-view-router
Version:
react-view-router
209 lines • 8.07 kB
JavaScript
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
import React from 'react';
import ReactDOM from 'react-dom';
import Animate from 'rc-animate';
import { Swipeable } from 'react-swipeable';
import { CAN_USE_DOM } from '../..';
class Drawer extends React.Component {
constructor(props) {
super(props);
_defineProperty(this, "closed", void 0);
_defineProperty(this, "isTouching", void 0);
_defineProperty(this, "drawerRef", void 0);
_defineProperty(this, "container", void 0);
this.closed = false;
this.isTouching = null;
this.container = null;
this.drawerRef = null;
this.getContainer = this.getContainer.bind(this);
this.removeContainer = this.removeContainer.bind(this);
this.onAnimateAppear = this.onAnimateAppear.bind(this);
this.onAnimateLeave = this.onAnimateLeave.bind(this);
this.onTouchMove = this.onTouchMove.bind(this);
this.onTouchEnd = this.onTouchEnd.bind(this);
this.close = this.close.bind(this);
this.onMaskClick = this.onMaskClick.bind(this);
}
componentWillUnmount() {
this.restoreOverflow();
this.removeContainer();
}
onTouchMove(event) {
if (!this.drawerRef) return;
if (this.isTouching === null) {
this.isTouching = event.dir === 'Right';
if (!this.isTouching) return;
}
if (this.isTouching === false) return;
const drawerRef = this.drawerRef;
let deltaX = Math.max(-event.deltaX, 0);
drawerRef.style.webkitTransform = drawerRef.style.transform = `translateX(${deltaX}px)`;
}
onTouchEnd(event) {
if (this.isTouching && -event.deltaX > this.props.touchThreshold) {
const drawerRef = this.drawerRef;
if (!drawerRef) return;
const viewLength = drawerRef.getBoundingClientRect().width;
drawerRef.classList.add('touched');
let close = null;
let actionClass = '';
if (-event.deltaX > viewLength / 2) {
actionClass = 'touch-hide';
close = () => {
this.closed = true;
this.close();
};
} else actionClass = 'touch-restore';
drawerRef.style.webkitTransform = drawerRef.style.transform = '';
if (actionClass) drawerRef.classList.add(actionClass);
setTimeout(() => {
close && close();
drawerRef.classList.remove(actionClass);
drawerRef.classList.remove('touched');
}, this.props.delay);
}
this.isTouching = null;
}
removeContainer() {
if (!this.container) return;
if (this.container.parentNode) this.container.parentNode.removeChild(this.container);
this.container = null;
}
getContainer() {
if (!this.container) {
const container = document.createElement('div');
const containerId = `${this.props.prefixCls}-container-${new Date().getTime()}`;
container.setAttribute('id', containerId);
document.body.appendChild(container);
this.container = container;
}
return this.container;
}
getZIndexStyle() {
const style = {};
if (this.props.zIndex !== undefined) style.zIndex = this.props.zIndex;
return style;
}
getWrapStyle() {
const wrapStyle = this.props.wrapStyle || {};
return _objectSpread(_objectSpread({}, this.getZIndexStyle()), wrapStyle);
}
getMaskStyle() {
const maskStyle = this.props.maskStyle || {};
return _objectSpread(_objectSpread({}, this.getZIndexStyle()), maskStyle);
}
getMaskTransitionName() {
if (this.closed) return '';
const props = this.props;
let transitionName = props.maskTransitionName;
const animation = props.maskAnimation;
if (!transitionName && animation) {
transitionName = `${props.prefixCls}-${animation}`;
}
return transitionName;
}
getTransitionName() {
if (this.closed) return '';
const props = this.props;
let transitionName = props.transitionName;
const animation = props.animation;
if (!transitionName && animation) {
transitionName = `${props.prefixCls}-${animation}`;
}
return transitionName;
}
getDrawerElement() {
const props = this.props;
const prefixCls = props.prefixCls;
let dialogElement = /*#__PURE__*/React.createElement('div', {
key: 'drawer-element',
role: 'document',
ref: el => this.drawerRef = el,
style: props.style || {},
className: `${prefixCls} ${props.className || ''}`,
open: props.open
}, props.children);
const transitionName = this.getTransitionName();
if (transitionName) {
dialogElement = /*#__PURE__*/React.createElement(Animate, {
key: 'drawer',
showProp: 'open',
onAppear: this.onAnimateAppear,
onLeave: this.onAnimateLeave,
transitionName,
component: '',
transitionAppear: true
}, dialogElement);
}
if (this.props.touch) {
dialogElement = /*#__PURE__*/React.createElement(Swipeable, {
className: `${props.prefixCls}-wrap`,
onSwiping: this.onTouchMove,
onSwiped: this.onTouchEnd
}, dialogElement);
}
return dialogElement;
}
restoreOverflow() {
if (document.body.style.overflow) document.body.style.overflow = '';
}
onAnimateAppear() {
document.body.style.overflow = 'hidden';
if (this.props.onAnimateStart) this.props.onAnimateStart();
}
onAnimateLeave() {
this.restoreOverflow();
if (this.props.onAnimateLeave) this.props.onAnimateLeave();
if (this.props.afterClose) this.props.afterClose();
}
close(e) {
if (this.props.onClose) this.props.onClose(e);
}
onMaskClick(e) {
if (!this.props.maskClosable) return;
if (e.target === e.currentTarget) this.close(e);
}
render() {
if (!CAN_USE_DOM) return null;
const props = this.props;
if (props.open) this.closed = false;
let drawer = this.getDrawerElement();
if (props.mask) {
drawer = /*#__PURE__*/React.createElement('div', _objectSpread(_objectSpread({
style: this.getMaskStyle(),
key: 'mask-element',
className: `${props.prefixCls}-mask ${props.open ? `${props.prefixCls}-mask-hidden` : ''}`,
open: props.open
}, props.maskProps), {}, {
onClick: this.onMaskClick
}), drawer);
const transitionName = this.getMaskTransitionName();
if (transitionName) {
drawer = /*#__PURE__*/React.createElement(Animate, {
key: 'mask',
showProp: 'open',
transitionAppear: true,
component: '',
transitionName
}, drawer);
}
}
return /*#__PURE__*/ReactDOM.createPortal(drawer, this.getContainer());
}
}
_defineProperty(Drawer, "defaultProps", void 0);
Drawer.defaultProps = {
prefixCls: 'rvr-drawer',
className: '',
mask: true,
open: false,
maskClosable: false,
touch: true,
touchThreshold: 10,
delay: 400
};
export default Drawer;