react-native-gesture-handler 2.30.0 → 2.31.0-nightly-20260122-b776a8137

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -54,6 +54,9 @@ public class RNGestureHandlerButtonManagerDelegate<T extends View, U extends Bas
54
54
  case "borderStyle":
55
55
  mViewManager.setBorderStyle(view, value == null ? "solid" : (String) value);
56
56
  break;
57
+ case "pointerEvents":
58
+ mViewManager.setPointerEvents(view, (String) value);
59
+ break;
57
60
  default:
58
61
  super.setProperty(view, propName, value);
59
62
  }
@@ -24,4 +24,5 @@ public interface RNGestureHandlerButtonManagerInterface<T extends View> extends
24
24
  void setBorderWidth(T view, float value);
25
25
  void setBorderColor(T view, @Nullable Integer value);
26
26
  void setBorderStyle(T view, @Nullable String value);
27
+ void setPointerEvents(T view, @Nullable String value);
27
28
  }
@@ -27,6 +27,8 @@ import androidx.core.view.children
27
27
  import com.facebook.react.R
28
28
  import com.facebook.react.module.annotations.ReactModule
29
29
  import com.facebook.react.uimanager.PixelUtil
30
+ import com.facebook.react.uimanager.PointerEvents
31
+ import com.facebook.react.uimanager.ReactPointerEventsView
30
32
  import com.facebook.react.uimanager.ThemedReactContext
31
33
  import com.facebook.react.uimanager.ViewGroupManager
32
34
  import com.facebook.react.uimanager.ViewManagerDelegate
@@ -132,6 +134,17 @@ class RNGestureHandlerButtonViewManager :
132
134
  view.isSoundEffectsEnabled = !touchSoundDisabled
133
135
  }
134
136
 
