UNPKG

10.6 kBJavaScriptView Raw
1import _extends from 'babel-runtime/helpers/extends';
2import _defineProperty from 'babel-runtime/helpers/defineProperty';
3import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
4import _createClass from 'babel-runtime/helpers/createClass';
5import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
6import _inherits from 'babel-runtime/helpers/inherits';
7var __rest = this && this.__rest || function (s, e) {
8 var t = {};
9 for (var p in s) {
10 if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
11 }if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
12 if (e.indexOf(p[i]) < 0) t[p[i]] = s[p[i]];
13 }return t;
14};
15import React from 'react';
16import ReactDOM from 'react-dom';
17import Gesture from 'rc-gesture';
18import classnames from 'classnames';
19// https://developer.mozilla.org/en-US/docs/Web/API/Element/matches
20// http://caniuse.com/#search=match
21function closest(el, selector) {
22 var matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
23 while (el) {
24 if (matchesSelector.call(el, selector)) {
25 return el;
26 } else {
27 el = el.parentElement;
28 }
29 }
30 return null;
31}
32
33var Swipeout = function (_React$Component) {
34 _inherits(Swipeout, _React$Component);
35
36 function Swipeout(props) {
37 _classCallCheck(this, Swipeout);
38
39 var _this = _possibleConstructorReturn(this, (Swipeout.__proto__ || Object.getPrototypeOf(Swipeout)).call(this, props));
40
41 _this.onCloseSwipe = function (ev) {
42 if (!(_this.openedLeft || _this.openedRight)) {
43 return;
44 }
45 var pNode = closest(ev.target, '.' + _this.props.prefixCls + '-actions');
46 if (!pNode) {
47 ev.preventDefault();
48 _this.close();
49 }
50 };
51 _this.onPanStart = function (e) {
52 var direction = e.direction,
53 moveStatus = e.moveStatus;
54 var deltaX = moveStatus.x;
55 // http://hammerjs.github.io/api/#directions
56
57 var isLeft = direction === 2;
58 var isRight = direction === 4;
59 if (!isLeft && !isRight) {
60 return;
61 }
62 var _this$props = _this.props,
63 left = _this$props.left,
64 right = _this$props.right;
65
66 _this.needShowRight = isLeft && right.length > 0;
67 _this.needShowLeft = isRight && left.length > 0;
68 if (_this.left) {
69 _this.left.style.visibility = _this.needShowRight ? 'hidden' : 'visible';
70 }
71 if (_this.right) {
72 _this.right.style.visibility = _this.needShowLeft ? 'hidden' : 'visible';
73 }
74 if (_this.needShowLeft || _this.needShowRight) {
75 _this.swiping = true;
76 _this.setState({
77 swiping: _this.swiping
78 });
79 _this._setStyle(deltaX);
80 }
81 };
82 _this.onPanMove = function (e) {
83 var moveStatus = e.moveStatus;
84 var deltaX = moveStatus.x;
85
86 if (!_this.swiping) {
87 return;
88 }
89 _this._setStyle(deltaX);
90 };
91 _this.onPanEnd = function (e) {
92 if (!_this.swiping) {
93 return;
94 }
95 var moveStatus = e.moveStatus;
96 var deltaX = moveStatus.x;
97
98 var needOpenRight = _this.needShowRight && Math.abs(deltaX) > _this.btnsRightWidth / 2;
99 var needOpenLeft = _this.needShowLeft && Math.abs(deltaX) > _this.btnsLeftWidth / 2;
100 if (needOpenRight) {
101 _this.doOpenRight();
102 } else if (needOpenLeft) {
103 _this.doOpenLeft();
104 } else {
105 _this.close();
106 }
107 _this.swiping = false;
108 _this.setState({
109 swiping: _this.swiping
110 });
111 _this.needShowLeft = false;
112 _this.needShowRight = false;
113 };
114 _this.doOpenLeft = function () {
115 _this.open(_this.btnsLeftWidth, true, false);
116 };
117 _this.doOpenRight = function () {
118 _this.open(-_this.btnsRightWidth, true, false);
119 };
120 // set content & actions style
121 _this._setStyle = function (value) {
122 var limit = value > 0 ? _this.btnsLeftWidth : -_this.btnsRightWidth;
123 var contentLeft = _this._getContentEasing(value, limit);
124 _this.content.style.left = contentLeft + 'px';
125 if (_this.cover) {
126 _this.cover.style.display = Math.abs(value) > 0 ? 'block' : 'none';
127 _this.cover.style.left = contentLeft + 'px';
128 }
129 };
130 _this.open = function (value, openedLeft, openedRight) {
131 if (!_this.openedLeft && !_this.openedRight && _this.props.onOpen) {
132 _this.props.onOpen();
133 }
134 _this.openedLeft = openedLeft;
135 _this.openedRight = openedRight;
136 _this._setStyle(value);
137 };
138 _this.close = function () {
139 if ((_this.openedLeft || _this.openedRight) && _this.props.onClose) {
140 _this.props.onClose();
141 }
142 _this._setStyle(0);
143 _this.openedLeft = false;
144 _this.openedRight = false;
145 };
146 _this.state = {
147 swiping: false
148 };
149 _this.openedLeft = false;
150 _this.openedRight = false;
151 return _this;
152 }
153
154 _createClass(Swipeout, [{
155 key: 'componentDidMount',
156 value: function componentDidMount() {
157 this.btnsLeftWidth = this.left ? this.left.offsetWidth : 0;
158 this.btnsRightWidth = this.right ? this.right.offsetWidth : 0;
159 document.body.addEventListener('touchstart', this.onCloseSwipe, true);
160 }
161 }, {
162 key: 'componentWillUnmount',
163 value: function componentWillUnmount() {
164 document.body.removeEventListener('touchstart', this.onCloseSwipe, true);
165 }
166 // left & right button click
167
168 }, {
169 key: 'onBtnClick',
170 value: function onBtnClick(ev, btn) {
171 var onPress = btn.onPress;
172 if (onPress) {
173 onPress(ev);
174 }
175 if (this.props.autoClose) {
176 this.close();
177 }
178 }
179 }, {
180 key: '_getContentEasing',
181 value: function _getContentEasing(value, limit) {
182 // limit content style left when value > actions width
183 var delta = Math.abs(value) - Math.abs(limit);
184 var isOverflow = delta > 0;
185 var factor = limit > 0 ? 1 : -1;
186 if (isOverflow) {
187 value = limit + Math.pow(delta, 0.85) * factor;
188 return Math.abs(value) > Math.abs(limit) ? limit : value;
189 }
190 return value;
191 }
192 }, {
193 key: 'renderButtons',
194 value: function renderButtons(buttons, _ref) {
195 var _this2 = this;
196
197 var prefixCls = this.props.prefixCls;
198 return buttons && buttons.length ? React.createElement(
199 'div',
200 { className: prefixCls + '-actions ' + prefixCls + '-actions-' + _ref, ref: function ref(el) {
201 return _this2[_ref] = el;
202 } },
203 buttons.map(function (btn, i) {
204 return React.createElement(
205 'div',
206 { key: i, className: prefixCls + '-btn ' + (btn.hasOwnProperty('className') ? btn.className : ''), style: btn.style, role: 'button', onClick: function onClick(e) {
207 return _this2.onBtnClick(e, btn);
208 } },
209 React.createElement(
210 'div',
211 { className: prefixCls + '-btn-text' },
212 btn.text || 'Click'
213 )
214 );
215 })
216 ) : null;
217 }
218 }, {
219 key: 'render',
220 value: function render() {
221 var _this3 = this;
222
223 var _a = this.props,
224 prefixCls = _a.prefixCls,
225 left = _a.left,
226 right = _a.right,
227 disabled = _a.disabled,
228 children = _a.children,
229 restProps = __rest(_a, ["prefixCls", "left", "right", "disabled", "children"]);
230 var autoClose = restProps.autoClose,
231 onOpen = restProps.onOpen,
232 onClose = restProps.onClose,
233 divProps = __rest(restProps, ["autoClose", "onOpen", "onClose"]);
234
235 var cls = classnames(prefixCls, _defineProperty({}, prefixCls + '-swiping', this.state.swiping));
236 var refProps = {
237 ref: function ref(el) {
238 return _this3.content = ReactDOM.findDOMNode(el);
239 }
240 };
241 return (left.length || right.length) && !disabled ? React.createElement(
242 'div',
243 _extends({ className: cls }, divProps),
244 React.createElement('div', { className: prefixCls + '-cover', ref: function ref(el) {
245 return _this3.cover = el;
246 } }),
247 this.renderButtons(left, 'left'),
248 this.renderButtons(right, 'right'),
249 React.createElement(
250 Gesture,
251 _extends({ onPanStart: this.onPanStart, onPanMove: this.onPanMove, onPanEnd: this.onPanEnd, onPanCancel: this.onPanEnd, onSwipeLeft: this.doOpenRight, onSwipeRight: this.doOpenLeft, direction: 'horizontal' }, refProps),
252 React.createElement(
253 'div',
254 { className: prefixCls + '-content' },
255 children
256 )
257 )
258 ) : React.createElement(
259 'div',
260 _extends({}, refProps, divProps),
261 children
262 );
263 }
264 }]);
265
266 return Swipeout;
267}(React.Component);
268
269export default Swipeout;
270
271Swipeout.defaultProps = {
272 prefixCls: 'rc-swipeout',
273 autoClose: false,
274 disabled: false,
275 left: [],
276 right: [],
277 onOpen: function onOpen() {},
278 onClose: function onClose() {}
279};
\No newline at end of file