Skip to content

Commit

Permalink
Fix swipeable overlap bug (#3340)
Browse files Browse the repository at this point in the history
## Description

Reported by @blazejkustra 

Before this PR, the left action panel could've been partially or
entirely covered the right action panel, when the left action panel was
opened.

Similarily, the left action panel could've been seen below the right
action panel, when the right action panel was opened.
 
## Test plan

- open `New swipeable` example in the `Gesture Handler Example App`
- swipe right on the `Gmail` swipeable
- see how it was `red` (right action) before this PR, and how it is
`green` (left action) thanks to this PR
  • Loading branch information
latekvo authored Jan 21, 2025
1 parent f803ac1 commit cb2c528
Showing 1 changed file with 35 additions and 4 deletions.
39 changes: 35 additions & 4 deletions src/components/ReanimatedSwipeable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import Animated, {
withSpring,
} from 'react-native-reanimated';
import {
Dimensions,
I18nManager,
LayoutChangeEvent,
StyleProp,
Expand Down Expand Up @@ -414,11 +415,11 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
const progressTarget = toValue === 0 ? 0 : 1;

showLeftProgress.value =
leftWidth.value > 0
showLeftProgress.value > 0
? withSpring(progressTarget, progressSpringConfig)
: 0;
showRightProgress.value =
rightWidth.value > 0
showRightProgress.value > 0
? withSpring(progressTarget, progressSpringConfig)
: 0;

Expand Down Expand Up @@ -481,9 +482,24 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
[rowWidth]
);

// As stated in `Dimensions.get` docstring, this function should be called on every render
// since dimensions may change (e.g. orientation change)
const hiddenSwipeableOffset = Dimensions.get('window').width + 1;

const leftActionAnimation = useAnimatedStyle(() => {
return {
transform: [
{
translateX:
showLeftProgress.value === 0 ? -hiddenSwipeableOffset : 0,
},
],
};
});

const leftElement = useCallback(
() => (
<Animated.View style={[styles.leftActions]}>
<Animated.View style={[styles.leftActions, leftActionAnimation]}>
{renderLeftActions?.(
showLeftProgress,
appliedTranslation,
Expand All @@ -498,16 +514,28 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
),
[
appliedTranslation,
leftActionAnimation,
leftWidth,
renderLeftActions,
showLeftProgress,
swipeableMethods,
]
);

const rightActionAnimation = useAnimatedStyle(() => {
return {
transform: [
{
translateX:
showRightProgress.value === 0 ? hiddenSwipeableOffset : 0,
},
],
};
});

const rightElement = useCallback(
() => (
<Animated.View style={[styles.rightActions]}>
<Animated.View style={[styles.rightActions, rightActionAnimation]}>
{renderRightActions?.(
showRightProgress,
appliedTranslation,
Expand All @@ -523,6 +551,7 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
[
appliedTranslation,
renderRightActions,
rightActionAnimation,
rightOffset,
showRightProgress,
swipeableMethods,
Expand Down Expand Up @@ -700,9 +729,11 @@ const styles = StyleSheet.create({
leftActions: {
...StyleSheet.absoluteFillObject,
flexDirection: I18nManager.isRTL ? 'row-reverse' : 'row',
overflow: 'hidden',
},
rightActions: {
...StyleSheet.absoluteFillObject,
flexDirection: I18nManager.isRTL ? 'row' : 'row-reverse',
overflow: 'hidden',
},
});

0 comments on commit cb2c528

Please sign in to comment.