137
+ @ReactProp(name = ViewProps.POINTER_EVENTS)
138
+ override fun setPointerEvents(view: ButtonViewGroup, pointerEvents: String?) {
139
+ view.pointerEvents = when (pointerEvents) {
140
+ "none" -> PointerEvents.NONE
141
+ "box-none" -> PointerEvents.BOX_NONE
142
+ "box-only" -> PointerEvents.BOX_ONLY
143
+ "auto", null -> PointerEvents.AUTO
144
+ else -> PointerEvents.AUTO
145
+ }
146
+ }
147
+
135
148
  override fun onAfterUpdateTransaction(view: ButtonViewGroup) {
136
149
  super.onAfterUpdateTransaction(view)
137
150
 
@@ -142,7 +155,8 @@ class RNGestureHandlerButtonViewManager :
142
155
 
143
156
  class ButtonViewGroup(context: Context?) :
144
157
  ViewGroup(context),
145
- NativeViewGestureHandler.NativeViewGestureHandlerHook {
158
+ NativeViewGestureHandler.NativeViewGestureHandlerHook,
159
+ ReactPointerEventsView {
146
160
  // Using object because of handling null representing no value set.
147
161
  var rippleColor: Int? = null
148
162
  set(color) = withBackgroundUpdate {
@@ -200,6 +214,8 @@ class RNGestureHandlerButtonViewManager :
200
214
 
201
215
  var exclusive = true
202
216
 
217
+ override var pointerEvents: PointerEvents = PointerEvents.AUTO
218
+
203
219
  private var buttonBackgroundColor = Color.TRANSPARENT
204
220
  private var needBackgroundUpdate = false
205
221
  private var lastEventTime = -1L
@@ -2,6 +2,7 @@
2
2
  #import "RNGestureHandlerActionType.h"
3
3
  #import "RNGestureHandlerDirection.h"
4
4
  #import "RNGestureHandlerEvents.h"
5
+ #import "RNGestureHandlerPointerEvents.h"
5
6
  #import "RNGestureHandlerPointerTracker.h"
6
7
  #import "RNGestureHandlerPointerType.h"
7
8
  #import "RNGestureHandlerState.h"
@@ -28,6 +28,7 @@
28
28
  @property (nonatomic, assign) UIEdgeInsets hitTestEdgeInsets;
29
29
  @property (nonatomic, assign) CGFloat borderRadius;
30
30
  @property (nonatomic) BOOL userEnabled;
31
+ @property (nonatomic, assign) RNGestureHandlerPointerEvents pointerEvents;
31
32
 
32
33
  #if TARGET_OS_OSX && RCT_NEW_ARCH_ENABLED
33
34
  - (void)mountChildComponentView:(RNGHUIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index;
@@ -50,6 +50,7 @@
50
50
  if (self) {
51
51
  _hitTestEdgeInsets = UIEdgeInsetsZero;
52
52
  _userEnabled = YES;
53
+ _pointerEvents = RNGestureHandlerPointerEventsAuto;
53
54
  #if !TARGET_OS_TV && !TARGET_OS_OSX
54
55
  [self setExclusiveTouch:YES];
55
56
  #endif
@@ -93,6 +94,29 @@
93
94
 
94
95
  - (RNGHUIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
95
96
  {
97
+ RNGestureHandlerPointerEvents pointerEvents = _pointerEvents;
98
+
99
+ if (pointerEvents == RNGestureHandlerPointerEventsNone) {
100
+ return nil;
101
+ }
102
+
103
+ if (pointerEvents == RNGestureHandlerPointerEventsBoxNone) {
104
+ for (UIView *subview in [self.subviews reverseObjectEnumerator]) {
105
+ if (!subview.isHidden && subview.alpha > 0) {
106
+ CGPoint convertedPoint = [subview convertPoint:point fromView:self];
107
+ UIView *hitView = [subview hitTest:convertedPoint withEvent:event];
108
+ if (hitView != nil && [self shouldHandleTouch:hitView]) {
109
+ return hitView;
110
+ }
111
+ }
112
+ }
113
+ return nil;
114
+ }
115
+
116
+ if (pointerEvents == RNGestureHandlerPointerEventsBoxOnly) {
117
+ return [self pointInside:point withEvent:event] ? self : nil;
118
+ }
119
+
96
120
  RNGHUIView *inner = [super hitTest:point withEvent:event];
97
121
  while (inner && ![self shouldHandleTouch:inner]) {
98
122
  inner = inner.superview;
@@ -9,11 +9,27 @@
9
9
  #import <react/renderer/components/rngesturehandler_codegen/EventEmitters.h>
10
10
  #import <react/renderer/components/rngesturehandler_codegen/Props.h>
11
11
  #import <react/renderer/components/rngesturehandler_codegen/RCTComponentViewHelpers.h>
12
+ #import <react/renderer/components/view/ViewProps.h>
12
13
 
13
14
  #import "RNGestureHandlerButton.h"
14
15
 
15
16
  using namespace facebook::react;
16
17
 
18
+ static RNGestureHandlerPointerEvents RCTPointerEventsToEnum(facebook::react::PointerEventsMode pointerEvents)
19
+ {
20
+ switch (pointerEvents) {
21
+ case facebook::react::PointerEventsMode::None:
22
+ return RNGestureHandlerPointerEventsNone;
23
+ case facebook::react::PointerEventsMode::BoxNone:
24
+ return RNGestureHandlerPointerEventsBoxNone;
25
+ case facebook::react::PointerEventsMode::BoxOnly:
26
+ return RNGestureHandlerPointerEventsBoxOnly;
27
+ case facebook::react::PointerEventsMode::Auto:
28
+ default:
29
+ return RNGestureHandlerPointerEventsAuto;
30
+ }
31
+ }
32
+
17
33
  @interface RNGestureHandlerButtonComponentView () <RCTRNGestureHandlerButtonViewProtocol>
18
34
  @end
19
35
 
@@ -207,8 +223,40 @@ using namespace facebook::react;
207
223
  _buttonView.hitTestEdgeInsets = UIEdgeInsetsMake(
208
224
  -newProps.hitSlop.top, -newProps.hitSlop.left, -newProps.hitSlop.bottom, -newProps.hitSlop.right);
209
225
 
226
+ // We need to cast to ViewProps to access the pointerEvents property with the correct type.
227
+ // This is necessary because pointerEvents is redefined in the spec,
228
+ // which shadows the base property with a different, incompatible type.
229
+ const auto &newViewProps = static_cast<const ViewProps &>(newProps);
230
+ if (!oldProps) {
231
+ _buttonView.pointerEvents = RCTPointerEventsToEnum(newViewProps.pointerEvents);
232
+ } else {
233
+ const auto &oldButtonProps = *std::static_pointer_cast<const RNGestureHandlerButtonProps>(oldProps);
234
+ const auto &oldViewProps = static_cast<const ViewProps &>(oldButtonProps);
235
+ if (oldViewProps.pointerEvents != newViewProps.pointerEvents) {
236
+ _buttonView.pointerEvents = RCTPointerEventsToEnum(newViewProps.pointerEvents);
237
+ }
238
+ }
239
+
210
240
  [super updateProps:props oldProps:oldProps];
211
241
  }
242
+
243
+ #if !TARGET_OS_OSX
244
+ // Override hitTest to forward touches to _buttonView
245
+ // This is necessary because RCTViewComponentView's hitTest might handle pointerEvents
246
+ // from ViewProps and prevent touches from reaching _buttonView (which is the contentView).
247
+ // Since _buttonView has its own pointerEvents handling, we always forward to it.
248
+ - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
249
+ {
250
+ if (![self pointInside:point withEvent:event]) {
251
+ return nil;
252
+ }
253
+
254
+ CGPoint buttonPoint = [self convertPoint:point toView:_buttonView];
255
+
256
+ return [_buttonView hitTest:buttonPoint withEvent:event];
257
+ }
258
+ #endif
259
+
212
260
  @end
213
261
 
214
262
  Class<RCTComponentViewProtocol> RNGestureHandlerButtonCls(void)
@@ -1,6 +1,20 @@
1
1
  #import "RNGestureHandlerButtonManager.h"
2
2
  #import "RNGestureHandlerButton.h"
3
3
 
4
+ static RNGestureHandlerPointerEvents RCTPointerEventsToEnum(RCTPointerEvents pointerEvents)
5
+ {
6
+ switch (pointerEvents) {
7
+ case RCTPointerEventsNone:
8
+ return RNGestureHandlerPointerEventsNone;
9
+ case RCTPointerEventsBoxNone:
10
+ return RNGestureHandlerPointerEventsBoxNone;
11
+ case RCTPointerEventsBoxOnly:
12
+ return RNGestureHandlerPointerEventsBoxOnly;
13
+ default:
14
+ return RNGestureHandlerPointerEventsAuto;
15
+ }
16
+ }
17
+
4
18
  @implementation RNGestureHandlerButtonManager
5
19
 
6
20
  RCT_EXPORT_MODULE(RNGestureHandlerButton)
@@ -28,6 +42,16 @@ RCT_CUSTOM_VIEW_PROPERTY(hitSlop, UIEdgeInsets, RNGestureHandlerButton)
28
42
  }
29
43
  }
30
44
 
45
+ RCT_CUSTOM_VIEW_PROPERTY(pointerEvents, RCTPointerEvents, RNGestureHandlerButton)
46
+ {
47
+ if (json) {
48
+ RCTPointerEvents pointerEvents = [RCTConvert RCTPointerEvents:json];
49
+ view.pointerEvents = RCTPointerEventsToEnum(pointerEvents);
50
+ } else {
51
+ view.pointerEvents = RNGestureHandlerPointerEventsAuto;
52
+ }
53
+ }
54
+
31
55
  - (RNGHUIView *)view
32
56
  {
33
57
  return (RNGHUIView *)[RNGestureHandlerButton new];
@@ -0,0 +1,8 @@
1
+ #import <Foundation/Foundation.h>
2
+
3
+ typedef NS_ENUM(NSInteger, RNGestureHandlerPointerEvents) {
4
+ RNGestureHandlerPointerEventsNone,
5
+ RNGestureHandlerPointerEventsBoxNone,
6
+ RNGestureHandlerPointerEventsBoxOnly,
7
+ RNGestureHandlerPointerEventsAuto
8
+ };
@@ -6,6 +6,7 @@ import type {
6
6
  } from 'react-native/Libraries/Types/CodegenTypes';
7
7
  import type { ViewProps, ColorValue } from 'react-native';
8
8
 
9
+ // @ts-ignore - Redefining pointerEvents with WithDefault for codegen, conflicts with ViewProps type but codegen needs it
9
10
  interface NativeProps extends ViewProps {
10
11
  exclusive?: WithDefault<boolean, true>;
11
12
  foreground?: boolean;
@@ -17,6 +18,10 @@ interface NativeProps extends ViewProps {
17
18
  borderWidth?: Float;
18
19
  borderColor?: ColorValue;
19
20
  borderStyle?: WithDefault<string, 'solid'>;
21
+ pointerEvents?: WithDefault<
22
+ 'box-none' | 'none' | 'box-only' | 'auto',
23
+ 'auto'
24
+ >;
20
25
  }
21
26
 
22
27
  export default codegenNativeComponent<NativeProps>('RNGestureHandlerButton');
@@ -6,6 +6,7 @@ import type {
6
6
  } from 'react-native/Libraries/Types/CodegenTypes';
7
7
  import type { ViewProps, ColorValue } from 'react-native';
8
8
 
9
+ // @ts-ignore - Redefining pointerEvents with WithDefault for codegen, conflicts with ViewProps type but codegen needs it
9
10
  interface NativeProps extends ViewProps {
10
11
  exclusive?: WithDefault<boolean, true>;
11
12
  foreground?: boolean;
@@ -17,6 +18,10 @@ interface NativeProps extends ViewProps {
17
18
  borderWidth?: Float;
18
19
  borderColor?: ColorValue;
19
20
  borderStyle?: WithDefault<string, 'solid'>;
21
+ pointerEvents?: WithDefault<
22
+ 'box-none' | 'none' | 'box-only' | 'auto',
23
+ 'auto'
24
+ >;
20
25
  }
21
26
 
22
27
  export default codegenNativeComponent<NativeProps>('RNGestureHandlerButton');
@@ -11,6 +11,7 @@ interface NativeProps extends ViewProps {
11
11
  borderWidth?: Float;
12
12
  borderColor?: ColorValue;
13
13
  borderStyle?: WithDefault<string, 'solid'>;
14
+ pointerEvents?: WithDefault<'box-none' | 'none' | 'box-only' | 'auto', 'auto'>;
14
15
  }
15
16
  declare const _default: import("react-native/Libraries/Utilities/codegenNativeComponent").NativeComponentType<NativeProps>;
16
17
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"RNGestureHandlerButtonNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/specs/RNGestureHandlerButtonNativeComponent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,KAAK,EACL,WAAW,EACX,KAAK,EACN,MAAM,2CAA2C,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1D,UAAU,WAAY,SAAQ,SAAS;IACrC,SAAS,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACvC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACrC,WAAW,CAAC,EAAE,UAAU,CAAC;IACzB,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB,kBAAkB,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACjD,WAAW,CAAC,EAAE,KAAK,CAAC;IACpB,WAAW,CAAC,EAAE,UAAU,CAAC;IACzB,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC5C;;AAED,wBAA6E"}
1
+ {"version":3,"file":"RNGestureHandlerButtonNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/specs/RNGestureHandlerButtonNativeComponent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,KAAK,EACL,WAAW,EACX,KAAK,EACN,MAAM,2CAA2C,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1D,UAAU,WAAY,SAAQ,SAAS;IACrC,SAAS,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACvC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACrC,WAAW,CAAC,EAAE,UAAU,CAAC;IACzB,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB,kBAAkB,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACjD,WAAW,CAAC,EAAE,KAAK,CAAC;IACpB,WAAW,CAAC,EAAE,UAAU,CAAC;IACzB,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,aAAa,CAAC,EAAE,WAAW,CACzB,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,EACzC,MAAM,CACP,CAAC;CACH;;AAED,wBAA6E"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-gesture-handler",
3
- "version": "2.30.0",
3
+ "version": "2.31.0-nightly-20260122-b776a8137",
4
4
  "description": "Declarative API exposing native platform touch and gesture system to React Native",
5
5
  "scripts": {
6
6
  "test": "jest",
@@ -6,6 +6,7 @@ import type {
6
6
  } from 'react-native/Libraries/Types/CodegenTypes';
7
7
  import type { ViewProps, ColorValue } from 'react-native';
8
8
 
9
+ // @ts-ignore - Redefining pointerEvents with WithDefault for codegen, conflicts with ViewProps type but codegen needs it
9
10
  interface NativeProps extends ViewProps {
10
11
  exclusive?: WithDefault<boolean, true>;
11
12
  foreground?: boolean;
@@ -17,6 +18,10 @@ interface NativeProps extends ViewProps {
17
18
  borderWidth?: Float;
18
19
  borderColor?: ColorValue;
19
20
  borderStyle?: WithDefault<string, 'solid'>;
21
+ pointerEvents?: WithDefault<
22
+ 'box-none' | 'none' | 'box-only' | 'auto',
23
+ 'auto'
24
+ >;
20
25
  }
21
26
 
22
27
  export default codegenNativeComponent<NativeProps>('RNGestureHandlerButton');