Skip to content

Commit 1f723ec

Browse files
authored
Cancel handlers by NativeViewGestureHandler (#2788)
## Description This is a follow-up PR to #2787 that is meant to fix scrolling of swipeable elements. It overrides `shouldHandlerBeCancelledBy` method so that **_active_** `NativeViewGestureHandler` that is _**not a button**_, will cancel other handler. Keep in mind that on web, if scroll has already started we cannot cancel it by calling `preventDefault`, hence it makes sense to cancel other handlers in that case (but we may want to limit it just to `Pan`). Fixes #2617 ## Test plan Tested on - Swipeable example in our example app - Transformations example with added text to achieve scrolling <details> <summary> Modified code from #2617 </summary> ```jsx import React from 'react'; import { View, Text } from 'react-native'; import { FlatList, GestureHandlerRootView } from 'react-native-gesture-handler'; import Swipeable from 'react-native-gesture-handler/Swipeable'; export default function Home() { type ItemProps = { item: { text: string; }; }; const data = Array.from({ length: 50 }, (_, i) => ({ id: i, text: `Item ${i}`, })); const Item = ({ item }: ItemProps) => { return ( <View style={{ margin: 10 }}> <Swipeable renderRightActions={() => ( <View style={{ justifyContent: 'center', }}> <Text style={{ color: 'white', textAlign: 'center' }}> Delete </Text> </View> )}> <View style={{ height: 50, backgroundColor: 'white', justifyContent: 'center', }}> <Text>{item.text}</Text> </View> </Swipeable> </View> ); }; return ( <GestureHandlerRootView> <FlatList data={data} keyExtractor={(item) => item.id.toString()} renderItem={({ item }) => <Item item={item} />} style={{ maxHeight: 400 }} /> </GestureHandlerRootView> ); } ``` </details>
1 parent b587af3 commit 1f723ec

File tree

2 files changed

+13
-9
lines changed

2 files changed

+13
-9
lines changed

src/web/handlers/NativeViewGestureHandler.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,10 @@ export default class NativeViewGestureHandler extends GestureHandler {
2828
const view = this.delegate.getView() as HTMLElement;
2929

3030
view.style['touchAction'] = 'auto';
31-
3231
//@ts-ignore Turns on defualt touch behavior on Safari
3332
view.style['WebkitTouchCallout'] = 'auto';
3433

35-
if (view.hasAttribute('role')) {
36-
this.buttonRole = true;
37-
} else {
38-
this.buttonRole = false;
39-
}
34+
this.buttonRole = view.getAttribute('role') === 'button';
4035
}
4136

4237
public updateGestureConfig({ enabled = true, ...props }: Config): void {
@@ -164,4 +159,8 @@ export default class NativeViewGestureHandler extends GestureHandler {
164159
public disallowsInterruption(): boolean {
165160
return this.disallowInterruption;
166161
}
162+
163+
public isButton(): boolean {
164+
return this.buttonRole;
165+
}
167166
}

src/web/tools/InteractionManager.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import { State } from '../../State';
12
import GestureHandler from '../handlers/GestureHandler';
3+
import NativeViewGestureHandler from '../handlers/NativeViewGestureHandler';
24
import { Config, Handler } from '../interfaces';
35

46
export default class InteractionManager {
@@ -102,10 +104,13 @@ export default class InteractionManager {
102104

103105
public shouldHandlerBeCancelledBy(
104106
_handler: GestureHandler,
105-
_otherHandler: GestureHandler
107+
otherHandler: GestureHandler
106108
): boolean {
107-
//TODO: Implement logic
108-
return false;
109+
return (
110+
otherHandler instanceof NativeViewGestureHandler &&
111+
otherHandler.getState() === State.ACTIVE &&
112+
!otherHandler.isButton()
113+
);
109114
}
110115

111116
public dropRelationsForHandlerWithTag(handlerTag: number): void {

0 commit comments

Comments
 (0)