software-mansion / react-native-gesture-handler

Declarative API exposing platform native touch and gesture system to React Native.
https://docs.swmansion.com/react-native-gesture-handler/
MIT License
6.13k stars 982 forks source link

Fix left action panel of `ReanimatedSwipeable` being non-interactive #3236

Closed latekvo closed 7 hours ago

latekvo commented 9 hours ago

Description



Please do not review, I found some issues with this approach.



The left action panel of ReanimatedSwipeable has an issue, where it's not interactive.

This issue is a result of the StyleSheet.absoluteFillObject styles messing with the hitboxes of the Swipeable's movable part. The central hitboxes are picking up presses landing on the left action panel, despite the two Views having no overlap, since they were out of bounds of the swipeable, and blocked from pressing the left action panel, the touch events got lost every time the left panel was clicked.

This PR fixes this issue by separating the action panels from the movable part of the swipeable.

I could not find a more elegant way of resolving this issue - both StyleSheet changes, and structural changes within the individual action panel render functions usually resulted in the onLayout functions returning LayoutChangeEvents with completely zeroed values.

Closes #3223

Test plan

Collapsed repro ```js import React from 'react'; import { View, TouchableOpacity, Text } from 'react-native'; import Swipeable from 'react-native-gesture-handler/ReanimatedSwipeable'; export default function Example() { return ( { console.log('will close', dir); }} onSwipeableWillOpen={(dir) => { console.log('will open', dir); }} onSwipeableOpen={(dir) => { console.log('open', dir); }} onSwipeableClose={(dir) => { console.log('close', dir); }} leftThreshold={50} rightThreshold={50} renderLeftActions={() => { return ( { console.log('press left'); }}> Left ); }} renderRightActions={() => { return ( { console.log('press right'); }}> Right ); }}> { console.log('press outer'); }}> { console.log('press inner'); }} style={{ width: 80, height: 80, alignSelf: 'center' }}> ); } ```

Potential issue with reanimated Animated.View - minimal repo

Collapsed code ```jsx import React, { forwardRef, useCallback } from 'react'; import Animated from 'react-native-reanimated'; import { Text, I18nManager, StyleSheet, TouchableOpacity, View, } from 'react-native'; interface SwipeableMethods { close: () => void; openLeft: () => void; openRight: () => void; reset: () => void; } const Example = forwardRef((_props, _ref) => { const leftElement = useCallback( () => ( { console.log('press left'); }}> Left ), [] ); const rightElement = useCallback( () => ( { console.log('press right'); }}> Right ), [] ); return ( {leftElement()} {rightElement()} ); }); export default Example; ```
latekvo commented 7 hours ago

This is likely an external issue, blocked until this is either resolved or closed.