From 3df19285ba116d5f7dbc442d49793c68168d9cca Mon Sep 17 00:00:00 2001 From: Sergey Kozel Date: Wed, 12 Dec 2018 17:04:26 +0300 Subject: [PATCH 1/2] add automatic buttons opening possibility --- src/index.js | 66 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 60 insertions(+), 6 deletions(-) diff --git a/src/index.js b/src/index.js index d77cf98..26c25f7 100644 --- a/src/index.js +++ b/src/index.js @@ -154,6 +154,12 @@ export default class Swipeable extends PureComponent { swipeStartMinDistance: 15 }; + static AutoSwipeType = Object.freeze({ + Recenter: 'recenter', + OpenRightButtons: 'open-right-buttons', + OpenLeftButtons: 'open-left-buttons' + }); + state = { pan: new Animated.ValueXY(), width: 0, @@ -177,26 +183,58 @@ export default class Swipeable extends PureComponent { this._unmounted = true; } + openLeftButtons = ( + animationFn, + animationConfig, + onDone + ) => { + this._autoSwipe(Swipeable.AutoSwipeType.OpenLeftButtons, animationFn, animationConfig, onDone); + }; + + openRightButtons = ( + animationFn, + animationConfig, + onDone + ) => { + this._autoSwipe(Swipeable.AutoSwipeType.OpenRightButtons, animationFn, animationConfig, onDone); + }; + recenter = ( animationFn = this.props.swipeReleaseAnimationFn, animationConfig = this.props.swipeReleaseAnimationConfig, onDone + ) => { + this._autoSwipe(Swipeable.AutoSwipeType.Recenter, animationFn, animationConfig, onDone); + }; + + _autoSwipe = ( + type, + animationFn, + animationConfig, + onDone ) => { const {pan} = this.state; + const finalAnimationFn = animationFn || Animated.timing; + const finalAnimationConfig = animationConfig || { + toValue: this._getAutoSwipeTargetPoint(type), + duration: 250, + easing: Easing.elastic(0.5) + }; + this.setState({ - lastOffset: {x: 0, y: 0}, + lastOffset: this._getAutoSwipeTargetPoint(type), leftActionActivated: false, - leftButtonsActivated: false, - leftButtonsOpen: false, + leftButtonsActivated: type === Swipeable.AutoSwipeType.OpenLeftButtons, + leftButtonsOpen: type === Swipeable.AutoSwipeType.OpenLeftButtons, rightActionActivated: false, - rightButtonsActivated: false, - rightButtonsOpen: false + rightButtonsActivated: type === Swipeable.AutoSwipeType.OpenRightButtons, + rightButtonsOpen: type === Swipeable.AutoSwipeType.OpenRightButtons }); pan.flattenOffset(); - animationFn(pan, animationConfig).start(onDone); + finalAnimationFn(pan, finalAnimationConfig).start(onDone); }; _unmounted = false; @@ -206,6 +244,22 @@ export default class Swipeable extends PureComponent { dy: this.state.pan.y }]); + _getAutoSwipeTargetPoint(type) { + switch (type) { + case Swipeable.AutoSwipeType.Recenter: + return {x: 0, y: 0}; + + case Swipeable.AutoSwipeType.OpenLeftButtons: + return {x: this.props.leftButtons && (this.props.leftButtons.length * this.props.leftButtonWidth), y: 0}; + + case Swipeable.AutoSwipeType.OpenRightButtons: + return {x: this.props.rightButtons && (-this.props.rightButtons.length * this.props.rightButtonWidth), y: 0}; + + default: + return {x: 0, y: 0}; + } + } + _handleMoveShouldSetPanResponder = (event, gestureState) => ( Math.abs(gestureState.dx) > this.props.swipeStartMinDistance ); From 075dc86537567e38bcf85e751d2263de5dbacaee Mon Sep 17 00:00:00 2001 From: Sergey Kozel Date: Wed, 23 Jan 2019 11:55:09 +0300 Subject: [PATCH 2/2] add RTL support --- src/index.js | 52 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/src/index.js b/src/index.js index 26c25f7..3b2764a 100644 --- a/src/index.js +++ b/src/index.js @@ -74,6 +74,7 @@ export default class Swipeable extends PureComponent { onRef: PropTypes.func, onPanAnimatedValueRef: PropTypes.func, swipeStartMinDistance: PropTypes.number, + isRTL: PropTypes.bool, // styles style: ViewPropTypes.style, @@ -151,7 +152,8 @@ export default class Swipeable extends PureComponent { // misc onRef: noop, onPanAnimatedValueRef: noop, - swipeStartMinDistance: 15 + swipeStartMinDistance: 15, + isRTL: false }; static AutoSwipeType = Object.freeze({ @@ -244,16 +246,24 @@ export default class Swipeable extends PureComponent { dy: this.state.pan.y }]); + _invertInRtl(value) { + return this.props.isRTL ? -value : value; + } + + _getTextDirectionDependentValue(ltrValue, rtlValue) { + return this.props.isRTL ? rtlValue : ltrValue; + } + _getAutoSwipeTargetPoint(type) { switch (type) { case Swipeable.AutoSwipeType.Recenter: return {x: 0, y: 0}; case Swipeable.AutoSwipeType.OpenLeftButtons: - return {x: this.props.leftButtons && (this.props.leftButtons.length * this.props.leftButtonWidth), y: 0}; + return {x: this.props.leftButtons && this._invertInRtl(this.props.leftButtons.length * this.props.leftButtonWidth), y: 0}; case Swipeable.AutoSwipeType.OpenRightButtons: - return {x: this.props.rightButtons && (-this.props.rightButtons.length * this.props.rightButtonWidth), y: 0}; + return {x: this.props.rightButtons && this._invertInRtl(-this.props.rightButtons.length * this.props.rightButtonWidth), y: 0}; default: return {x: 0, y: 0}; @@ -294,7 +304,8 @@ export default class Swipeable extends PureComponent { rightActionActivated, rightButtonsActivated } = this.state; - const {dx, vx} = gestureState; + const dx = this._invertInRtl(gestureState.dx); + const vx = this._invertInRtl(gestureState.vx); const x = dx + lastOffset.x; const canSwipeRight = this._canSwipeRight(); const canSwipeLeft = this._canSwipeLeft(); @@ -584,7 +595,7 @@ export default class Swipeable extends PureComponent { return { ...swipeReleaseAnimationConfig, toValue: { - x: leftButtons.length * leftButtonWidth, + x: this._invertInRtl(leftButtons.length * leftButtonWidth), y: 0 }, ...leftButtonsOpenReleaseAnimationConfig @@ -595,7 +606,7 @@ export default class Swipeable extends PureComponent { return { ...swipeReleaseAnimationConfig, toValue: { - x: rightButtons.length * rightButtonWidth * -1, + x: this._invertInRtl(rightButtons.length * rightButtonWidth * -1), y: 0 }, ...rightButtonsOpenReleaseAnimationConfig @@ -619,13 +630,17 @@ export default class Swipeable extends PureComponent { const canSwipeLeft = this._canSwipeLeft(); const canSwipeRight = this._canSwipeRight(); const count = buttons.length; - const leftEnd = canSwipeLeft ? -width : 0; - const rightEnd = canSwipeRight ? width : 0; - const inputRange = isLeftButtons ? [0, rightEnd] : [leftEnd, 0]; + const leftEnd = this._getTextDirectionDependentValue(canSwipeLeft ? -width : 0, canSwipeLeft ? 0 : -width); + const rightEnd = this._getTextDirectionDependentValue(canSwipeRight ? width : 0, canSwipeRight ? 0 : width); + const inputRange = this._getTextDirectionDependentValue( + isLeftButtons ? [0, rightEnd] : [leftEnd, 0], + isLeftButtons ? [leftEnd, 0] : [0, rightEnd]); return buttons.map((buttonContent, index) => { const outputMultiplier = -index / count; - const outputRange = isLeftButtons ? [0, rightEnd * outputMultiplier] : [leftEnd * outputMultiplier, 0]; + const outputRange = this._getTextDirectionDependentValue( + isLeftButtons ? [0, rightEnd * outputMultiplier] : [leftEnd * outputMultiplier, 0], + isLeftButtons ? [leftEnd * outputMultiplier, 0] : [0, rightEnd * outputMultiplier]); const transform = [{ translateX: pan.x.interpolate({ inputRange, @@ -665,11 +680,18 @@ export default class Swipeable extends PureComponent { const canSwipeRight = this._canSwipeRight(); const transform = [{ translateX: pan.x.interpolate({ - inputRange: [canSwipeLeft ? -width : 0, canSwipeRight ? width : 0], - outputRange: [ - canSwipeLeft ? -width + StyleSheet.hairlineWidth : 0, - canSwipeRight ? width - StyleSheet.hairlineWidth : 0 - ], + inputRange: this._getTextDirectionDependentValue( + [canSwipeLeft ? -width : 0, canSwipeRight ? width : 0], + [canSwipeLeft ? 0 : -width, canSwipeRight ? 0 : width]), + outputRange: this._getTextDirectionDependentValue( + [ + canSwipeLeft ? -width + StyleSheet.hairlineWidth : 0, + canSwipeRight ? width - StyleSheet.hairlineWidth : 0 + ], + [ + canSwipeLeft ? 0 : -width + StyleSheet.hairlineWidth, + canSwipeRight ? 0 : width - StyleSheet.hairlineWidth + ]), extrapolate: 'clamp' }) }];