react-native-gesture-handler 2.24.0 → 2.25.0

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.
Files changed (61) hide show
  1. package/README.md +3 -0
  2. package/android/build.gradle +39 -12
  3. package/android/fabric/src/main/java/com/swmansion/gesturehandler/ReactContextExtensions.kt +2 -0
  4. package/android/nosvg/src/main/java/com/swmansion/gesturehandler/RNSVGHitTester.kt +13 -0
  5. package/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt +6 -1
  6. package/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt +13 -3
  7. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerModule.kt +1 -1
  8. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootHelper.kt +8 -2
  9. package/android/svg/src/main/java/com/swmansion/gesturehandler/RNSVGHitTester.kt +67 -0
  10. package/apple/RNGestureHandlerButtonComponentView.h +2 -1
  11. package/apple/RNGestureHandlerButtonComponentView.mm +95 -0
  12. package/lib/commonjs/components/GestureButtons.js +5 -4
  13. package/lib/commonjs/components/GestureButtons.js.map +1 -1
  14. package/lib/commonjs/components/Pressable/Pressable.js +76 -40
  15. package/lib/commonjs/components/Pressable/Pressable.js.map +1 -1
  16. package/lib/commonjs/handlers/createHandler.js +5 -8
  17. package/lib/commonjs/handlers/createHandler.js.map +1 -1
  18. package/lib/commonjs/handlers/gestures/GestureDetector/updateHandlers.js +12 -5
  19. package/lib/commonjs/handlers/gestures/GestureDetector/updateHandlers.js.map +1 -1
  20. package/lib/commonjs/handlers/gestures/GestureDetector/utils.js +3 -7
  21. package/lib/commonjs/handlers/gestures/GestureDetector/utils.js.map +1 -1
  22. package/lib/commonjs/web/tools/GestureHandlerOrchestrator.js +0 -1
  23. package/lib/commonjs/web/tools/GestureHandlerOrchestrator.js.map +1 -1
  24. package/lib/commonjs/web/tools/InteractionManager.js +1 -3
  25. package/lib/commonjs/web/tools/InteractionManager.js.map +1 -1
  26. package/lib/module/components/GestureButtons.js +4 -3
  27. package/lib/module/components/GestureButtons.js.map +1 -1
  28. package/lib/module/components/Pressable/Pressable.js +75 -39
  29. package/lib/module/components/Pressable/Pressable.js.map +1 -1
  30. package/lib/module/handlers/createHandler.js +5 -8
  31. package/lib/module/handlers/createHandler.js.map +1 -1
  32. package/lib/module/handlers/gestures/GestureDetector/updateHandlers.js +12 -5
  33. package/lib/module/handlers/gestures/GestureDetector/updateHandlers.js.map +1 -1
  34. package/lib/module/handlers/gestures/GestureDetector/utils.js +3 -6
  35. package/lib/module/handlers/gestures/GestureDetector/utils.js.map +1 -1
  36. package/lib/module/web/tools/GestureHandlerOrchestrator.js +0 -1
  37. package/lib/module/web/tools/GestureHandlerOrchestrator.js.map +1 -1
  38. package/lib/module/web/tools/InteractionManager.js +1 -2
  39. package/lib/module/web/tools/InteractionManager.js.map +1 -1
  40. package/lib/typescript/components/GestureButtons.d.ts +3 -3
  41. package/lib/typescript/components/Pressable/Pressable.d.ts +3 -1
  42. package/package.json +4 -2
  43. package/src/components/GestureButtons.tsx +13 -9
  44. package/src/components/Pressable/Pressable.tsx +400 -351
  45. package/src/handlers/createHandler.tsx +4 -8
  46. package/src/handlers/gestures/GestureDetector/updateHandlers.ts +11 -3
  47. package/src/handlers/gestures/GestureDetector/utils.ts +3 -7
  48. package/src/web/tools/GestureHandlerOrchestrator.ts +0 -1
  49. package/src/web/tools/InteractionManager.ts +1 -2
  50. package/lib/commonjs/getReactNativeVersion.js +0 -22
  51. package/lib/commonjs/getReactNativeVersion.js.map +0 -1
  52. package/lib/commonjs/getReactNativeVersion.web.js +0 -11
  53. package/lib/commonjs/getReactNativeVersion.web.js.map +0 -1
  54. package/lib/module/getReactNativeVersion.js +0 -10
  55. package/lib/module/getReactNativeVersion.js.map +0 -1
  56. package/lib/module/getReactNativeVersion.web.js +0 -4
  57. package/lib/module/getReactNativeVersion.web.js.map +0 -1
  58. package/lib/typescript/getReactNativeVersion.d.ts +0 -4
  59. package/lib/typescript/getReactNativeVersion.web.d.ts +0 -1
  60. package/src/getReactNativeVersion.ts +0 -11
  61. package/src/getReactNativeVersion.web.ts +0 -3
package/README.md CHANGED
@@ -35,8 +35,11 @@ You will need to have an Android or iOS device or emulator connected.
35
35
 
36
36
  ## React Native Support
37
37
 
38
+ `react-native-gesture-handler` supports the three latest minor releases of `react-native`.
39
+
38
40
  | version | react-native version |
39
41
  | ------- | -------------------- |
42
+ | 2.24.0+ | 0.75.0+ |
40
43
  | 2.21.0+ | 0.74.0+ |
41
44
  | 2.18.0+ | 0.73.0+ |
42
45
  | 2.16.0+ | 0.68.0+ |
@@ -45,9 +45,9 @@ def resolveReactNativeDirectory() {
45
45
  }
46
46
 
47
47
  throw new Exception(
48
- "[react-native-gesture-handler] Unable to resolve react-native location in " +
49
- "node_modules. You should add project extension property (in app/build.gradle) " +
50
- "`REACT_NATIVE_NODE_MODULES_DIR` with path to react-native."
48
+ "[react-native-gesture-handler] Unable to resolve react-native location in " +
49
+ "node_modules. You should add project extension property (in app/build.gradle) " +
50
+ "`REACT_NATIVE_NODE_MODULES_DIR` with path to react-native."
51
51
  )
