diff --git a/assets/index.less b/assets/index.less index e2b4ec1..b170447 100644 --- a/assets/index.less +++ b/assets/index.less @@ -1,5 +1,8 @@ @swipeout-prefix-cls: rc-swipeout; +html { + overflow: hidden; +} .@{swipeout-prefix-cls} { overflow: hidden; position: relative; diff --git a/examples/simple.tsx b/examples/simple.tsx index 4055f44..03a697c 100644 --- a/examples/simple.tsx +++ b/examples/simple.tsx @@ -5,45 +5,64 @@ import Swipeout from '../src'; import React from 'react'; import ReactDOM from 'react-dom'; +const SwipeDemo = () => ( + console.log('more more'), + style: { backgroundColor: 'orange', color: 'white' }, + }, + { text: 'delete', + onPress: () => console.log('delete'), + style: { backgroundColor: 'red', color: 'white' }, + }, + ]} + left={[ + { + text: 'read', + onPress: () => console.log('read'), + style: { backgroundColor: 'blue', color: 'white' }, + }, + { + text: 'reply me', + onPress: () => console.log('reply me'), + style: { backgroundColor: 'green', color: 'white' }, + }, + { + text: 'reply other people', + onPress: () => console.log('reply other people'), + style: { backgroundColor: 'gray', color: 'white' }, + }, + ]} + onOpen={() => console.log('open')} + onClose={() => console.log('close')} + > +
swipe out simple demo
+
+); + ReactDOM.render(
- console.log('more'), - style: { backgroundColor: 'orange', color: 'white' }, - }, - { text: 'delete', - onPress: () => console.log('delete'), - style: { backgroundColor: 'red', color: 'white' }, - }, - ]} - left={[ - { - text: 'read', - onPress: () => console.log('read'), - style: { backgroundColor: 'blue', color: 'white' }, - }, - { - text: 'reply', - onPress: () => console.log('reply'), - style: { backgroundColor: 'green', color: 'white' }, - }, - ]} - onOpen={() => console.log('open')} - onClose={() => console.log('close')} - > -
swipe out simple demo
-
+ + + + + + + + + + +
, document.getElementById('__react-content'), ); diff --git a/src/Swipeout.tsx b/src/Swipeout.tsx index 6f24b74..03de9c4 100644 --- a/src/Swipeout.tsx +++ b/src/Swipeout.tsx @@ -23,18 +23,13 @@ class Swipeout extends React.Component { right: any; btnsLeftWidth: number; btnsRightWidth: number; - panStartX: number; - panStartY: number; swiping: boolean; + needShowLeft: boolean; + needShowRight: boolean; constructor(props) { super(props); - this.onPanStart = this.onPanStart.bind(this); - this.onPan = this.onPan.bind(this); - this.onPanEnd = this.onPanEnd.bind(this); - this.onCloseSwipe = this.onCloseSwipe.bind(this); - this.openedLeft = false; this.openedRight = false; } @@ -49,7 +44,7 @@ class Swipeout extends React.Component { document.body.removeEventListener('touchstart', this.onCloseSwipe, true); } - onCloseSwipe(ev) { + onCloseSwipe = (ev) => { if (this.openedLeft || this.openedRight) { const pNode = (node => { while (node.parentNode && node.parentNode !== document.body) { @@ -66,49 +61,64 @@ class Swipeout extends React.Component { } } - onPanStart(e) { - this.panStartX = e.deltaX; - this.panStartY = e.deltaY; - } - - onPan(e) { - const posX = e.deltaX - this.panStartX; - const posY = e.deltaY - this.panStartY; + onPanStart = (e) => { + const { direction, deltaX } = e; + // http://hammerjs.github.io/api/#directions + const isLeft = direction === 2; + const isRight = direction === 4; - if (Math.abs(posX) <= Math.abs(posY)) { + if (!isLeft && !isRight) { return; } - const { left, right } = this.props; - if (posX < 0 && right!.length) { - this.swiping = true; - this._setStyle(Math.min(posX, 0)); - } else if (posX > 0 && left!.length) { + this.needShowRight = isLeft && right!.length > 0; + this.needShowLeft = isRight && left!.length > 0; + if (this.left) { + this.left.style.visibility = this.needShowRight ? 'hidden' : 'visible'; + } + if (this.right) { + this.right.style.visibility = this.needShowLeft ? 'hidden' : 'visible'; + } + if (this.needShowLeft || this.needShowRight) { this.swiping = true; - this._setStyle(Math.max(posX, 0)); + this._setStyle(deltaX); + } + } + onPan = (e) => { + const { deltaX } = e; + if (!this.swiping) { + return; } + this._setStyle(deltaX); } - onPanEnd(e) { + onPanEnd = (e) => { if (!this.swiping) { return; } - this.swiping = false; const { left = [], right = [] } = this.props; const btnsLeftWidth = this.btnsLeftWidth; const btnsRightWidth = this.btnsRightWidth; - const posX = e.deltaX - this.panStartX; - const openLeft = posX > btnsLeftWidth / 2; - const openRight = posX < -btnsRightWidth / 2; - if (openRight && posX < 0 && right.length) { + const { direction, deltaX } = e; + // http://hammerjs.github.io/api/#directions + const isLeft = direction === 2; + const isRight = direction === 4; + + const needOpenRight = this.needShowRight && Math.abs(deltaX) > btnsRightWidth / 2; + const needOpenLeft = this.needShowLeft && Math.abs(deltaX) > btnsRightWidth / 2; + + if (needOpenRight) { this.open(-btnsRightWidth, false, true); - } else if (openLeft && posX > 0 && left.length) { + } else if (needOpenLeft) { this.open(btnsLeftWidth, true, false); } else { this.close(); } + this.swiping = false; + this.needShowLeft = false; + this.needShowRight = false; } // left & right button click @@ -124,16 +134,19 @@ class Swipeout extends React.Component { _getContentEasing(value, limit) { // limit content style left when value > actions width - if (value < 0 && value < limit) { - return limit - Math.pow(limit - value, 0.85); - } else if (value > 0 && value > limit) { - return limit + Math.pow(value - limit, 0.85); + const delta = Math.abs(value) - Math.abs(limit); + const isOverflow = delta > 0; + const factor = limit > 0 ? 1 : -1; + if (isOverflow) { + value = limit + Math.pow(delta, 0.85) * factor; + return Math.abs(value) > Math.abs(limit) ? limit : value; } return value; } // set content & actions style - _setStyle(value) { + _setStyle = (value) => { + const limit = value > 0 ? this.btnsLeftWidth : -this.btnsRightWidth; const contentLeft = this._getContentEasing(value, limit); this.content.style.left = `${contentLeft}px`; @@ -143,7 +156,7 @@ class Swipeout extends React.Component { } } - open(value, openedLeft, openedRight) { + open = (value, openedLeft, openedRight) => { if (!this.openedLeft && !this.openedRight && this.props.onOpen) { this.props.onOpen(); } @@ -153,7 +166,7 @@ class Swipeout extends React.Component { this._setStyle(value); } - close() { + close = () => { if ((this.openedLeft || this.openedRight) && this.props.onClose) { this.props.onClose(); } @@ -213,7 +226,7 @@ class Swipeout extends React.Component { >
{children}
- + ) : (
{children}
);