From f5361ff0de4d46b6057e361878b1003946dd47d2 Mon Sep 17 00:00:00 2001 From: Hugo EXTRAT Date: Tue, 20 Jan 2026 14:45:46 +0100 Subject: [PATCH 1/4] fix(android): handles `pointerEvents` for `Pressable` component --- .../RNGestureHandlerButtonManagerDelegate.java | 3 +++ ...RNGestureHandlerButtonManagerInterface.java | 1 + .../react/RNGestureHandlerButtonViewManager.kt | 18 +++++++++++++++++- .../RNGestureHandlerButtonNativeComponent.ts | 2 ++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/react-native-gesture-handler/android/paper/src/main/java/com/facebook/react/viewmanagers/RNGestureHandlerButtonManagerDelegate.java b/packages/react-native-gesture-handler/android/paper/src/main/java/com/facebook/react/viewmanagers/RNGestureHandlerButtonManagerDelegate.java index 3e0b2e26c4..9cd1d88285 100644 --- a/packages/react-native-gesture-handler/android/paper/src/main/java/com/facebook/react/viewmanagers/RNGestureHandlerButtonManagerDelegate.java +++ b/packages/react-native-gesture-handler/android/paper/src/main/java/com/facebook/react/viewmanagers/RNGestureHandlerButtonManagerDelegate.java @@ -54,6 +54,9 @@ public void setProperty(T view, String propName, @Nullable Object value) { case "borderStyle": mViewManager.setBorderStyle(view, value == null ? "solid" : (String) value); break; + case "pointerEvents": + mViewManager.setPointerEvents(view, value == null ? "auto" : (String) value); + break; default: super.setProperty(view, propName, value); } diff --git a/packages/react-native-gesture-handler/android/paper/src/main/java/com/facebook/react/viewmanagers/RNGestureHandlerButtonManagerInterface.java b/packages/react-native-gesture-handler/android/paper/src/main/java/com/facebook/react/viewmanagers/RNGestureHandlerButtonManagerInterface.java index 975704f08b..6250c3d502 100644 --- a/packages/react-native-gesture-handler/android/paper/src/main/java/com/facebook/react/viewmanagers/RNGestureHandlerButtonManagerInterface.java +++ b/packages/react-native-gesture-handler/android/paper/src/main/java/com/facebook/react/viewmanagers/RNGestureHandlerButtonManagerInterface.java @@ -24,4 +24,5 @@ public interface RNGestureHandlerButtonManagerInterface extends void setBorderWidth(T view, float value); void setBorderColor(T view, @Nullable Integer value); void setBorderStyle(T view, @Nullable String value); + void setPointerEvents(T view, @Nullable String value); } diff --git a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt index 32cb973b80..e4114c40fa 100644 --- a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt +++ b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt @@ -27,6 +27,8 @@ import androidx.core.view.children import com.facebook.react.R import com.facebook.react.module.annotations.ReactModule import com.facebook.react.uimanager.PixelUtil +import com.facebook.react.uimanager.PointerEvents +import com.facebook.react.uimanager.ReactPointerEventsView import com.facebook.react.uimanager.ThemedReactContext import com.facebook.react.uimanager.ViewGroupManager import com.facebook.react.uimanager.ViewManagerDelegate @@ -132,6 +134,17 @@ class RNGestureHandlerButtonViewManager : view.isSoundEffectsEnabled = !touchSoundDisabled } + @ReactProp(name = ViewProps.POINTER_EVENTS) + override fun setPointerEvents(view: ButtonViewGroup, pointerEvents: String?) { + view.pointerEvents = when (pointerEvents) { + "none" -> PointerEvents.NONE + "box-none" -> PointerEvents.BOX_NONE + "box-only" -> PointerEvents.BOX_ONLY + "auto", null -> PointerEvents.AUTO + else -> PointerEvents.AUTO + } + } + override fun onAfterUpdateTransaction(view: ButtonViewGroup) { super.onAfterUpdateTransaction(view) @@ -142,7 +155,8 @@ class RNGestureHandlerButtonViewManager : class ButtonViewGroup(context: Context?) : ViewGroup(context), - NativeViewGestureHandler.NativeViewGestureHandlerHook { + NativeViewGestureHandler.NativeViewGestureHandlerHook, + ReactPointerEventsView { // Using object because of handling null representing no value set. var rippleColor: Int? = null set(color) = withBackgroundUpdate { @@ -200,6 +214,8 @@ class RNGestureHandlerButtonViewManager : var exclusive = true + override var pointerEvents: PointerEvents = PointerEvents.AUTO + private var buttonBackgroundColor = Color.TRANSPARENT private var needBackgroundUpdate = false private var lastEventTime = -1L diff --git a/packages/react-native-gesture-handler/src/specs/RNGestureHandlerButtonNativeComponent.ts b/packages/react-native-gesture-handler/src/specs/RNGestureHandlerButtonNativeComponent.ts index 8d4c3da4b9..65c06f829a 100644 --- a/packages/react-native-gesture-handler/src/specs/RNGestureHandlerButtonNativeComponent.ts +++ b/packages/react-native-gesture-handler/src/specs/RNGestureHandlerButtonNativeComponent.ts @@ -6,6 +6,7 @@ import type { } from 'react-native/Libraries/Types/CodegenTypes'; import type { ViewProps, ColorValue } from 'react-native'; +// @ts-ignore - Redefining pointerEvents with WithDefault for codegen, conflicts with ViewProps type but codegen needs it interface NativeProps extends ViewProps { exclusive?: WithDefault; foreground?: boolean; @@ -17,6 +18,7 @@ interface NativeProps extends ViewProps { borderWidth?: Float; borderColor?: ColorValue; borderStyle?: WithDefault; + pointerEvents?: WithDefault<'box-none' | 'none' | 'box-only' | 'auto', 'auto'>; } export default codegenNativeComponent('RNGestureHandlerButton'); From 8c240057fbd1067f9dcc4236358efa54e7d93d7c Mon Sep 17 00:00:00 2001 From: Hugo EXTRAT Date: Wed, 21 Jan 2026 21:00:08 +0100 Subject: [PATCH 2/4] fix(iOS): cast pointerEvents after codegen --- .../apple/RNGestureHandlerButtonComponentView.mm | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandlerButtonComponentView.mm b/packages/react-native-gesture-handler/apple/RNGestureHandlerButtonComponentView.mm index 2ae6f8eea8..a4d8b7877f 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandlerButtonComponentView.mm +++ b/packages/react-native-gesture-handler/apple/RNGestureHandlerButtonComponentView.mm @@ -223,12 +223,14 @@ - (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared & _buttonView.hitTestEdgeInsets = UIEdgeInsetsMake( -newProps.hitSlop.top, -newProps.hitSlop.left, -newProps.hitSlop.bottom, -newProps.hitSlop.right); + const auto &newViewProps = static_cast(newProps); if (!oldProps) { - _buttonView.pointerEvents = RCTPointerEventsToEnum(newProps.pointerEvents); + _buttonView.pointerEvents = RCTPointerEventsToEnum(newViewProps.pointerEvents); } else { const auto &oldButtonProps = *std::static_pointer_cast(oldProps); - if (oldButtonProps.pointerEvents != newProps.pointerEvents) { - _buttonView.pointerEvents = RCTPointerEventsToEnum(newProps.pointerEvents); + const auto &oldViewProps = static_cast(oldButtonProps); + if (oldViewProps.pointerEvents != newViewProps.pointerEvents) { + _buttonView.pointerEvents = RCTPointerEventsToEnum(newViewProps.pointerEvents); } } From 4edd4855c10c4c93cedcf3dcf196deae50422475 Mon Sep 17 00:00:00 2001 From: Hugo EXTRAT Date: Wed, 21 Jan 2026 21:08:42 +0100 Subject: [PATCH 3/4] chore: lint fix --- .../viewmanagers/RNGestureHandlerButtonManagerDelegate.java | 2 +- .../src/specs/RNGestureHandlerButtonNativeComponent.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/react-native-gesture-handler/android/paper/src/main/java/com/facebook/react/viewmanagers/RNGestureHandlerButtonManagerDelegate.java b/packages/react-native-gesture-handler/android/paper/src/main/java/com/facebook/react/viewmanagers/RNGestureHandlerButtonManagerDelegate.java index 9cd1d88285..dc618ead4c 100644 --- a/packages/react-native-gesture-handler/android/paper/src/main/java/com/facebook/react/viewmanagers/RNGestureHandlerButtonManagerDelegate.java +++ b/packages/react-native-gesture-handler/android/paper/src/main/java/com/facebook/react/viewmanagers/RNGestureHandlerButtonManagerDelegate.java @@ -55,7 +55,7 @@ public void setProperty(T view, String propName, @Nullable Object value) { mViewManager.setBorderStyle(view, value == null ? "solid" : (String) value); break; case "pointerEvents": - mViewManager.setPointerEvents(view, value == null ? "auto" : (String) value); + mViewManager.setPointerEvents(view, (String) value); break; default: super.setProperty(view, propName, value); diff --git a/packages/react-native-gesture-handler/src/specs/RNGestureHandlerButtonNativeComponent.ts b/packages/react-native-gesture-handler/src/specs/RNGestureHandlerButtonNativeComponent.ts index 65c06f829a..4fedd3160e 100644 --- a/packages/react-native-gesture-handler/src/specs/RNGestureHandlerButtonNativeComponent.ts +++ b/packages/react-native-gesture-handler/src/specs/RNGestureHandlerButtonNativeComponent.ts @@ -18,7 +18,10 @@ interface NativeProps extends ViewProps { borderWidth?: Float; borderColor?: ColorValue; borderStyle?: WithDefault; - pointerEvents?: WithDefault<'box-none' | 'none' | 'box-only' | 'auto', 'auto'>; + pointerEvents?: WithDefault< + 'box-none' | 'none' | 'box-only' | 'auto', + 'auto' + >; } export default codegenNativeComponent('RNGestureHandlerButton'); From 1af36768eee44ae6fb6597fb12fc6803a0ac1298 Mon Sep 17 00:00:00 2001 From: Hugo EXTRAT Date: Thu, 22 Jan 2026 16:14:05 +0100 Subject: [PATCH 4/4] chore(ios): updateProps comment --- .../apple/RNGestureHandlerButtonComponentView.mm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandlerButtonComponentView.mm b/packages/react-native-gesture-handler/apple/RNGestureHandlerButtonComponentView.mm index a4d8b7877f..4979bad4da 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandlerButtonComponentView.mm +++ b/packages/react-native-gesture-handler/apple/RNGestureHandlerButtonComponentView.mm @@ -223,6 +223,9 @@ - (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared & _buttonView.hitTestEdgeInsets = UIEdgeInsetsMake( -newProps.hitSlop.top, -newProps.hitSlop.left, -newProps.hitSlop.bottom, -newProps.hitSlop.right); + // We need to cast to ViewProps to access the pointerEvents property with the correct type. + // This is necessary because pointerEvents is redefined in the spec, + // which shadows the base property with a different, incompatible type. const auto &newViewProps = static_cast(newProps); if (!oldProps) { _buttonView.pointerEvents = RCTPointerEventsToEnum(newViewProps.pointerEvents);