From c00cd6d9eeb412972b8cbe92a259e491d3449bf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Wed, 1 Oct 2025 13:11:13 +0200 Subject: [PATCH 1/4] Change handling of enabled prop --- .../src/web/handlers/GestureHandler.ts | 24 ++++++++++++++----- .../src/web/handlers/IGestureHandler.ts | 2 +- .../src/web/tools/EventManager.ts | 9 +++++++ .../web/tools/GestureHandlerWebDelegate.ts | 23 ++++++------------ 4 files changed, 35 insertions(+), 23 deletions(-) diff --git a/packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts b/packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts index 9e851191e7..158375b5f4 100644 --- a/packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts +++ b/packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts @@ -35,7 +35,7 @@ export default abstract class GestureHandler implements IGestureHandler { private _state: State = State.UNDETERMINED; private _shouldCancelWhenOutside = false; - private _enabled = false; + private _enabled: boolean | null = null; private viewRef: number | null = null; private propsRef: React.RefObject | null = null; @@ -707,16 +707,28 @@ export default abstract class GestureHandler implements IGestureHandler { // Handling config // + // Helper function to correctly set enabled property + private updateEnabled(enabled: boolean | null) { + if (enabled === undefined) { + if (this._enabled) { + return; + } + + this._enabled = true; + } else if (this._enabled !== enabled) { + this._enabled = enabled; + } + + this.delegate.onEnabledChange(); + } + public setGestureConfig(config: Config) { this.resetConfig(); this.updateGestureConfig(config); } public updateGestureConfig(config: Config): void { - if (config.enabled !== undefined && this.enabled !== config.enabled) { - this._enabled = config.enabled; - this.delegate.onEnabledChange(); - } + this.updateEnabled(config.enabled); if (config.hitSlop !== undefined) { this.hitSlop = config.hitSlop; @@ -906,7 +918,7 @@ export default abstract class GestureHandler implements IGestureHandler { } protected resetConfig(): void { - this._enabled = true; + this._enabled = null; this.manualActivation = false; this.shouldCancelWhenOutside = false; this.mouseButton = undefined; diff --git a/packages/react-native-gesture-handler/src/web/handlers/IGestureHandler.ts b/packages/react-native-gesture-handler/src/web/handlers/IGestureHandler.ts index b0a75269ee..1877271c19 100644 --- a/packages/react-native-gesture-handler/src/web/handlers/IGestureHandler.ts +++ b/packages/react-native-gesture-handler/src/web/handlers/IGestureHandler.ts @@ -21,7 +21,7 @@ export default interface IGestureHandler { state: State; shouldCancelWhenOutside: boolean; shouldResetProgress: boolean; - readonly enabled: boolean; + readonly enabled: boolean | null; readonly pointerType: PointerType; enableContextMenu: boolean; readonly activeCursor?: ActiveCursor; diff --git a/packages/react-native-gesture-handler/src/web/tools/EventManager.ts b/packages/react-native-gesture-handler/src/web/tools/EventManager.ts index ea63906678..d628b1471a 100644 --- a/packages/react-native-gesture-handler/src/web/tools/EventManager.ts +++ b/packages/react-native-gesture-handler/src/web/tools/EventManager.ts @@ -94,6 +94,15 @@ export default abstract class EventManager { this.pointersInBounds.splice(index, 1); } + public enable(value: boolean | null) { + if (value) { + this.registerListeners(); + } else { + this.resetManager(); + this.unregisterListeners(); + } + } + public resetManager(): void { // Reseting activePointersCounter is necessary to make gestures such as pinch work properly // There are gestures that end when there is still one active pointer (like pinch/rotation) diff --git a/packages/react-native-gesture-handler/src/web/tools/GestureHandlerWebDelegate.ts b/packages/react-native-gesture-handler/src/web/tools/GestureHandlerWebDelegate.ts index 8e46b32c9b..12b126c8ea 100644 --- a/packages/react-native-gesture-handler/src/web/tools/GestureHandlerWebDelegate.ts +++ b/packages/react-native-gesture-handler/src/web/tools/GestureHandlerWebDelegate.ts @@ -38,8 +38,6 @@ export class GestureHandlerWebDelegate ); } - this.isInitialized = true; - this.gestureHandler = handler; this.view = findNodeHandle(viewRef) as unknown as HTMLElement; @@ -48,10 +46,6 @@ export class GestureHandlerWebDelegate touchAction: this.view.style.touchAction, }; - this.setUserSelect(); - this.setTouchAction(); - this.setContextMenu(); - this.eventManagers.push(new PointerEventManager(this.view)); this.eventManagers.push(new KeyboardEventManager(this.view)); this.eventManagers.push(new WheelEventManager(this.view)); @@ -59,6 +53,8 @@ export class GestureHandlerWebDelegate this.eventManagers.forEach((manager) => this.gestureHandler.attachEventManager(manager) ); + + this.isInitialized = true; } detach(): void { @@ -68,8 +64,9 @@ export class GestureHandlerWebDelegate }; this.eventManagers.forEach((manager) => { - manager.unregisterListeners(); + manager.enable(false); }); + this.removeContextMenuListeners(); this._view = null; this.eventManagers = []; @@ -198,15 +195,9 @@ export class GestureHandlerWebDelegate this.setTouchAction(); this.setContextMenu(); - if (this.gestureHandler.enabled) { - this.eventManagers.forEach((manager) => { - manager.registerListeners(); - }); - } else { - this.eventManagers.forEach((manager) => { - manager.unregisterListeners(); - }); - } + this.eventManagers.forEach((manager) => { + manager.enable(this.gestureHandler.enabled); + }); } onBegin(): void { From 24b57ac5b6ec4146891bf3eacc6db495e069f715 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Thu, 2 Oct 2025 11:10:13 +0200 Subject: [PATCH 2/4] Rename to setEnabled --- .../src/web/tools/EventManager.ts | 2 +- .../src/web/tools/GestureHandlerWebDelegate.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/react-native-gesture-handler/src/web/tools/EventManager.ts b/packages/react-native-gesture-handler/src/web/tools/EventManager.ts index d628b1471a..95c82b4e1a 100644 --- a/packages/react-native-gesture-handler/src/web/tools/EventManager.ts +++ b/packages/react-native-gesture-handler/src/web/tools/EventManager.ts @@ -94,7 +94,7 @@ export default abstract class EventManager { this.pointersInBounds.splice(index, 1); } - public enable(value: boolean | null) { + public setEnabled(value: boolean | null) { if (value) { this.registerListeners(); } else { diff --git a/packages/react-native-gesture-handler/src/web/tools/GestureHandlerWebDelegate.ts b/packages/react-native-gesture-handler/src/web/tools/GestureHandlerWebDelegate.ts index 12b126c8ea..14476c9ad2 100644 --- a/packages/react-native-gesture-handler/src/web/tools/GestureHandlerWebDelegate.ts +++ b/packages/react-native-gesture-handler/src/web/tools/GestureHandlerWebDelegate.ts @@ -64,7 +64,7 @@ export class GestureHandlerWebDelegate }; this.eventManagers.forEach((manager) => { - manager.enable(false); + manager.setEnabled(false); }); this.removeContextMenuListeners(); @@ -196,7 +196,7 @@ export class GestureHandlerWebDelegate this.setContextMenu(); this.eventManagers.forEach((manager) => { - manager.enable(this.gestureHandler.enabled); + manager.setEnabled(this.gestureHandler.enabled); }); } From ad10a30dceb36836896243bacacb76baa7efa4c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Thu, 2 Oct 2025 11:13:51 +0200 Subject: [PATCH 3/4] Update type --- .../src/web/handlers/GestureHandler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts b/packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts index 158375b5f4..865423387d 100644 --- a/packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts +++ b/packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts @@ -708,7 +708,7 @@ export default abstract class GestureHandler implements IGestureHandler { // // Helper function to correctly set enabled property - private updateEnabled(enabled: boolean | null) { + private updateEnabled(enabled: boolean | undefined) { if (enabled === undefined) { if (this._enabled) { return; From 1f818188d24e25b9bdf01604136be207febaf6f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Mon, 6 Oct 2025 09:26:12 +0200 Subject: [PATCH 4/4] Do not call onEnabledChange every time --- .../src/web/handlers/GestureHandler.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts b/packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts index ae0ce75f2c..a21f86efff 100644 --- a/packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts +++ b/packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts @@ -720,11 +720,11 @@ export default abstract class GestureHandler implements IGestureHandler { } this._enabled = true; + this.delegate.onEnabledChange(); } else if (this._enabled !== enabled) { this._enabled = enabled; + this.delegate.onEnabledChange(); } - - this.delegate.onEnabledChange(); } public setGestureConfig(config: Config) {