52
52
  }
53
53
 
@@ -75,6 +75,22 @@ def shouldUseCommonInterfaceFromReanimated() {
75
75
  }
76
76
  }
77
77
 
78
+ def shouldUseCommonInterfaceFromRNSVG() {
79
+ // common interface compatible with react-native-svg >= 15.11.2
80
+ def rnsvg = rootProject.subprojects.find { it.name == 'react-native-svg' }
81
+ if (rnsvg == null) {
82
+ return false
83
+ }
84
+
85
+ def inputFile = new File(rnsvg.projectDir, '../package.json')
86
+ def json = new JsonSlurper().parseText(inputFile.text)
87
+ def rnsvgVersion = json.version as String
88
+ def (major, minor, patch) = rnsvgVersion.tokenize('.')
89
+ return (Integer.parseInt(major) == 15 && Integer.parseInt(minor) == 11 && Integer.parseInt(patch) >= 2) ||
90
+ (Integer.parseInt(major) == 15 && Integer.parseInt(minor) > 11) ||
91
+ Integer.parseInt(major) > 15
92
+ }
93
+
78
94
  def reactNativeArchitectures() {
79
95
  def value = project.getProperties().get("reactNativeArchitectures")
80
96
  return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
@@ -119,15 +135,15 @@ android {
119
135
  buildConfigField "int", "REACT_NATIVE_MINOR_VERSION", REACT_NATIVE_MINOR_VERSION.toString()
120
136
 
121
137
  if (isNewArchitectureEnabled()) {
122
- var appProject = rootProject.allprojects.find {it.plugins.hasPlugin('com.android.application')}
138
+ var appProject = rootProject.allprojects.find { it.plugins.hasPlugin('com.android.application') }
123
139
  externalNativeBuild {
124
140
  cmake {
125
141
  cppFlags "-O2", "-frtti", "-fexceptions", "-Wall", "-Werror", "-std=c++20", "-DANDROID"
126
142
  arguments "-DREACT_NATIVE_DIR=${REACT_NATIVE_DIR}",
127
- "-DREACT_NATIVE_MINOR_VERSION=${REACT_NATIVE_MINOR_VERSION}",
128
- "-DANDROID_STL=c++_shared",
129
- "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
130
- abiFilters (*reactNativeArchitectures())
143
+ "-DREACT_NATIVE_MINOR_VERSION=${REACT_NATIVE_MINOR_VERSION}",
144
+ "-DANDROID_STL=c++_shared",
145
+ "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
146
+ abiFilters(*reactNativeArchitectures())
131
147
  }
132
148
  }
133
149
  }
@@ -168,13 +184,19 @@ android {
168
184
  srcDirs += 'noreanimated/src/main/java'
169
185
  }
170
186
 
187
+ if (shouldUseCommonInterfaceFromRNSVG()) {
188
+ srcDirs += 'svg/src/main/java'
189
+ } else {
190
+ srcDirs += 'nosvg/src/main/java'
191
+ }
192
+
171
193
  if (isNewArchitectureEnabled()) {
172
194
  srcDirs += 'fabric/src/main/java'
173
195
  } else {
174
196
  // 'paper/src/main/java' includes files from codegen so the library can compile with
175
197
  // codegen turned off
176
198
 
177
- if (REACT_NATIVE_MINOR_VERSION > 77){
199
+ if (REACT_NATIVE_MINOR_VERSION > 77) {
178
200
  srcDirs += 'paper/src/main/java'
179
201
  } else {
180
202
  srcDirs += 'paper77/src/main/java'
@@ -211,15 +233,20 @@ def kotlin_version = safeExtGet('kotlinVersion', project.properties['RNGH_kotlin
211
233
 
212
234
  dependencies {
213
235
  implementation 'com.facebook.react:react-native:+' // from node_modules
214
-
236
+
215
237
 
216
238
  if (shouldUseCommonInterfaceFromReanimated()) {
217
239
  // Include Reanimated as dependency to load the common interface
218
- implementation (rootProject.subprojects.find { it.name == 'react-native-reanimated' }) {
219
- exclude group:'com.facebook.fbjni' // resolves "Duplicate class com.facebook.jni.CppException"
240
+ implementation(rootProject.subprojects.find { it.name == 'react-native-reanimated' }) {
241
+ // resolves "Duplicate class com.facebook.jni.CppException"
242
+ exclude group: 'com.facebook.fbjni'
220
243
  }
221
244
  }
222
245
 
246
+ if (shouldUseCommonInterfaceFromRNSVG()) {
247
+ implementation rootProject.subprojects.find { it.name == 'react-native-svg' }
248
+ }
249
+
223
250
  implementation 'androidx.appcompat:appcompat:1.2.0'
224
251
  implementation "androidx.core:core-ktx:1.6.0"
225
252
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
@@ -5,8 +5,10 @@ import com.facebook.react.fabric.FabricUIManager
5
5
  import com.facebook.react.uimanager.UIManagerHelper
6
6
  import com.facebook.react.uimanager.common.UIManagerType
7
7
  import com.facebook.react.uimanager.events.Event
8
+ import android.annotation.SuppressLint
8
9
 
9
10
  fun ReactContext.dispatchEvent(event: Event<*>) {
11
+ @SuppressLint("WrongConstant")
10
12
  val fabricUIManager = UIManagerHelper.getUIManager(this, UIManagerType.FABRIC) as FabricUIManager
11
13
  fabricUIManager.eventDispatcher.dispatchEvent(event)
12
14
  }
@@ -0,0 +1,13 @@
1
+ package com.swmansion.gesturehandler
2
+
3
+ import android.view.View
4
+
5
+ class RNSVGHitTester {
6
+ companion object {
7
+ @Suppress("UNUSED_PARAMETER")
8
+ fun isSvgElement(view: Any) = false
9
+
10
+ @Suppress("UNUSED_PARAMETER")
11
+ fun hitTest(view: View, posX: Float, posY: Float) = false
12
+ }
13
+ }
@@ -15,6 +15,7 @@ import com.facebook.react.bridge.UiThreadUtil
15
15
  import com.facebook.react.bridge.WritableArray
16
16
  import com.facebook.react.uimanager.PixelUtil
17
17
  import com.swmansion.gesturehandler.BuildConfig
18
+ import com.swmansion.gesturehandler.RNSVGHitTester
18
19
  import com.swmansion.gesturehandler.react.RNGestureHandlerTouchEvent
19
20
  import java.lang.IllegalStateException
20
21
  import java.util.*
@@ -610,9 +611,13 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
610
611
  }
611
612
 
612
613
  fun isWithinBounds(view: View?, posX: Float, posY: Float): Boolean {
614
+ if (RNSVGHitTester.isSvgElement(view!!)) {
615
+ return RNSVGHitTester.hitTest(view, posX, posY)
616
+ }
617
+
613
618
  var left = 0f
614
619
  var top = 0f
615
- var right = view!!.width.toFloat()
620
+ var right = view.width.toFloat()
616
621
  var bottom = view.height.toFloat()
617
622
  hitSlop?.let { hitSlop ->
618
623
  val padLeft = hitSlop[HIT_SLOP_LEFT_IDX]
@@ -6,8 +6,8 @@ import android.view.MotionEvent
6
6
  import android.view.View
7
7
  import android.view.ViewGroup
8
8
  import android.widget.EditText
9
+ import com.swmansion.gesturehandler.react.RNGestureHandlerRootHelper
9
10
  import java.util.*
10
- import kotlin.collections.HashSet
11
11
 
12
12
  class GestureHandlerOrchestrator(
13
13
  private val wrapperView: ViewGroup,
@@ -470,6 +470,17 @@ class GestureHandlerOrchestrator(
470
470
  return found
471
471
  }
472
472
 
473
+ // We don't want to extract gestures other than hover when processing hover events.
474
+ // There's only one exception - RootViewGestureHandler. TalkBack uses hover events,
475
+ // so we need to pass them into RootViewGestureHandler, otherwise press and hold
476
+ // gesture stops working correctly (see https://github.com/software-mansion/react-native-gesture-handler/issues/3407)
477
+ private fun shouldHandlerSkipHoverEvents(handler: GestureHandler<*>, action: Int): Boolean {
478
+ val shouldSkipHoverEvents =
479
+ handler !is HoverGestureHandler && handler !is RNGestureHandlerRootHelper.RootViewGestureHandler
480
+
481
+ return shouldSkipHoverEvents && action in listOf(MotionEvent.ACTION_HOVER_EXIT, MotionEvent.ACTION_HOVER_ENTER, MotionEvent.ACTION_HOVER_MOVE)
482
+ }
483
+
473
484
  private fun recordViewHandlersForPointer(view: View, coords: FloatArray, pointerId: Int, event: MotionEvent): Boolean {
474
485
  var found = false
475
486
  handlerRegistry.getHandlersForView(view)?.let {
@@ -480,8 +491,7 @@ class GestureHandlerOrchestrator(
480
491
  continue
481
492
  }
482
493
 
483
- // we don't want to extract gestures other than hover when processing hover events
484
- if (event.action in listOf(MotionEvent.ACTION_HOVER_EXIT, MotionEvent.ACTION_HOVER_ENTER, MotionEvent.ACTION_HOVER_MOVE) && handler !is HoverGestureHandler) {
494
+ if (shouldHandlerSkipHoverEvents(handler, event.action)) {
485
495
  continue
486
496
  }
487
497
 
@@ -548,7 +548,7 @@ class RNGestureHandlerModule(reactContext: ReactApplicationContext?) :
548
548
  val event = RNGestureHandlerEvent.obtain(
549
549
  handler,
550
550
  handlerFactory.createEventBuilder(handler),
551
- useTopPrefixedName = BuildConfig.REACT_NATIVE_MINOR_VERSION >= 71
551
+ true
552
552
  )
553
553
  sendEventForNativeAnimatedEvent(event)
554
554
  } else if (handler.actionType == GestureHandler.ACTION_TYPE_JS_FUNCTION_OLD_API) {
@@ -58,19 +58,25 @@ class RNGestureHandlerRootHelper(private val context: ReactContext, wrappedView:
58
58
  }
59
59
 
60
60
  internal inner class RootViewGestureHandler : GestureHandler<RootViewGestureHandler>() {
61
- override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) {
61
+ private fun handleEvent(event: MotionEvent) {
62
62
  val currentState = state
63
+
63
64
  // we shouldn't stop intercepting events when there is an active handler already, which could happen when
64
65
  // adding a new pointer to the screen after a handler activates
65
66
  if (currentState == STATE_UNDETERMINED && (!shouldIntercept || orchestrator?.isAnyHandlerActive() != true)) {
66
67
  begin()
67
68
  shouldIntercept = false
68
69
  }
69
- if (event.actionMasked == MotionEvent.ACTION_UP) {
70
+
71
+ if (event.actionMasked == MotionEvent.ACTION_UP || event.actionMasked == MotionEvent.ACTION_HOVER_EXIT) {
70
72
  end()
71
73
  }
72
74
  }
73
75
 
76
+ override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) = handleEvent(event)
77
+
78
+ override fun onHandleHover(event: MotionEvent, sourceEvent: MotionEvent) = handleEvent(event)
79
+
74
80
  override fun onCancel() {
75
81
  shouldIntercept = true
76
82
  val time = SystemClock.uptimeMillis()
@@ -0,0 +1,67 @@
1
+ package com.swmansion.gesturehandler
2
+
3
+ import android.view.View
4
+ import androidx.core.view.children
5
+ import com.horcrux.svg.SvgView
6
+ import com.horcrux.svg.VirtualView
7
+
8
+ class RNSVGHitTester {
9
+ companion object {
10
+ private fun getRootSvgView(view: View): SvgView {
11
+ var rootSvgView: SvgView
12
+
13
+ rootSvgView = if (view is VirtualView) {
14
+ view.svgView!!
15
+ } else {
16
+ view as SvgView
17
+ }
18
+
19
+ while (isSvgElement(rootSvgView.parent)) {
20
+ rootSvgView = if (rootSvgView.parent is VirtualView) {
21
+ (rootSvgView.parent as VirtualView).svgView!!
22
+ } else {
23
+ rootSvgView.parent as SvgView
24
+ }
25
+ }
26
+
27
+ return rootSvgView
28
+ }
29
+
30
+ fun isSvgElement(view: Any): Boolean {
31
+ return (view is VirtualView || view is SvgView)
32
+ }
33
+
34
+ fun hitTest(view: View, posX: Float, posY: Float): Boolean {
35
+ val rootSvgView = getRootSvgView(view)
36
+ val viewLocation = intArrayOf(0, 0)
37
+ val rootLocation = intArrayOf(0, 0)
38
+
39
+ view.getLocationOnScreen(viewLocation)
40
+ rootSvgView.getLocationOnScreen(rootLocation)
41
+
42
+ // convert View-relative coordinates into SvgView-relative coordinates
43
+ val rootX = posX + viewLocation[0] - rootLocation[0]
44
+ val rootY = posY + viewLocation[1] - rootLocation[1]
45
+
46
+ val pressedId = rootSvgView.reactTagForTouch(rootX, rootY)
47
+ val hasBeenPressed = view.id == pressedId
48
+
49
+ // hitTest(view, ...) should only be called after isSvgElement(view) returns true
50
+ // Consequently, `view` will always be either SvgView or VirtualView
51
+
52
+ val pressIsInBounds =
53
+ posX in 0.0..view.width.toDouble() &&
54
+ posY in 0.0..view.height.toDouble()
55
+
56
+ if (view is SvgView) {
57
+ val childrenIds = view.children.map { it.id }
58
+
59
+ val hasChildBeenPressed = pressedId in childrenIds
60
+
61
+ return (hasBeenPressed || hasChildBeenPressed) && pressIsInBounds
62
+ }
63
+
64
+ return hasBeenPressed && pressIsInBounds
65
+ }
66
+ }
67
+ }
@@ -13,7 +13,8 @@
13
13
  NS_ASSUME_NONNULL_BEGIN
14
14
 
15
15
  @interface RNGestureHandlerButtonComponentView : RCTViewComponentView
16
-
16
+ - (void)setAccessibilityProps:(const facebook::react::Props::Shared &)props
17
+ oldProps:(const facebook::react::Props::Shared &)oldProps;
17
18
  @end
18
19
 
19
20
  NS_ASSUME_NONNULL_END
@@ -101,6 +101,100 @@ using namespace facebook::react;
101
101
  return concreteComponentDescriptorProvider<RNGestureHandlerButtonComponentDescriptor>();
102
102
  }
103
103
 
104
+ #if TARGET_OS_IOS
105
+ // Taken from
106
+ // https://github.com/facebook/react-native/blob/b226049a4a28ea3f7f32266269fb76340c324d42/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm#L343
107
+ - (void)setAccessibilityProps:(const Props::Shared &)props oldProps:(const Props::Shared &)oldProps
108
+ {
109
+ const auto &oldButtonProps = *std::static_pointer_cast<const RNGestureHandlerButtonProps>(oldProps);
110
+ const auto &newButtonProps = *std::static_pointer_cast<const RNGestureHandlerButtonProps>(props);
111
+
112
+ if (!oldProps || oldButtonProps.accessible != newButtonProps.accessible) {
113
+ _buttonView.isAccessibilityElement = newButtonProps.accessible;
114
+ }
115
+
116
+ if (!oldProps || oldButtonProps.accessibilityLabel != newButtonProps.accessibilityLabel) {
117
+ _buttonView.accessibilityLabel = RCTNSStringFromStringNilIfEmpty(newButtonProps.accessibilityLabel);
118
+ }
119
+
120
+ if (!oldProps || oldButtonProps.accessibilityLanguage != newButtonProps.accessibilityLanguage) {
121
+ _buttonView.accessibilityLanguage = RCTNSStringFromStringNilIfEmpty(newButtonProps.accessibilityLanguage);
122
+ }
123
+
124
+ if (!oldProps || oldButtonProps.accessibilityHint != newButtonProps.accessibilityHint) {
125
+ _buttonView.accessibilityHint = RCTNSStringFromStringNilIfEmpty(newButtonProps.accessibilityHint);
126
+ }
127
+
128
+ if (!oldProps || oldButtonProps.accessibilityViewIsModal != newButtonProps.accessibilityViewIsModal) {
129
+ _buttonView.accessibilityViewIsModal = newButtonProps.accessibilityViewIsModal;
130
+ }
131
+
132
+ if (!oldProps || oldButtonProps.accessibilityElementsHidden != newButtonProps.accessibilityElementsHidden) {
133
+ _buttonView.accessibilityElementsHidden = newButtonProps.accessibilityElementsHidden;
134
+ }
135
+
136
+ if (!oldProps ||
137
+ oldButtonProps.accessibilityShowsLargeContentViewer != newButtonProps.accessibilityShowsLargeContentViewer) {
138
+ if (@available(iOS 13.0, *)) {
139
+ if (newButtonProps.accessibilityShowsLargeContentViewer) {
140
+ _buttonView.showsLargeContentViewer = YES;
141
+ UILargeContentViewerInteraction *interaction = [[UILargeContentViewerInteraction alloc] init];
142
+ [_buttonView addInteraction:interaction];
143
+ } else {
144
+ _buttonView.showsLargeContentViewer = NO;
145
+ }
146
+ }
147
+ }
148
+
149
+ if (!oldProps || oldButtonProps.accessibilityLargeContentTitle != newButtonProps.accessibilityLargeContentTitle) {
150
+ if (@available(iOS 13.0, *)) {
151
+ _buttonView.largeContentTitle = RCTNSStringFromStringNilIfEmpty(newButtonProps.accessibilityLargeContentTitle);
152
+ }
153
+ }
154
+
155
+ if (!oldProps || oldButtonProps.accessibilityTraits != newButtonProps.accessibilityTraits) {
156
+ _buttonView.accessibilityTraits =
157
+ RCTUIAccessibilityTraitsFromAccessibilityTraits(newButtonProps.accessibilityTraits);
158
+ }
159
+
160
+ if (!oldProps || oldButtonProps.accessibilityState != newButtonProps.accessibilityState) {
161
+ _buttonView.accessibilityTraits &= ~(UIAccessibilityTraitNotEnabled | UIAccessibilityTraitSelected);
162
+ const auto accessibilityState = newButtonProps.accessibilityState.value_or(AccessibilityState{});
163
+ if (accessibilityState.selected) {
164
+ _buttonView.accessibilityTraits |= UIAccessibilityTraitSelected;
165
+ }
166
+ if (accessibilityState.disabled) {
167
+ _buttonView.accessibilityTraits |= UIAccessibilityTraitNotEnabled;
168
+ }
169
+ }
170
+
171
+ if (!oldProps || oldButtonProps.accessibilityIgnoresInvertColors != newButtonProps.accessibilityIgnoresInvertColors) {
172
+ _buttonView.accessibilityIgnoresInvertColors = newButtonProps.accessibilityIgnoresInvertColors;
173
+ }
174
+
175
+ if (!oldProps || oldButtonProps.accessibilityValue != newButtonProps.accessibilityValue) {
176
+ if (newButtonProps.accessibilityValue.text.has_value()) {
177
+ _buttonView.accessibilityValue = RCTNSStringFromStringNilIfEmpty(newButtonProps.accessibilityValue.text.value());
178
+ } else if (
179
+ newButtonProps.accessibilityValue.now.has_value() && newButtonProps.accessibilityValue.min.has_value() &&
180
+ newButtonProps.accessibilityValue.max.has_value()) {
181
+ CGFloat val = (CGFloat)(newButtonProps.accessibilityValue.now.value()) /
182
+ (newButtonProps.accessibilityValue.max.value() - newButtonProps.accessibilityValue.min.value());
183
+ _buttonView.accessibilityValue = [NSNumberFormatter localizedStringFromNumber:@(val)
184
+ numberStyle:NSNumberFormatterPercentStyle];
185
+ ;
186
+ } else {
187
+ _buttonView.accessibilityValue = nil;
188
+ }
189
+ }
190
+
191
+ if (!oldProps || oldButtonProps.testId != newButtonProps.testId) {
192
+ UIView *accessibilityView = (UIView *)_buttonView;
193
+ accessibilityView.accessibilityIdentifier = RCTNSStringFromString(newButtonProps.testId);
194
+ }
195
+ }
196
+ #endif
197
+
104
198
  - (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &)oldProps
105
199
  {
106
200
  const auto &newProps = *std::static_pointer_cast<const RNGestureHandlerButtonProps>(props);
@@ -108,6 +202,7 @@ using namespace facebook::react;
108
202
  _buttonView.userEnabled = newProps.enabled;
109
203
  #if !TARGET_OS_TV && !TARGET_OS_OSX
110
204
  _buttonView.exclusiveTouch = newProps.exclusive;
205
+ [self setAccessibilityProps:props oldProps:oldProps];
111
206
  #endif
112
207
  _buttonView.hitTestEdgeInsets = UIEdgeInsetsMake(
113
208
  -newProps.hitSlop.top, -newProps.hitSlop.left, -newProps.hitSlop.bottom, -newProps.hitSlop.right);
@@ -143,12 +143,15 @@ _defineProperty(InnerBaseButton, "defaultProps", {
143
143
  delayLongPress: 600
144
144
  });
145
145
 
146
+ const AnimatedInnerBaseButton = _reactNative.Animated.createAnimatedComponent(InnerBaseButton);
147
+
146
148
  const BaseButton = /*#__PURE__*/React.forwardRef((props, ref) => /*#__PURE__*/React.createElement(InnerBaseButton, _extends({
147
149
  innerRef: ref
148
150
  }, props)));
149
151
  exports.BaseButton = BaseButton;
150
-
151
- const AnimatedBaseButton = _reactNative.Animated.createAnimatedComponent(BaseButton);
152
+ const AnimatedBaseButton = /*#__PURE__*/React.forwardRef((props, ref) => /*#__PURE__*/React.createElement(AnimatedInnerBaseButton, _extends({
153
+ innerRef: ref
154
+ }, props)));
152
155
 
153
156
  const btnStyles = _reactNative.StyleSheet.create({
154
157
  underlay: {
@@ -244,8 +247,6 @@ class InnerBorderlessButton extends React.Component {
244
247
  ...rest
245
248
  } = this.props;
246
249
  return /*#__PURE__*/React.createElement(AnimatedBaseButton, _extends({}, rest, {
247
- // @ts-ignore We don't want `innerRef` to be accessible from public API.
248
- // However in this case we need to set it indirectly on `BaseButton`, hence we use ts-ignore
249
250
  innerRef: innerRef,
250
251
  onActiveStateChange: this.onActiveStateChange,
251
252
  style: [style, _reactNative.Platform.OS === 'ios' && {
@@ -1 +1 @@
1
- {"version":3,"sources":["GestureButtons.tsx"],"names":["RawButton","GestureHandlerButton","shouldCancelWhenOutside","shouldActivateOnStart","IS_FABRIC","InnerBaseButton","React","Component","constructor","props","nativeEvent","state","oldState","pointerInside","active","State","ACTIVE","lastActive","onActiveStateChange","longPressDetected","CANCELLED","onPress","Platform","OS","BEGAN","onLongPress","longPressTimeout","setTimeout","delayLongPress","undefined","clearTimeout","END","FAILED","e","onHandlerStateChange","handleEvent","onGestureEvent","render","rippleColor","unprocessedRippleColor","style","rest","innerRef","cursor","BaseButton","forwardRef","ref","AnimatedBaseButton","Animated","createAnimatedComponent","btnStyles","StyleSheet","create","underlay","position","left","right","bottom","top","InnerRectButton","opacity","setValue","activeOpacity","Value","children","resolvedStyle","flatten","backgroundColor","underlayColor","borderRadius","borderTopLeftRadius","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius","RectButton","InnerBorderlessButton","borderless","BorderlessButton"],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport { Animated, Platform, processColor, StyleSheet } from 'react-native';\n\nimport createNativeWrapper from '../handlers/createNativeWrapper';\nimport GestureHandlerButton from './GestureHandlerButton';\nimport { State } from '../State';\n\nimport {\n GestureEvent,\n HandlerStateChangeEvent,\n} from '../handlers/gestureHandlerCommon';\nimport type { NativeViewGestureHandlerPayload } from '../handlers/GestureHandlerEventPayload';\nimport type {\n BaseButtonWithRefProps,\n BaseButtonProps,\n RectButtonWithRefProps,\n RectButtonProps,\n BorderlessButtonWithRefProps,\n BorderlessButtonProps,\n} from './GestureButtonsProps';\nimport { isFabric } from '../utils';\n\nexport const RawButton = createNativeWrapper(GestureHandlerButton, {\n shouldCancelWhenOutside: false,\n shouldActivateOnStart: false,\n});\n\nlet IS_FABRIC: null | boolean = null;\n\nclass InnerBaseButton extends React.Component<BaseButtonWithRefProps> {\n static defaultProps = {\n delayLongPress: 600,\n };\n\n private lastActive: boolean;\n private longPressTimeout: ReturnType<typeof setTimeout> | undefined;\n private longPressDetected: boolean;\n\n constructor(props: BaseButtonProps) {\n super(props);\n this.lastActive = false;\n this.longPressDetected = false;\n }\n\n private handleEvent = ({\n nativeEvent,\n }: HandlerStateChangeEvent<NativeViewGestureHandlerPayload>) => {\n const { state, oldState, pointerInside } = nativeEvent;\n const active = pointerInside && state === State.ACTIVE;\n\n if (active !== this.lastActive && this.props.onActiveStateChange) {\n this.props.onActiveStateChange(active);\n }\n\n if (\n !this.longPressDetected &&\n oldState === State.ACTIVE &&\n state !== State.CANCELLED &&\n this.lastActive &&\n this.props.onPress\n ) {\n this.props.onPress(pointerInside);\n }\n\n if (\n !this.lastActive &&\n // NativeViewGestureHandler sends different events based on platform\n state === (Platform.OS !== 'android' ? State.ACTIVE : State.BEGAN) &&\n pointerInside\n ) {\n this.longPressDetected = false;\n if (this.props.onLongPress) {\n this.longPressTimeout = setTimeout(\n this.onLongPress,\n this.props.delayLongPress\n );\n }\n } else if (\n // Cancel longpress timeout if it's set and the finger moved out of the view\n state === State.ACTIVE &&\n !pointerInside &&\n this.longPressTimeout !== undefined\n ) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = undefined;\n } else if (\n // Cancel longpress timeout if it's set and the gesture has finished\n this.longPressTimeout !== undefined &&\n (state === State.END ||\n state === State.CANCELLED ||\n state === State.FAILED)\n ) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = undefined;\n }\n\n this.lastActive = active;\n };\n\n private onLongPress = () => {\n this.longPressDetected = true;\n this.props.onLongPress?.();\n };\n\n // Normally, the parent would execute it's handler first, then forward the\n // event to listeners. However, here our handler is virtually only forwarding\n // events to listeners, so we reverse the order to keep the proper order of\n // the callbacks (from \"raw\" ones to \"processed\").\n private onHandlerStateChange = (\n e: HandlerStateChangeEvent<NativeViewGestureHandlerPayload>\n ) => {\n this.props.onHandlerStateChange?.(e);\n this.handleEvent(e);\n };\n\n private onGestureEvent = (\n e: GestureEvent<NativeViewGestureHandlerPayload>\n ) => {\n this.props.onGestureEvent?.(e);\n this.handleEvent(\n e as HandlerStateChangeEvent<NativeViewGestureHandlerPayload>\n ); // TODO: maybe it is not correct\n };\n\n render() {\n const { rippleColor: unprocessedRippleColor, style, ...rest } = this.props;\n\n if (IS_FABRIC === null) {\n IS_FABRIC = isFabric();\n }\n\n const rippleColor = IS_FABRIC\n ? unprocessedRippleColor\n : processColor(unprocessedRippleColor ?? undefined);\n\n return (\n <RawButton\n ref={this.props.innerRef}\n rippleColor={rippleColor}\n style={[style, Platform.OS === 'ios' && { cursor: undefined }]}\n {...rest}\n onGestureEvent={this.onGestureEvent}\n onHandlerStateChange={this.onHandlerStateChange}\n />\n );\n }\n}\n\nexport const BaseButton = React.forwardRef<\n any,\n Omit<BaseButtonProps, 'innerRef'>\n>((props, ref) => <InnerBaseButton innerRef={ref} {...props} />);\n\nconst AnimatedBaseButton = Animated.createAnimatedComponent(BaseButton);\n\nconst btnStyles = StyleSheet.create({\n underlay: {\n position: 'absolute',\n left: 0,\n right: 0,\n bottom: 0,\n top: 0,\n },\n});\n\nclass InnerRectButton extends React.Component<RectButtonWithRefProps> {\n static defaultProps = {\n activeOpacity: 0.105,\n underlayColor: 'black',\n };\n\n private opacity: Animated.Value;\n\n constructor(props: RectButtonProps) {\n super(props);\n this.opacity = new Animated.Value(0);\n }\n\n private onActiveStateChange = (active: boolean) => {\n if (Platform.OS !== 'android') {\n this.opacity.setValue(active ? this.props.activeOpacity! : 0);\n }\n\n this.props.onActiveStateChange?.(active);\n };\n\n render() {\n const { children, style, ...rest } = this.props;\n\n const resolvedStyle = StyleSheet.flatten(style ?? {});\n\n return (\n <BaseButton\n {...rest}\n ref={this.props.innerRef}\n style={resolvedStyle}\n onActiveStateChange={this.onActiveStateChange}>\n <Animated.View\n style={[\n btnStyles.underlay,\n {\n opacity: this.opacity,\n backgroundColor: this.props.underlayColor,\n borderRadius: resolvedStyle.borderRadius,\n borderTopLeftRadius: resolvedStyle.borderTopLeftRadius,\n borderTopRightRadius: resolvedStyle.borderTopRightRadius,\n borderBottomLeftRadius: resolvedStyle.borderBottomLeftRadius,\n borderBottomRightRadius: resolvedStyle.borderBottomRightRadius,\n },\n ]}\n />\n {children}\n </BaseButton>\n );\n }\n}\n\nexport const RectButton = React.forwardRef<\n any,\n Omit<RectButtonProps, 'innerRef'>\n>((props, ref) => <InnerRectButton innerRef={ref} {...props} />);\n\nclass InnerBorderlessButton extends React.Component<BorderlessButtonWithRefProps> {\n static defaultProps = {\n activeOpacity: 0.3,\n borderless: true,\n };\n\n private opacity: Animated.Value;\n\n constructor(props: BorderlessButtonProps) {\n super(props);\n this.opacity = new Animated.Value(1);\n }\n\n private onActiveStateChange = (active: boolean) => {\n if (Platform.OS !== 'android') {\n this.opacity.setValue(active ? this.props.activeOpacity! : 1);\n }\n\n this.props.onActiveStateChange?.(active);\n };\n\n render() {\n const { children, style, innerRef, ...rest } = this.props;\n\n return (\n <AnimatedBaseButton\n {...rest}\n // @ts-ignore We don't want `innerRef` to be accessible from public API.\n // However in this case we need to set it indirectly on `BaseButton`, hence we use ts-ignore\n innerRef={innerRef}\n onActiveStateChange={this.onActiveStateChange}\n style={[style, Platform.OS === 'ios' && { opacity: this.opacity }]}>\n {children}\n </AnimatedBaseButton>\n );\n }\n}\n\nexport const BorderlessButton = React.forwardRef<\n any,\n Omit<BorderlessButtonProps, 'innerRef'>\n>((props, ref) => <InnerBorderlessButton innerRef={ref} {...props} />);\n\nexport { default as PureNativeButton } from './GestureHandlerButton';\n"]}
1
+ {"version":3,"sources":["GestureButtons.tsx"],"names":["RawButton","GestureHandlerButton","shouldCancelWhenOutside","shouldActivateOnStart","IS_FABRIC","InnerBaseButton","React","Component","constructor","props","nativeEvent","state","oldState","pointerInside","active","State","ACTIVE","lastActive","onActiveStateChange","longPressDetected","CANCELLED","onPress","Platform","OS","BEGAN","onLongPress","longPressTimeout","setTimeout","delayLongPress","undefined","clearTimeout","END","FAILED","e","onHandlerStateChange","handleEvent","onGestureEvent","render","rippleColor","unprocessedRippleColor","style","rest","innerRef","cursor","AnimatedInnerBaseButton","Animated","createAnimatedComponent","BaseButton","forwardRef","ref","AnimatedBaseButton","btnStyles","StyleSheet","create","underlay","position","left","right","bottom","top","InnerRectButton","opacity","setValue","activeOpacity","Value","children","resolvedStyle","flatten","backgroundColor","underlayColor","borderRadius","borderTopLeftRadius","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius","RectButton","InnerBorderlessButton","borderless","BorderlessButton"],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport { Animated, Platform, processColor, StyleSheet } from 'react-native';\n\nimport createNativeWrapper from '../handlers/createNativeWrapper';\nimport GestureHandlerButton from './GestureHandlerButton';\nimport { State } from '../State';\n\nimport {\n GestureEvent,\n HandlerStateChangeEvent,\n} from '../handlers/gestureHandlerCommon';\nimport type { NativeViewGestureHandlerPayload } from '../handlers/GestureHandlerEventPayload';\nimport type {\n BaseButtonWithRefProps,\n BaseButtonProps,\n RectButtonWithRefProps,\n RectButtonProps,\n BorderlessButtonWithRefProps,\n BorderlessButtonProps,\n} from './GestureButtonsProps';\nimport { isFabric } from '../utils';\n\nexport const RawButton = createNativeWrapper(GestureHandlerButton, {\n shouldCancelWhenOutside: false,\n shouldActivateOnStart: false,\n});\n\nlet IS_FABRIC: null | boolean = null;\n\nclass InnerBaseButton extends React.Component<BaseButtonWithRefProps> {\n static defaultProps = {\n delayLongPress: 600,\n };\n\n private lastActive: boolean;\n private longPressTimeout: ReturnType<typeof setTimeout> | undefined;\n private longPressDetected: boolean;\n\n constructor(props: BaseButtonWithRefProps) {\n super(props);\n this.lastActive = false;\n this.longPressDetected = false;\n }\n\n private handleEvent = ({\n nativeEvent,\n }: HandlerStateChangeEvent<NativeViewGestureHandlerPayload>) => {\n const { state, oldState, pointerInside } = nativeEvent;\n const active = pointerInside && state === State.ACTIVE;\n\n if (active !== this.lastActive && this.props.onActiveStateChange) {\n this.props.onActiveStateChange(active);\n }\n\n if (\n !this.longPressDetected &&\n oldState === State.ACTIVE &&\n state !== State.CANCELLED &&\n this.lastActive &&\n this.props.onPress\n ) {\n this.props.onPress(pointerInside);\n }\n\n if (\n !this.lastActive &&\n // NativeViewGestureHandler sends different events based on platform\n state === (Platform.OS !== 'android' ? State.ACTIVE : State.BEGAN) &&\n pointerInside\n ) {\n this.longPressDetected = false;\n if (this.props.onLongPress) {\n this.longPressTimeout = setTimeout(\n this.onLongPress,\n this.props.delayLongPress\n );\n }\n } else if (\n // Cancel longpress timeout if it's set and the finger moved out of the view\n state === State.ACTIVE &&\n !pointerInside &&\n this.longPressTimeout !== undefined\n ) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = undefined;\n } else if (\n // Cancel longpress timeout if it's set and the gesture has finished\n this.longPressTimeout !== undefined &&\n (state === State.END ||\n state === State.CANCELLED ||\n state === State.FAILED)\n ) {\n clearTimeout(this.longPressTimeout);\n this.longPressTimeout = undefined;\n }\n\n this.lastActive = active;\n };\n\n private onLongPress = () => {\n this.longPressDetected = true;\n this.props.onLongPress?.();\n };\n\n // Normally, the parent would execute it's handler first, then forward the\n // event to listeners. However, here our handler is virtually only forwarding\n // events to listeners, so we reverse the order to keep the proper order of\n // the callbacks (from \"raw\" ones to \"processed\").\n private onHandlerStateChange = (\n e: HandlerStateChangeEvent<NativeViewGestureHandlerPayload>\n ) => {\n this.props.onHandlerStateChange?.(e);\n this.handleEvent(e);\n };\n\n private onGestureEvent = (\n e: GestureEvent<NativeViewGestureHandlerPayload>\n ) => {\n this.props.onGestureEvent?.(e);\n this.handleEvent(\n e as HandlerStateChangeEvent<NativeViewGestureHandlerPayload>\n ); // TODO: maybe it is not correct\n };\n\n render() {\n const { rippleColor: unprocessedRippleColor, style, ...rest } = this.props;\n\n if (IS_FABRIC === null) {\n IS_FABRIC = isFabric();\n }\n\n const rippleColor = IS_FABRIC\n ? unprocessedRippleColor\n : processColor(unprocessedRippleColor ?? undefined);\n\n return (\n <RawButton\n ref={this.props.innerRef}\n rippleColor={rippleColor}\n style={[style, Platform.OS === 'ios' && { cursor: undefined }]}\n {...rest}\n onGestureEvent={this.onGestureEvent}\n onHandlerStateChange={this.onHandlerStateChange}\n />\n );\n }\n}\n\nconst AnimatedInnerBaseButton =\n Animated.createAnimatedComponent<typeof InnerBaseButton>(InnerBaseButton);\n\nexport const BaseButton = React.forwardRef<\n React.ComponentType,\n Omit<BaseButtonProps, 'innerRef'>\n>((props, ref) => <InnerBaseButton innerRef={ref} {...props} />);\n\nconst AnimatedBaseButton = React.forwardRef<\n React.ComponentType,\n BaseButtonWithRefProps\n>((props, ref) => <AnimatedInnerBaseButton innerRef={ref} {...props} />);\n\nconst btnStyles = StyleSheet.create({\n underlay: {\n position: 'absolute',\n left: 0,\n right: 0,\n bottom: 0,\n top: 0,\n },\n});\n\nclass InnerRectButton extends React.Component<RectButtonWithRefProps> {\n static defaultProps = {\n activeOpacity: 0.105,\n underlayColor: 'black',\n };\n\n private opacity: Animated.Value;\n\n constructor(props: RectButtonWithRefProps) {\n super(props);\n this.opacity = new Animated.Value(0);\n }\n\n private onActiveStateChange = (active: boolean) => {\n if (Platform.OS !== 'android') {\n this.opacity.setValue(active ? this.props.activeOpacity! : 0);\n }\n\n this.props.onActiveStateChange?.(active);\n };\n\n render() {\n const { children, style, ...rest } = this.props;\n\n const resolvedStyle = StyleSheet.flatten(style ?? {});\n\n return (\n <BaseButton\n {...rest}\n ref={this.props.innerRef}\n style={resolvedStyle}\n onActiveStateChange={this.onActiveStateChange}>\n <Animated.View\n style={[\n btnStyles.underlay,\n {\n opacity: this.opacity,\n backgroundColor: this.props.underlayColor,\n borderRadius: resolvedStyle.borderRadius,\n borderTopLeftRadius: resolvedStyle.borderTopLeftRadius,\n borderTopRightRadius: resolvedStyle.borderTopRightRadius,\n borderBottomLeftRadius: resolvedStyle.borderBottomLeftRadius,\n borderBottomRightRadius: resolvedStyle.borderBottomRightRadius,\n },\n ]}\n />\n {children}\n </BaseButton>\n );\n }\n}\n\nexport const RectButton = React.forwardRef<\n React.ComponentType,\n Omit<RectButtonProps, 'innerRef'>\n>((props, ref) => <InnerRectButton innerRef={ref} {...props} />);\n\nclass InnerBorderlessButton extends React.Component<BorderlessButtonWithRefProps> {\n static defaultProps = {\n activeOpacity: 0.3,\n borderless: true,\n };\n\n private opacity: Animated.Value;\n\n constructor(props: BorderlessButtonWithRefProps) {\n super(props);\n this.opacity = new Animated.Value(1);\n }\n\n private onActiveStateChange = (active: boolean) => {\n if (Platform.OS !== 'android') {\n this.opacity.setValue(active ? this.props.activeOpacity! : 1);\n }\n\n this.props.onActiveStateChange?.(active);\n };\n\n render() {\n const { children, style, innerRef, ...rest } = this.props;\n\n return (\n <AnimatedBaseButton\n {...rest}\n innerRef={innerRef}\n onActiveStateChange={this.onActiveStateChange}\n style={[style, Platform.OS === 'ios' && { opacity: this.opacity }]}>\n {children}\n </AnimatedBaseButton>\n );\n }\n}\n\nexport const BorderlessButton = React.forwardRef<\n React.ComponentType,\n Omit<BorderlessButtonProps, 'innerRef'>\n>((props, ref) => <InnerBorderlessButton innerRef={ref} {...props} />);\n\nexport { default as PureNativeButton } from './GestureHandlerButton';\n"]}