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..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 @@ -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, (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/apple/RNGestureHandlerButtonComponentView.mm b/packages/react-native-gesture-handler/apple/RNGestureHandlerButtonComponentView.mm index 2ae6f8eea8..4979bad4da 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandlerButtonComponentView.mm +++ b/packages/react-native-gesture-handler/apple/RNGestureHandlerButtonComponentView.mm @@ -223,12 +223,17 @@ - (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(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); } } diff --git a/packages/react-native-gesture-handler/src/specs/RNGestureHandlerButtonNativeComponent.ts b/packages/react-native-gesture-handler/src/specs/RNGestureHandlerButtonNativeComponent.ts index 8d4c3da4b9..4fedd3160e 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,10 @@ interface NativeProps extends ViewProps { borderWidth?: Float; borderColor?: ColorValue; borderStyle?: WithDefault; + pointerEvents?: WithDefault< + 'box-none' | 'none' | 'box-only' | 'auto', + 'auto' + >; } export default codegenNativeComponent('RNGestureHandlerButton');