@react-native-oh-tpl/react-native-gesture-handler 2.12.6-1 → 2.12.9

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 (211) hide show
  1. package/harmony/gesture_handler/BuildProfile.ets +5 -0
  2. package/harmony/gesture_handler/build-profile.json5 +18 -7
  3. package/harmony/gesture_handler/hvigorfile.ts +2 -2
  4. package/harmony/gesture_handler/index.ets +3 -3
  5. package/harmony/gesture_handler/oh-package-lock.json5 +17 -0
  6. package/harmony/gesture_handler/oh-package.json5 +12 -11
  7. package/harmony/gesture_handler/src/main/cpp/CMakeLists.txt +8 -8
  8. package/harmony/gesture_handler/src/main/cpp/GestureHandlerPackage.cpp +103 -34
  9. package/harmony/gesture_handler/src/main/cpp/GestureHandlerPackage.h +21 -15
  10. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerButtonComponentDescriptor.h +36 -60
  11. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerButtonComponentInstance.h +27 -0
  12. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerButtonJSIBinder.h +32 -0
  13. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerModule.cpp +22 -17
  14. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerModule.h +15 -12
  15. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerPackage.h +72 -0
  16. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerRootViewComponentDescriptor.h +36 -60
  17. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerRootViewComponentInstance.h +78 -0
  18. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerRootViewJSIBinder.h +25 -0
  19. package/harmony/gesture_handler/src/main/ets/CircularBuffer.ts +42 -42
  20. package/harmony/gesture_handler/src/main/ets/Event.ts +67 -67
  21. package/harmony/gesture_handler/src/main/ets/EventDispatcher.ts +52 -37
  22. package/harmony/gesture_handler/src/main/ets/GestureHandler.ts +663 -663
  23. package/harmony/gesture_handler/src/main/ets/{GestureHandlerArkUIAdapter.ets → GestureHandlerArkUIAdapter.ts} +202 -201
  24. package/harmony/gesture_handler/src/main/ets/GestureHandlerFactory.ts +44 -44
  25. package/harmony/gesture_handler/src/main/ets/GestureHandlerOrchestrator.ts +280 -280
  26. package/harmony/gesture_handler/src/main/ets/GestureHandlerPackage.ts +22 -22
  27. package/harmony/gesture_handler/src/main/ets/GestureHandlerRegistry.ts +27 -27
  28. package/harmony/gesture_handler/src/main/ets/InteractionManager.ts +108 -108
  29. package/harmony/gesture_handler/src/main/ets/LeastSquareSolver.ts +182 -182
  30. package/harmony/gesture_handler/src/main/ets/NativeViewGestureHandler.ts +114 -114
  31. package/harmony/gesture_handler/src/main/ets/OutgoingEvent.ts +33 -33
  32. package/harmony/gesture_handler/src/main/ets/PanGestureHandler.ts +327 -327
  33. package/harmony/gesture_handler/src/main/ets/PointerTracker.ts +239 -239
  34. package/harmony/gesture_handler/src/main/ets/RNGHError.ts +4 -4
  35. package/harmony/gesture_handler/src/main/ets/RNGHLogger.ts +47 -28
  36. package/harmony/gesture_handler/src/main/ets/{RNGHRootTouchHandler.ets → RNGHRootTouchHandlerArkTS.ts} +59 -57
  37. package/harmony/gesture_handler/src/main/ets/RNGHRootTouchHandlerCAPI.ts +87 -0
  38. package/harmony/gesture_handler/src/main/ets/RNGestureHandlerButton.ets +37 -36
  39. package/harmony/gesture_handler/src/main/ets/RNGestureHandlerModule.ts +183 -125
  40. package/harmony/gesture_handler/src/main/ets/RNGestureHandlerRootView.ets +52 -55
  41. package/harmony/gesture_handler/src/main/ets/RNOHScrollLocker.ts +23 -11
  42. package/harmony/gesture_handler/src/main/ets/State.ts +46 -46
  43. package/harmony/gesture_handler/src/main/ets/TapGestureHandler.ts +205 -205
  44. package/harmony/gesture_handler/src/main/ets/Vector2D.ts +36 -36
  45. package/harmony/gesture_handler/src/main/ets/VelocityTracker.ts +98 -98
  46. package/harmony/gesture_handler/src/main/ets/View.ts +70 -70
  47. package/harmony/gesture_handler/src/main/ets/ViewRegistry.ts +42 -42
  48. package/harmony/gesture_handler/src/main/ets/namespace/RNGestureHandlerButton.ts +140 -0
  49. package/harmony/gesture_handler/src/main/ets/namespace/RNGestureHandlerModule.ts +25 -0
  50. package/harmony/gesture_handler/src/main/ets/namespace/RNGestureHandlerRootView.ts +101 -0
  51. package/harmony/gesture_handler/src/main/ets/namespace/ts.ts +3 -0
  52. package/harmony/gesture_handler/src/main/ets/pages/Index.ets +16 -16
  53. package/harmony/gesture_handler/src/main/ets/types.ts +25 -0
  54. package/harmony/gesture_handler/src/main/ets/webviewability/WebviewAbility.ts +41 -41
  55. package/harmony/gesture_handler/src/main/module.json5 +7 -7
  56. package/harmony/gesture_handler/src/main/resources/base/element/color.json +7 -7
  57. package/harmony/gesture_handler/src/main/resources/base/element/string.json +15 -15
  58. package/harmony/gesture_handler/src/main/resources/base/profile/main_pages.json +5 -5
  59. package/harmony/gesture_handler/src/main/resources/en_US/element/string.json +15 -15
  60. package/harmony/gesture_handler/src/main/resources/zh_CN/element/string.json +15 -15
  61. package/harmony/gesture_handler/ts.ts +2 -1
  62. package/harmony/gesture_handler.har +0 -0
  63. package/lib/commonjs/RNGestureHandlerModule.js +6 -3
  64. package/lib/commonjs/RNGestureHandlerModule.js.map +1 -1
  65. package/lib/commonjs/components/GestureHandlerRootView.js +5 -13
  66. package/lib/commonjs/components/GestureHandlerRootView.js.map +1 -1
  67. package/lib/commonjs/handlers/createHandler.js +31 -28
  68. package/lib/commonjs/handlers/createHandler.js.map +1 -1
  69. package/lib/commonjs/index.js +42 -19
  70. package/lib/commonjs/index.js.map +1 -1
  71. package/lib/commonjs/specs/NativeRNGestureHandlerModule.js +10 -0
  72. package/lib/commonjs/specs/NativeRNGestureHandlerModule.js.map +1 -0
  73. package/lib/commonjs/specs/RNGestureHandlerButtonNativeComponent.js +11 -0
  74. package/lib/commonjs/specs/RNGestureHandlerButtonNativeComponent.js.map +1 -0
  75. package/lib/commonjs/specs/RNGestureHandlerRootViewNativeComponent.js +11 -0
  76. package/lib/commonjs/specs/RNGestureHandlerRootViewNativeComponent.js.map +1 -0
  77. package/lib/module/RNGestureHandlerModule.js +3 -2
  78. package/lib/module/RNGestureHandlerModule.js.map +1 -1
  79. package/lib/module/components/GestureHandlerRootView.js +3 -11
  80. package/lib/module/components/GestureHandlerRootView.js.map +1 -1
  81. package/lib/module/handlers/createHandler.js +20 -19
  82. package/lib/module/handlers/createHandler.js.map +1 -1
  83. package/lib/module/index.js +6 -14
  84. package/lib/module/index.js.map +1 -1
  85. package/lib/module/specs/NativeRNGestureHandlerModule.js +3 -0
  86. package/lib/module/specs/NativeRNGestureHandlerModule.js.map +1 -0
  87. package/lib/module/specs/RNGestureHandlerButtonNativeComponent.js +3 -0
  88. package/lib/module/specs/RNGestureHandlerButtonNativeComponent.js.map +1 -0
  89. package/lib/module/specs/RNGestureHandlerRootViewNativeComponent.js +3 -0
  90. package/lib/module/specs/RNGestureHandlerRootViewNativeComponent.js.map +1 -0
  91. package/lib/typescript/RNGestureHandlerModule.d.ts +2 -6
  92. package/lib/typescript/RNGestureHandlerModule.d.ts.map +1 -1
  93. package/lib/typescript/components/GestureHandlerRootView.d.ts +6 -6
  94. package/lib/typescript/components/GestureHandlerRootView.d.ts.map +1 -1
  95. package/lib/typescript/handlers/createHandler.d.ts +11 -11
  96. package/lib/typescript/handlers/createHandler.d.ts.map +1 -1
  97. package/lib/typescript/index.d.ts +9 -8
  98. package/lib/typescript/index.d.ts.map +1 -1
  99. package/lib/typescript/specs/NativeRNGestureHandlerModule.d.ts +15 -0
  100. package/lib/typescript/specs/NativeRNGestureHandlerModule.d.ts.map +1 -0
  101. package/lib/typescript/specs/RNGestureHandlerButtonNativeComponent.d.ts +15 -0
  102. package/lib/typescript/specs/RNGestureHandlerButtonNativeComponent.d.ts.map +1 -0
  103. package/lib/typescript/specs/RNGestureHandlerRootViewNativeComponent.d.ts +7 -0
  104. package/lib/typescript/specs/RNGestureHandlerRootViewNativeComponent.d.ts.map +1 -0
  105. package/package.json +66 -70
  106. package/src/RNGestureHandlerModule.ts +5 -6
  107. package/src/components/GestureHandlerRootView.tsx +23 -34
  108. package/src/handlers/createHandler.tsx +534 -535
  109. package/src/index.ts +172 -172
  110. package/src/specs/NativeRNGestureHandlerModule.ts +26 -0
  111. package/src/specs/RNGestureHandlerButtonNativeComponent.ts +18 -0
  112. package/src/specs/RNGestureHandlerRootViewNativeComponent.ts +6 -0
  113. package/README.md +0 -1
  114. package/lib/commonjs/components/GestureButtons.js +0 -186
  115. package/lib/commonjs/components/GestureButtons.js.map +0 -1
  116. package/lib/commonjs/components/GestureHandlerButton.js +0 -9
  117. package/lib/commonjs/components/GestureHandlerButton.js.map +0 -1
  118. package/lib/commonjs/components/RNGestureHandlerButton.js +0 -23
  119. package/lib/commonjs/components/RNGestureHandlerButton.js.map +0 -1
  120. package/lib/commonjs/components/touchables/GenericTouchable.js +0 -247
  121. package/lib/commonjs/components/touchables/GenericTouchable.js.map +0 -1
  122. package/lib/commonjs/components/touchables/TouchableOpacity.js +0 -58
  123. package/lib/commonjs/components/touchables/TouchableOpacity.js.map +0 -1
  124. package/lib/commonjs/components/touchables/TouchableWithoutFeedback.js +0 -18
  125. package/lib/commonjs/components/touchables/TouchableWithoutFeedback.js.map +0 -1
  126. package/lib/commonjs/components/touchables/index.js +0 -21
  127. package/lib/commonjs/components/touchables/index.js.map +0 -1
  128. package/lib/commonjs/handlers/NativeViewGestureHandler.js +0 -19
  129. package/lib/commonjs/handlers/NativeViewGestureHandler.js.map +0 -1
  130. package/lib/commonjs/handlers/PanGestureHandler.js +0 -103
  131. package/lib/commonjs/handlers/PanGestureHandler.js.map +0 -1
  132. package/lib/commonjs/handlers/TapGestureHandler.js +0 -22
  133. package/lib/commonjs/handlers/TapGestureHandler.js.map +0 -1
  134. package/lib/commonjs/handlers/createNativeWrapper.js +0 -64
  135. package/lib/commonjs/handlers/createNativeWrapper.js.map +0 -1
  136. package/lib/commonjs/handlers/gestureHandlerCommon.js +0 -22
  137. package/lib/commonjs/handlers/gestureHandlerCommon.js.map +0 -1
  138. package/lib/commonjs/handlers/gestures/GestureDetector.js +0 -554
  139. package/lib/commonjs/handlers/gestures/GestureDetector.js.map +0 -1
  140. package/lib/commonjs/init.js +0 -24
  141. package/lib/commonjs/init.js.map +0 -1
  142. package/lib/module/components/GestureButtons.js +0 -168
  143. package/lib/module/components/GestureButtons.js.map +0 -1
  144. package/lib/module/components/GestureHandlerButton.js +0 -3
  145. package/lib/module/components/GestureHandlerButton.js.map +0 -1
  146. package/lib/module/components/RNGestureHandlerButton.js +0 -17
  147. package/lib/module/components/RNGestureHandlerButton.js.map +0 -1
  148. package/lib/module/components/touchables/GenericTouchable.js +0 -238
  149. package/lib/module/components/touchables/GenericTouchable.js.map +0 -1
  150. package/lib/module/components/touchables/TouchableOpacity.js +0 -49
  151. package/lib/module/components/touchables/TouchableOpacity.js.map +0 -1
  152. package/lib/module/components/touchables/TouchableWithoutFeedback.js +0 -9
  153. package/lib/module/components/touchables/TouchableWithoutFeedback.js.map +0 -1
  154. package/lib/module/components/touchables/index.js +0 -8
  155. package/lib/module/components/touchables/index.js.map +0 -1
  156. package/lib/module/handlers/NativeViewGestureHandler.js +0 -12
  157. package/lib/module/handlers/NativeViewGestureHandler.js.map +0 -1
  158. package/lib/module/handlers/PanGestureHandler.js +0 -92
  159. package/lib/module/handlers/PanGestureHandler.js.map +0 -1
  160. package/lib/module/handlers/TapGestureHandler.js +0 -14
  161. package/lib/module/handlers/TapGestureHandler.js.map +0 -1
  162. package/lib/module/handlers/createNativeWrapper.js +0 -57
  163. package/lib/module/handlers/createNativeWrapper.js.map +0 -1
  164. package/lib/module/handlers/gestureHandlerCommon.js +0 -15
  165. package/lib/module/handlers/gestureHandlerCommon.js.map +0 -1
  166. package/lib/module/handlers/gestures/GestureDetector.js +0 -543
  167. package/lib/module/handlers/gestures/GestureDetector.js.map +0 -1
  168. package/lib/module/init.js +0 -17
  169. package/lib/module/init.js.map +0 -1
  170. package/lib/typescript/components/GestureButtons.d.ts +0 -122
  171. package/lib/typescript/components/GestureButtons.d.ts.map +0 -1
  172. package/lib/typescript/components/GestureHandlerButton.d.ts +0 -5
  173. package/lib/typescript/components/GestureHandlerButton.d.ts.map +0 -1
  174. package/lib/typescript/components/RNGestureHandlerButton.d.ts +0 -2
  175. package/lib/typescript/components/RNGestureHandlerButton.d.ts.map +0 -1
  176. package/lib/typescript/components/touchables/GenericTouchable.d.ts +0 -68
  177. package/lib/typescript/components/touchables/GenericTouchable.d.ts.map +0 -1
  178. package/lib/typescript/components/touchables/TouchableOpacity.d.ts +0 -26
  179. package/lib/typescript/components/touchables/TouchableOpacity.d.ts.map +0 -1
  180. package/lib/typescript/components/touchables/TouchableWithoutFeedback.d.ts +0 -8
  181. package/lib/typescript/components/touchables/TouchableWithoutFeedback.d.ts.map +0 -1
  182. package/lib/typescript/components/touchables/index.d.ts +0 -4
  183. package/lib/typescript/components/touchables/index.d.ts.map +0 -1
  184. package/lib/typescript/handlers/NativeViewGestureHandler.d.ts +0 -29
  185. package/lib/typescript/handlers/NativeViewGestureHandler.d.ts.map +0 -1
  186. package/lib/typescript/handlers/PanGestureHandler.d.ts +0 -140
  187. package/lib/typescript/handlers/PanGestureHandler.d.ts.map +0 -1
  188. package/lib/typescript/handlers/TapGestureHandler.d.ts +0 -58
  189. package/lib/typescript/handlers/TapGestureHandler.d.ts.map +0 -1
  190. package/lib/typescript/handlers/createNativeWrapper.d.ts +0 -4
  191. package/lib/typescript/handlers/createNativeWrapper.d.ts.map +0 -1
  192. package/lib/typescript/handlers/gestureHandlerCommon.d.ts +0 -2
  193. package/lib/typescript/handlers/gestureHandlerCommon.d.ts.map +0 -1
  194. package/lib/typescript/handlers/gestures/GestureDetector.d.ts +0 -24
  195. package/lib/typescript/handlers/gestures/GestureDetector.d.ts.map +0 -1
  196. package/lib/typescript/init.d.ts +0 -3
  197. package/lib/typescript/init.d.ts.map +0 -1
  198. package/src/components/GestureButtons.tsx +0 -334
  199. package/src/components/GestureHandlerButton.tsx +0 -5
  200. package/src/components/RNGestureHandlerButton.tsx +0 -23
  201. package/src/components/touchables/GenericTouchable.tsx +0 -301
  202. package/src/components/touchables/TouchableOpacity.tsx +0 -76
  203. package/src/components/touchables/TouchableWithoutFeedback.tsx +0 -14
  204. package/src/components/touchables/index.ts +0 -7
  205. package/src/handlers/NativeViewGestureHandler.ts +0 -55
  206. package/src/handlers/PanGestureHandler.ts +0 -327
  207. package/src/handlers/TapGestureHandler.ts +0 -95
  208. package/src/handlers/createNativeWrapper.tsx +0 -81
  209. package/src/handlers/gestureHandlerCommon.ts +0 -15
  210. package/src/handlers/gestures/GestureDetector.tsx +0 -823
  211. package/src/init.ts +0 -18
@@ -1,535 +1,534 @@
1
- // RNGH: patching the import to RNGestureHandlerModule
2
-
3
- import * as React from 'react';
4
- import {
5
- Platform,
6
- UIManager,
7
- DeviceEventEmitter,
8
- EmitterSubscription,
9
- } from 'react-native';
10
- // @ts-ignore - it isn't typed by TS & don't have definitelyTyped types
11
- import deepEqual from 'lodash/isEqual';
12
- import {RNGestureHandlerModule} from '../RNGestureHandlerModule'; // RNGH: patch
13
- import type RNGestureHandlerModuleWeb from 'react-native-gesture-handler/src/RNGestureHandlerModule.web';
14
- import { State } from 'react-native-gesture-handler/src/State';
15
- import {
16
- handlerIDToTag,
17
- getNextHandlerTag,
18
- registerOldGestureHandler,
19
- } from 'react-native-gesture-handler/src/handlers/handlersRegistry';
20
-
21
- import {
22
- BaseGestureHandlerProps,
23
- filterConfig,
24
- GestureEvent,
25
- HandlerStateChangeEvent,
26
- findNodeHandle,
27
- // scheduleFlushOperations, // RNGH: patch
28
- } from 'react-native-gesture-handler/src/handlers/gestureHandlerCommon';
29
- import { scheduleFlushOperations } from "../handlers/gestureHandlerCommon" // RNGH: patch
30
- import { ValueOf } from 'react-native-gesture-handler/src/typeUtils';
31
- import { isFabric, isJestEnv, tagMessage } from 'react-native-gesture-handler/src/utils';
32
- import { ActionType } from 'react-native-gesture-handler/src/ActionType';
33
- import { PressabilityDebugView } from 'react-native-gesture-handler/src/handlers/PressabilityDebugView';
34
- import GestureHandlerRootViewContext from 'react-native-gesture-handler/src/GestureHandlerRootViewContext';
35
-
36
- const UIManagerAny = UIManager as any;
37
-
38
- const customGHEventsConfigFabricAndroid = {
39
- topOnGestureHandlerEvent: { registrationName: 'onGestureHandlerEvent' },
40
- topOnGestureHandlerStateChange: {
41
- registrationName: 'onGestureHandlerStateChange',
42
- },
43
- };
44
-
45
- const customGHEventsConfig = {
46
- onGestureHandlerEvent: { registrationName: 'onGestureHandlerEvent' },
47
- onGestureHandlerStateChange: {
48
- registrationName: 'onGestureHandlerStateChange',
49
- },
50
-
51
- // When using React Native Gesture Handler for Animated.event with useNativeDriver: true
52
- // on Android with Fabric enabled, the native part still sends the native events to JS
53
- // but prefixed with "top". We cannot simply rename the events above so they are prefixed
54
- // with "top" instead of "on" because in such case Animated.events would not be registered.
55
- // That's why we need to register another pair of event names.
56
- // The incoming events will be queued but never handled.
57
- // Without this piece of code below, you'll get the following JS error:
58
- // Unsupported top level event type "topOnGestureHandlerEvent" dispatched
59
- ...(isFabric() &&
60
- Platform.OS === 'android' &&
61
- customGHEventsConfigFabricAndroid),
62
- };
63
-
64
- // Add gesture specific events to genericDirectEventTypes object exported from UIManager
65
- // native module.
66
- // Once new event types are registered with react it is possible to dispatch these
67
- // events to all kind of native views.
68
- UIManagerAny.genericDirectEventTypes = {
69
- ...UIManagerAny.genericDirectEventTypes,
70
- ...customGHEventsConfig,
71
- };
72
- // In newer versions of RN the `genericDirectEventTypes` is located in the object
73
- // returned by UIManager.getViewManagerConfig('getConstants') or in older RN UIManager.getConstants(), we need to add it there as well to make
74
- // it compatible with RN 61+
75
- const UIManagerConstants =
76
- UIManagerAny.getViewManagerConfig?.('getConstants') ??
77
- UIManagerAny.getConstants?.();
78
-
79
- if (UIManagerConstants) {
80
- UIManagerConstants.genericDirectEventTypes = {
81
- ...UIManagerConstants.genericDirectEventTypes,
82
- ...customGHEventsConfig,
83
- };
84
- }
85
-
86
- // Wrap JS responder calls and notify gesture handler manager
87
- const {
88
- setJSResponder: oldSetJSResponder = () => {
89
- //no operation
90
- },
91
- clearJSResponder: oldClearJSResponder = () => {
92
- //no operation
93
- },
94
- } = UIManagerAny;
95
- UIManagerAny.setJSResponder = (tag: number, blockNativeResponder: boolean) => {
96
- RNGestureHandlerModule.handleSetJSResponder(tag, blockNativeResponder);
97
- oldSetJSResponder(tag, blockNativeResponder);
98
- };
99
- UIManagerAny.clearJSResponder = () => {
100
- RNGestureHandlerModule.handleClearJSResponder();
101
- oldClearJSResponder();
102
- };
103
-
104
- let allowTouches = true;
105
- const DEV_ON_ANDROID = __DEV__ && Platform.OS === 'android';
106
- // Toggled inspector blocks touch events in order to allow inspecting on Android
107
- // This needs to be a global variable in order to set initial state for `allowTouches` property in Handler component
108
- if (DEV_ON_ANDROID) {
109
- DeviceEventEmitter.addListener('toggleElementInspector', () => {
110
- allowTouches = !allowTouches;
111
- });
112
- }
113
-
114
- type HandlerProps<T extends Record<string, unknown>> = Readonly<
115
- React.PropsWithChildren<BaseGestureHandlerProps<T>>
116
- >;
117
- function hasUnresolvedRefs<T extends Record<string, unknown>>(
118
- props: HandlerProps<T>
119
- ) {
120
- // TODO(TS) - add type for extract arg
121
- const extract = (refs: any | any[]) => {
122
- if (!Array.isArray(refs)) {
123
- return refs && refs.current === null;
124
- }
125
- return refs.some((r) => r && r.current === null);
126
- };
127
- return extract(props['simultaneousHandlers']) || extract(props['waitFor']);
128
- }
129
-
130
- const stateToPropMappings = {
131
- [State.UNDETERMINED]: undefined,
132
- [State.BEGAN]: 'onBegan',
133
- [State.FAILED]: 'onFailed',
134
- [State.CANCELLED]: 'onCancelled',
135
- [State.ACTIVE]: 'onActivated',
136
- [State.END]: 'onEnded',
137
- } as const;
138
-
139
- type CreateHandlerArgs<HandlerPropsT extends Record<string, unknown>> =
140
- Readonly<{
141
- name: string;
142
- allowedProps: Readonly<Extract<keyof HandlerPropsT, string>[]>;
143
- config: Readonly<Record<string, unknown>>;
144
- transformProps?: (props: HandlerPropsT) => HandlerPropsT;
145
- customNativeProps?: Readonly<string[]>;
146
- }>;
147
-
148
- // TODO(TS) fix event types
149
- type InternalEventHandlers = {
150
- onGestureHandlerEvent?: (event: any) => void;
151
- onGestureHandlerStateChange?: (event: any) => void;
152
- };
153
-
154
- const UNRESOLVED_REFS_RETRY_LIMIT = 1;
155
-
156
- // TODO(TS) - make sure that BaseGestureHandlerProps doesn't need other generic parameter to work with custom properties.
157
- export default function createHandler<
158
- T extends BaseGestureHandlerProps<U>,
159
- U extends Record<string, unknown>
160
- >({
161
- name,
162
- allowedProps = [],
163
- config = {},
164
- transformProps,
165
- customNativeProps = [],
166
- }: CreateHandlerArgs<T>): React.ComponentType<T & React.RefAttributes<any>> {
167
- interface HandlerState {
168
- allowTouches: boolean;
169
- }
170
- class Handler extends React.Component<
171
- T & InternalEventHandlers,
172
- HandlerState
173
- > {
174
- static displayName = name;
175
- static contextType = GestureHandlerRootViewContext;
176
-
177
- private handlerTag: number;
178
- private config: Record<string, unknown>;
179
- private propsRef: React.MutableRefObject<unknown>;
180
- private isMountedRef: React.MutableRefObject<boolean | null>;
181
- private viewNode: any;
182
- private viewTag?: number;
183
- private inspectorToggleListener?: EmitterSubscription;
184
-
185
- constructor(props: T & InternalEventHandlers) {
186
- super(props);
187
- this.handlerTag = getNextHandlerTag();
188
- this.config = {};
189
- this.propsRef = React.createRef();
190
- this.isMountedRef = React.createRef();
191
- this.state = { allowTouches };
192
- if (props.id) {
193
- if (handlerIDToTag[props.id] !== undefined) {
194
- throw new Error(`Handler with ID "${props.id}" already registered`);
195
- }
196
- handlerIDToTag[props.id] = this.handlerTag;
197
- }
198
- }
199
-
200
- componentDidMount() {
201
- const props: HandlerProps<U> = this.props;
202
- this.isMountedRef.current = true;
203
-
204
- if (DEV_ON_ANDROID) {
205
- this.inspectorToggleListener = DeviceEventEmitter.addListener(
206
- 'toggleElementInspector',
207
- () => {
208
- this.setState((_) => ({ allowTouches }));
209
- this.update(UNRESOLVED_REFS_RETRY_LIMIT);
210
- }
211
- );
212
- }
213
- if (hasUnresolvedRefs(props)) {
214
- // If there are unresolved refs (e.g. ".current" has not yet been set)
215
- // passed as `simultaneousHandlers` or `waitFor`, we enqueue a call to
216
- // _update method that will try to update native handler props using
217
- // queueMicrotask. This makes it so update() function gets called after all
218
- // react components are mounted and we expect the missing ref object to
219
- // be resolved by then.
220
- queueMicrotask(() => {
221
- this.update(UNRESOLVED_REFS_RETRY_LIMIT);
222
- });
223
- }
224
-
225
- this.createGestureHandler(
226
- filterConfig(
227
- transformProps ? transformProps(this.props) : this.props,
228
- [...allowedProps, ...customNativeProps],
229
- config
230
- )
231
- );
232
-
233
- this.attachGestureHandler(findNodeHandle(this.viewNode) as number); // TODO(TS) - check if this can be null
234
- }
235
-
236
- componentDidUpdate() {
237
- const viewTag = findNodeHandle(this.viewNode);
238
- if (this.viewTag !== viewTag) {
239
- this.attachGestureHandler(viewTag as number); // TODO(TS) - check interaction between _viewTag & findNodeHandle
240
- }
241
- this.update(UNRESOLVED_REFS_RETRY_LIMIT);
242
- }
243
-
244
- componentWillUnmount() {
245
- this.inspectorToggleListener?.remove();
246
- this.isMountedRef.current = false;
247
- RNGestureHandlerModule.dropGestureHandler(this.handlerTag);
248
- scheduleFlushOperations();
249
- // We can't use this.props.id directly due to TS generic type narrowing bug, see https://github.com/microsoft/TypeScript/issues/13995 for more context
250
- const handlerID: string | undefined = this.props.id;
251
- if (handlerID) {
252
- // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
253
- delete handlerIDToTag[handlerID];
254
- }
255
- }
256
-
257
- private onGestureHandlerEvent = (event: GestureEvent<U>) => {
258
- if (event.nativeEvent.handlerTag === this.handlerTag) {
259
- if (typeof this.props.onGestureEvent === 'function') {
260
- this.props.onGestureEvent?.(event);
261
- }
262
- } else {
263
- this.props.onGestureHandlerEvent?.(event);
264
- }
265
- };
266
-
267
- // TODO(TS) - make sure this is right type for event
268
- private onGestureHandlerStateChange = (
269
- event: HandlerStateChangeEvent<U>
270
- ) => {
271
- if (event.nativeEvent.handlerTag === this.handlerTag) {
272
- if (typeof this.props.onHandlerStateChange === 'function') {
273
- this.props.onHandlerStateChange?.(event);
274
- }
275
-
276
- const state: ValueOf<typeof State> = event.nativeEvent.state;
277
- const stateEventName = stateToPropMappings[state];
278
- const eventHandler = stateEventName && this.props[stateEventName];
279
- if (eventHandler && typeof eventHandler === 'function') {
280
- eventHandler(event);
281
- }
282
- } else {
283
- this.props.onGestureHandlerStateChange?.(event);
284
- }
285
- };
286
-
287
- private refHandler = (node: any) => {
288
- this.viewNode = node;
289
-
290
- const child = React.Children.only(this.props.children);
291
- // TODO(TS) fix ref type
292
- const { ref }: any = child;
293
- if (ref !== null) {
294
- if (typeof ref === 'function') {
295
- ref(node);
296
- } else {
297
- ref.current = node;
298
- }
299
- }
300
- };
301
-
302
- private createGestureHandler = (
303
- newConfig: Readonly<Record<string, unknown>>
304
- ) => {
305
- this.config = newConfig;
306
-
307
- RNGestureHandlerModule.createGestureHandler(
308
- name,
309
- this.handlerTag,
310
- newConfig
311
- );
312
- };
313
-
314
- private attachGestureHandler = (newViewTag: number) => {
315
- this.viewTag = newViewTag;
316
-
317
- if (Platform.OS === 'web') {
318
- // typecast due to dynamic resolution, attachGestureHandler should have web version signature in this branch
319
- (
320
- RNGestureHandlerModule.attachGestureHandler as typeof RNGestureHandlerModuleWeb.attachGestureHandler
321
- )(
322
- this.handlerTag,
323
- newViewTag,
324
- ActionType.JS_FUNCTION_OLD_API, // ignored on web
325
- this.propsRef
326
- );
327
- } else {
328
- registerOldGestureHandler(this.handlerTag, {
329
- onGestureEvent: this.onGestureHandlerEvent,
330
- onGestureStateChange: this.onGestureHandlerStateChange,
331
- });
332
-
333
- const actionType = (() => {
334
- if (
335
- (this.props?.onGestureEvent &&
336
- 'current' in this.props.onGestureEvent) ||
337
- (this.props?.onHandlerStateChange &&
338
- 'current' in this.props.onHandlerStateChange)
339
- ) {
340
- // Reanimated worklet
341
- return ActionType.REANIMATED_WORKLET;
342
- } else if (
343
- this.props?.onGestureEvent &&
344
- '__isNative' in this.props.onGestureEvent
345
- ) {
346
- // Animated.event with useNativeDriver: true
347
- return ActionType.NATIVE_ANIMATED_EVENT;
348
- } else {
349
- // JS callback or Animated.event with useNativeDriver: false
350
- return ActionType.JS_FUNCTION_OLD_API;
351
- }
352
- })();
353
-
354
- RNGestureHandlerModule.attachGestureHandler(
355
- this.handlerTag,
356
- newViewTag,
357
- actionType
358
- );
359
- }
360
-
361
- scheduleFlushOperations();
362
- };
363
-
364
- private updateGestureHandler = (
365
- newConfig: Readonly<Record<string, unknown>>
366
- ) => {
367
- this.config = newConfig;
368
-
369
- RNGestureHandlerModule.updateGestureHandler(this.handlerTag, newConfig);
370
- scheduleFlushOperations();
371
- };
372
-
373
- private update(remainingTries: number) {
374
- if (!this.isMountedRef.current) {
375
- return;
376
- }
377
-
378
- const props: HandlerProps<U> = this.props;
379
-
380
- // When ref is set via a function i.e. `ref={(r) => refObject.current = r}` instead of
381
- // `ref={refObject}` it's possible that it won't be resolved in time. Seems like trying
382
- // again is easy enough fix.
383
- if (hasUnresolvedRefs(props) && remainingTries > 0) {
384
- queueMicrotask(() => {
385
- this.update(remainingTries - 1);
386
- });
387
- } else {
388
- const newConfig = filterConfig(
389
- transformProps ? transformProps(this.props) : this.props,
390
- [...allowedProps, ...customNativeProps],
391
- config
392
- );
393
- if (!deepEqual(this.config, newConfig)) {
394
- this.updateGestureHandler(newConfig);
395
- }
396
- }
397
- }
398
-
399
- setNativeProps(updates: any) {
400
- const mergedProps = { ...this.props, ...updates };
401
- const newConfig = filterConfig(
402
- transformProps ? transformProps(mergedProps) : mergedProps,
403
- [...allowedProps, ...customNativeProps],
404
- config
405
- );
406
- this.updateGestureHandler(newConfig);
407
- }
408
-
409
- render() {
410
- if (__DEV__ && !this.context && !isJestEnv() && Platform.OS !== 'web' && (Platform.OS as any) !== "harmony") { // RNOH: patch
411
- throw new Error(
412
- name +
413
- ' must be used as a descendant of GestureHandlerRootView. Otherwise the gestures will not be recognized. See https://docs.swmansion.com/react-native-gesture-handler/docs/installation for more details.'
414
- );
415
- }
416
-
417
- let gestureEventHandler = this.onGestureHandlerEvent;
418
- // Another instance of https://github.com/microsoft/TypeScript/issues/13995
419
- type OnGestureEventHandlers = {
420
- onGestureEvent?: BaseGestureHandlerProps<U>['onGestureEvent'];
421
- onGestureHandlerEvent?: InternalEventHandlers['onGestureHandlerEvent'];
422
- };
423
- const { onGestureEvent, onGestureHandlerEvent }: OnGestureEventHandlers =
424
- this.props;
425
- if (onGestureEvent && typeof onGestureEvent !== 'function') {
426
- // If it's not a method it should be an native Animated.event
427
- // object. We set it directly as the handler for the view
428
- // In this case nested handlers are not going to be supported
429
- if (onGestureHandlerEvent) {
430
- throw new Error(
431
- 'Nesting touch handlers with native animated driver is not supported yet'
432
- );
433
- }
434
- gestureEventHandler = onGestureEvent;
435
- } else {
436
- if (
437
- onGestureHandlerEvent &&
438
- typeof onGestureHandlerEvent !== 'function'
439
- ) {
440
- throw new Error(
441
- 'Nesting touch handlers with native animated driver is not supported yet'
442
- );
443
- }
444
- }
445
-
446
- let gestureStateEventHandler = this.onGestureHandlerStateChange;
447
- // Another instance of https://github.com/microsoft/TypeScript/issues/13995
448
- type OnGestureStateChangeHandlers = {
449
- onHandlerStateChange?: BaseGestureHandlerProps<U>['onHandlerStateChange'];
450
- onGestureHandlerStateChange?: InternalEventHandlers['onGestureHandlerStateChange'];
451
- };
452
- const {
453
- onHandlerStateChange,
454
- onGestureHandlerStateChange,
455
- }: OnGestureStateChangeHandlers = this.props;
456
- if (onHandlerStateChange && typeof onHandlerStateChange !== 'function') {
457
- // If it's not a method it should be an native Animated.event
458
- // object. We set it directly as the handler for the view
459
- // In this case nested handlers are not going to be supported
460
- if (onGestureHandlerStateChange) {
461
- throw new Error(
462
- 'Nesting touch handlers with native animated driver is not supported yet'
463
- );
464
- }
465
- gestureStateEventHandler = onHandlerStateChange;
466
- } else {
467
- if (
468
- onGestureHandlerStateChange &&
469
- typeof onGestureHandlerStateChange !== 'function'
470
- ) {
471
- throw new Error(
472
- 'Nesting touch handlers with native animated driver is not supported yet'
473
- );
474
- }
475
- }
476
- const events = {
477
- onGestureHandlerEvent: this.state.allowTouches
478
- ? gestureEventHandler
479
- : undefined,
480
- onGestureHandlerStateChange: this.state.allowTouches
481
- ? gestureStateEventHandler
482
- : undefined,
483
- };
484
-
485
- this.propsRef.current = events;
486
-
487
- let child: any = null;
488
- try {
489
- child = React.Children.only(this.props.children);
490
- } catch (e) {
491
- throw new Error(
492
- tagMessage(
493
- `${name} got more than one view as a child. If you want the gesture to work on multiple views, wrap them with a common parent and attach the gesture to that view.`
494
- )
495
- );
496
- }
497
-
498
- let grandChildren = child.props.children;
499
- if (
500
- __DEV__ &&
501
- child.type &&
502
- (child.type === 'RNGestureHandlerButton' ||
503
- child.type.name === 'View' ||
504
- child.type.displayName === 'View')
505
- ) {
506
- grandChildren = React.Children.toArray(grandChildren);
507
- grandChildren.push(
508
- <PressabilityDebugView
509
- key="pressabilityDebugView"
510
- color="mediumspringgreen"
511
- hitSlop={child.props.hitSlop}
512
- />
513
- );
514
- }
515
-
516
- return React.cloneElement(
517
- child,
518
- {
519
- ref: this.refHandler,
520
- collapsable: false,
521
- ...(isJestEnv()
522
- ? {
523
- handlerType: name,
524
- handlerTag: this.handlerTag,
525
- }
526
- : {}),
527
- testID: this.props.testID ?? child.props.testID,
528
- ...events,
529
- },
530
- grandChildren
531
- );
532
- }
533
- }
534
- return Handler;
535
- }
1
+ // RNGH: patching the import to RNGestureHandlerModule
2
+
3
+ import * as React from 'react';
4
+ import {
5
+ Platform,
6
+ UIManager,
7
+ DeviceEventEmitter,
8
+ EmitterSubscription,
9
+ } from 'react-native';
10
+ // @ts-ignore - it isn't typed by TS & don't have definitelyTyped types
11
+ import deepEqual from 'lodash/isEqual';
12
+ import RNGestureHandlerModule from '../RNGestureHandlerModule'; // RNGH: patch
13
+ import type RNGestureHandlerModuleWeb from 'react-native-gesture-handler/src/RNGestureHandlerModule.web';
14
+ import { State } from 'react-native-gesture-handler/src/State';
15
+ import {
16
+ handlerIDToTag,
17
+ getNextHandlerTag,
18
+ registerOldGestureHandler,
19
+ } from 'react-native-gesture-handler/src/handlers/handlersRegistry';
20
+
21
+ import {
22
+ BaseGestureHandlerProps,
23
+ filterConfig,
24
+ GestureEvent,
25
+ HandlerStateChangeEvent,
26
+ findNodeHandle,
27
+ scheduleFlushOperations,
28
+ } from "react-native-gesture-handler/src/handlers/gestureHandlerCommon";
29
+ import { ValueOf } from 'react-native-gesture-handler/src/typeUtils';
30
+ import { isFabric, isJestEnv, tagMessage } from 'react-native-gesture-handler/src/utils';
31
+ import { ActionType } from 'react-native-gesture-handler/src/ActionType';
32
+ import { PressabilityDebugView } from 'react-native-gesture-handler/src/handlers/PressabilityDebugView';
33
+ import GestureHandlerRootViewContext from 'react-native-gesture-handler/src/GestureHandlerRootViewContext';
34
+
35
+ const UIManagerAny = UIManager as any;
36
+
37
+ const customGHEventsConfigFabricAndroid = {
38
+ topOnGestureHandlerEvent: { registrationName: 'onGestureHandlerEvent' },
39
+ topOnGestureHandlerStateChange: {
40
+ registrationName: 'onGestureHandlerStateChange',
41
+ },
42
+ };
43
+
44
+ const customGHEventsConfig = {
45
+ onGestureHandlerEvent: { registrationName: 'onGestureHandlerEvent' },
46
+ onGestureHandlerStateChange: {
47
+ registrationName: 'onGestureHandlerStateChange',
48
+ },
49
+
50
+ // When using React Native Gesture Handler for Animated.event with useNativeDriver: true
51
+ // on Android with Fabric enabled, the native part still sends the native events to JS
52
+ // but prefixed with "top". We cannot simply rename the events above so they are prefixed
53
+ // with "top" instead of "on" because in such case Animated.events would not be registered.
54
+ // That's why we need to register another pair of event names.
55
+ // The incoming events will be queued but never handled.
56
+ // Without this piece of code below, you'll get the following JS error:
57
+ // Unsupported top level event type "topOnGestureHandlerEvent" dispatched
58
+ ...(isFabric() &&
59
+ Platform.OS as string === 'harmony' && // RNGH: patch
60
+ customGHEventsConfigFabricAndroid),
61
+ };
62
+
63
+ // Add gesture specific events to genericDirectEventTypes object exported from UIManager
64
+ // native module.
65
+ // Once new event types are registered with react it is possible to dispatch these
66
+ // events to all kind of native views.
67
+ UIManagerAny.genericDirectEventTypes = {
68
+ ...UIManagerAny.genericDirectEventTypes,
69
+ ...customGHEventsConfig,
70
+ };
71
+ // In newer versions of RN the `genericDirectEventTypes` is located in the object
72
+ // returned by UIManager.getViewManagerConfig('getConstants') or in older RN UIManager.getConstants(), we need to add it there as well to make
73
+ // it compatible with RN 61+
74
+ const UIManagerConstants =
75
+ UIManagerAny.getViewManagerConfig?.('getConstants') ??
76
+ UIManagerAny.getConstants?.();
77
+
78
+ if (UIManagerConstants) {
79
+ UIManagerConstants.genericDirectEventTypes = {
80
+ ...UIManagerConstants.genericDirectEventTypes,
81
+ ...customGHEventsConfig,
82
+ };
83
+ }
84
+
85
+ // Wrap JS responder calls and notify gesture handler manager
86
+ const {
87
+ setJSResponder: oldSetJSResponder = () => {
88
+ //no operation
89
+ },
90
+ clearJSResponder: oldClearJSResponder = () => {
91
+ //no operation
92
+ },
93
+ } = UIManagerAny;
94
+ UIManagerAny.setJSResponder = (tag: number, blockNativeResponder: boolean) => {
95
+ RNGestureHandlerModule.handleSetJSResponder(tag, blockNativeResponder);
96
+ oldSetJSResponder(tag, blockNativeResponder);
97
+ };
98
+ UIManagerAny.clearJSResponder = () => {
99
+ RNGestureHandlerModule.handleClearJSResponder();
100
+ oldClearJSResponder();
101
+ };
102
+
103
+ let allowTouches = true;
104
+ const DEV_ON_ANDROID = __DEV__ && Platform.OS === 'android';
105
+ // Toggled inspector blocks touch events in order to allow inspecting on Android
106
+ // This needs to be a global variable in order to set initial state for `allowTouches` property in Handler component
107
+ if (DEV_ON_ANDROID) {
108
+ DeviceEventEmitter.addListener('toggleElementInspector', () => {
109
+ allowTouches = !allowTouches;
110
+ });
111
+ }
112
+
113
+ type HandlerProps<T extends Record<string, unknown>> = Readonly<
114
+ React.PropsWithChildren<BaseGestureHandlerProps<T>>
115
+ >;
116
+ function hasUnresolvedRefs<T extends Record<string, unknown>>(
117
+ props: HandlerProps<T>
118
+ ) {
119
+ // TODO(TS) - add type for extract arg
120
+ const extract = (refs: any | any[]) => {
121
+ if (!Array.isArray(refs)) {
122
+ return refs && refs.current === null;
123
+ }
124
+ return refs.some((r) => r && r.current === null);
125
+ };
126
+ return extract(props['simultaneousHandlers']) || extract(props['waitFor']);
127
+ }
128
+
129
+ const stateToPropMappings = {
130
+ [State.UNDETERMINED]: undefined,
131
+ [State.BEGAN]: 'onBegan',
132
+ [State.FAILED]: 'onFailed',
133
+ [State.CANCELLED]: 'onCancelled',
134
+ [State.ACTIVE]: 'onActivated',
135
+ [State.END]: 'onEnded',
136
+ } as const;
137
+
138
+ type CreateHandlerArgs<HandlerPropsT extends Record<string, unknown>> =
139
+ Readonly<{
140
+ name: string;
141
+ allowedProps: Readonly<Extract<keyof HandlerPropsT, string>[]>;
142
+ config: Readonly<Record<string, unknown>>;
143
+ transformProps?: (props: HandlerPropsT) => HandlerPropsT;
144
+ customNativeProps?: Readonly<string[]>;
145
+ }>;
146
+
147
+ // TODO(TS) fix event types
148
+ type InternalEventHandlers = {
149
+ onGestureHandlerEvent?: (event: any) => void;
150
+ onGestureHandlerStateChange?: (event: any) => void;
151
+ };
152
+
153
+ const UNRESOLVED_REFS_RETRY_LIMIT = 1;
154
+
155
+ // TODO(TS) - make sure that BaseGestureHandlerProps doesn't need other generic parameter to work with custom properties.
156
+ export default function createHandler<
157
+ T extends BaseGestureHandlerProps<U>,
158
+ U extends Record<string, unknown>
159
+ >({
160
+ name,
161
+ allowedProps = [],
162
+ config = {},
163
+ transformProps,
164
+ customNativeProps = [],
165
+ }: CreateHandlerArgs<T>): React.ComponentType<T & React.RefAttributes<any>> {
166
+ interface HandlerState {
167
+ allowTouches: boolean;
168
+ }
169
+ class Handler extends React.Component<
170
+ T & InternalEventHandlers,
171
+ HandlerState
172
+ > {
173
+ static displayName = name;
174
+ static contextType = GestureHandlerRootViewContext;
175
+
176
+ private handlerTag: number;
177
+ private config: Record<string, unknown>;
178
+ private propsRef: React.MutableRefObject<unknown>;
179
+ private isMountedRef: React.MutableRefObject<boolean | null>;
180
+ private viewNode: any;
181
+ private viewTag?: number;
182
+ private inspectorToggleListener?: EmitterSubscription;
183
+
184
+ constructor(props: T & InternalEventHandlers) {
185
+ super(props);
186
+ this.handlerTag = getNextHandlerTag();
187
+ this.config = {};
188
+ this.propsRef = React.createRef();
189
+ this.isMountedRef = React.createRef();
190
+ this.state = { allowTouches };
191
+ if (props.id) {
192
+ if (handlerIDToTag[props.id] !== undefined) {
193
+ throw new Error(`Handler with ID "${props.id}" already registered`);
194
+ }
195
+ handlerIDToTag[props.id] = this.handlerTag;
196
+ }
197
+ }
198
+
199
+ componentDidMount() {
200
+ const props: HandlerProps<U> = this.props;
201
+ this.isMountedRef.current = true;
202
+
203
+ if (DEV_ON_ANDROID) {
204
+ this.inspectorToggleListener = DeviceEventEmitter.addListener(
205
+ 'toggleElementInspector',
206
+ () => {
207
+ this.setState((_) => ({ allowTouches }));
208
+ this.update(UNRESOLVED_REFS_RETRY_LIMIT);
209
+ }
210
+ );
211
+ }
212
+ if (hasUnresolvedRefs(props)) {
213
+ // If there are unresolved refs (e.g. ".current" has not yet been set)
214
+ // passed as `simultaneousHandlers` or `waitFor`, we enqueue a call to
215
+ // _update method that will try to update native handler props using
216
+ // queueMicrotask. This makes it so update() function gets called after all
217
+ // react components are mounted and we expect the missing ref object to
218
+ // be resolved by then.
219
+ queueMicrotask(() => {
220
+ this.update(UNRESOLVED_REFS_RETRY_LIMIT);
221
+ });
222
+ }
223
+
224
+ this.createGestureHandler(
225
+ filterConfig(
226
+ transformProps ? transformProps(this.props) : this.props,
227
+ [...allowedProps, ...customNativeProps],
228
+ config
229
+ )
230
+ );
231
+
232
+ this.attachGestureHandler(findNodeHandle(this.viewNode) as number); // TODO(TS) - check if this can be null
233
+ }
234
+
235
+ componentDidUpdate() {
236
+ const viewTag = findNodeHandle(this.viewNode);
237
+ if (this.viewTag !== viewTag) {
238
+ this.attachGestureHandler(viewTag as number); // TODO(TS) - check interaction between _viewTag & findNodeHandle
239
+ }
240
+ this.update(UNRESOLVED_REFS_RETRY_LIMIT);
241
+ }
242
+
243
+ componentWillUnmount() {
244
+ this.inspectorToggleListener?.remove();
245
+ this.isMountedRef.current = false;
246
+ RNGestureHandlerModule.dropGestureHandler(this.handlerTag);
247
+ scheduleFlushOperations();
248
+ // We can't use this.props.id directly due to TS generic type narrowing bug, see https://github.com/microsoft/TypeScript/issues/13995 for more context
249
+ const handlerID: string | undefined = this.props.id;
250
+ if (handlerID) {
251
+ // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
252
+ delete handlerIDToTag[handlerID];
253
+ }
254
+ }
255
+
256
+ private onGestureHandlerEvent = (event: GestureEvent<U>) => {
257
+ if (event.nativeEvent.handlerTag === this.handlerTag) {
258
+ if (typeof this.props.onGestureEvent === 'function') {
259
+ this.props.onGestureEvent?.(event);
260
+ }
261
+ } else {
262
+ this.props.onGestureHandlerEvent?.(event);
263
+ }
264
+ };
265
+
266
+ // TODO(TS) - make sure this is right type for event
267
+ private onGestureHandlerStateChange = (
268
+ event: HandlerStateChangeEvent<U>
269
+ ) => {
270
+ if (event.nativeEvent.handlerTag === this.handlerTag) {
271
+ if (typeof this.props.onHandlerStateChange === 'function') {
272
+ this.props.onHandlerStateChange?.(event);
273
+ }
274
+
275
+ const state: ValueOf<typeof State> = event.nativeEvent.state;
276
+ const stateEventName = stateToPropMappings[state];
277
+ const eventHandler = stateEventName && this.props[stateEventName];
278
+ if (eventHandler && typeof eventHandler === 'function') {
279
+ eventHandler(event);
280
+ }
281
+ } else {
282
+ this.props.onGestureHandlerStateChange?.(event);
283
+ }
284
+ };
285
+
286
+ private refHandler = (node: any) => {
287
+ this.viewNode = node;
288
+
289
+ const child = React.Children.only(this.props.children);
290
+ // TODO(TS) fix ref type
291
+ const { ref }: any = child;
292
+ if (ref !== null) {
293
+ if (typeof ref === 'function') {
294
+ ref(node);
295
+ } else {
296
+ ref.current = node;
297
+ }
298
+ }
299
+ };
300
+
301
+ private createGestureHandler = (
302
+ newConfig: Readonly<Record<string, unknown>>
303
+ ) => {
304
+ this.config = newConfig;
305
+
306
+ RNGestureHandlerModule.createGestureHandler(
307
+ name,
308
+ this.handlerTag,
309
+ newConfig
310
+ );
311
+ };
312
+
313
+ private attachGestureHandler = (newViewTag: number) => {
314
+ this.viewTag = newViewTag;
315
+
316
+ if (Platform.OS === 'web') {
317
+ // typecast due to dynamic resolution, attachGestureHandler should have web version signature in this branch
318
+ (
319
+ RNGestureHandlerModule.attachGestureHandler as typeof RNGestureHandlerModuleWeb.attachGestureHandler
320
+ )(
321
+ this.handlerTag,
322
+ newViewTag,
323
+ ActionType.JS_FUNCTION_OLD_API, // ignored on web
324
+ this.propsRef
325
+ );
326
+ } else {
327
+ registerOldGestureHandler(this.handlerTag, {
328
+ onGestureEvent: this.onGestureHandlerEvent,
329
+ onGestureStateChange: this.onGestureHandlerStateChange,
330
+ });
331
+
332
+ const actionType = (() => {
333
+ if (
334
+ (this.props?.onGestureEvent &&
335
+ 'current' in this.props.onGestureEvent) ||
336
+ (this.props?.onHandlerStateChange &&
337
+ 'current' in this.props.onHandlerStateChange)
338
+ ) {
339
+ // Reanimated worklet
340
+ return ActionType.REANIMATED_WORKLET;
341
+ } else if (
342
+ this.props?.onGestureEvent &&
343
+ '__isNative' in this.props.onGestureEvent
344
+ ) {
345
+ // Animated.event with useNativeDriver: true
346
+ return ActionType.NATIVE_ANIMATED_EVENT;
347
+ } else {
348
+ // JS callback or Animated.event with useNativeDriver: false
349
+ return ActionType.JS_FUNCTION_OLD_API;
350
+ }
351
+ })();
352
+
353
+ RNGestureHandlerModule.attachGestureHandler(
354
+ this.handlerTag,
355
+ newViewTag,
356
+ actionType
357
+ );
358
+ }
359
+
360
+ scheduleFlushOperations();
361
+ };
362
+
363
+ private updateGestureHandler = (
364
+ newConfig: Readonly<Record<string, unknown>>
365
+ ) => {
366
+ this.config = newConfig;
367
+
368
+ RNGestureHandlerModule.updateGestureHandler(this.handlerTag, newConfig);
369
+ scheduleFlushOperations();
370
+ };
371
+
372
+ private update(remainingTries: number) {
373
+ if (!this.isMountedRef.current) {
374
+ return;
375
+ }
376
+
377
+ const props: HandlerProps<U> = this.props;
378
+
379
+ // When ref is set via a function i.e. `ref={(r) => refObject.current = r}` instead of
380
+ // `ref={refObject}` it's possible that it won't be resolved in time. Seems like trying
381
+ // again is easy enough fix.
382
+ if (hasUnresolvedRefs(props) && remainingTries > 0) {
383
+ queueMicrotask(() => {
384
+ this.update(remainingTries - 1);
385
+ });
386
+ } else {
387
+ const newConfig = filterConfig(
388
+ transformProps ? transformProps(this.props) : this.props,
389
+ [...allowedProps, ...customNativeProps],
390
+ config
391
+ );
392
+ if (!deepEqual(this.config, newConfig)) {
393
+ this.updateGestureHandler(newConfig);
394
+ }
395
+ }
396
+ }
397
+
398
+ setNativeProps(updates: any) {
399
+ const mergedProps = { ...this.props, ...updates };
400
+ const newConfig = filterConfig(
401
+ transformProps ? transformProps(mergedProps) : mergedProps,
402
+ [...allowedProps, ...customNativeProps],
403
+ config
404
+ );
405
+ this.updateGestureHandler(newConfig);
406
+ }
407
+
408
+ render() {
409
+ if (__DEV__ && !this.context && !isJestEnv() && Platform.OS !== 'web' && (Platform.OS as any) !== "harmony") { // RNOH: patch
410
+ throw new Error(
411
+ name +
412
+ ' must be used as a descendant of GestureHandlerRootView. Otherwise the gestures will not be recognized. See https://docs.swmansion.com/react-native-gesture-handler/docs/installation for more details.'
413
+ );
414
+ }
415
+
416
+ let gestureEventHandler = this.onGestureHandlerEvent;
417
+ // Another instance of https://github.com/microsoft/TypeScript/issues/13995
418
+ type OnGestureEventHandlers = {
419
+ onGestureEvent?: BaseGestureHandlerProps<U>['onGestureEvent'];
420
+ onGestureHandlerEvent?: InternalEventHandlers['onGestureHandlerEvent'];
421
+ };
422
+ const { onGestureEvent, onGestureHandlerEvent }: OnGestureEventHandlers =
423
+ this.props;
424
+ if (onGestureEvent && typeof onGestureEvent !== 'function') {
425
+ // If it's not a method it should be an native Animated.event
426
+ // object. We set it directly as the handler for the view
427
+ // In this case nested handlers are not going to be supported
428
+ if (onGestureHandlerEvent) {
429
+ throw new Error(
430
+ 'Nesting touch handlers with native animated driver is not supported yet'
431
+ );
432
+ }
433
+ gestureEventHandler = onGestureEvent;
434
+ } else {
435
+ if (
436
+ onGestureHandlerEvent &&
437
+ typeof onGestureHandlerEvent !== 'function'
438
+ ) {
439
+ throw new Error(
440
+ 'Nesting touch handlers with native animated driver is not supported yet'
441
+ );
442
+ }
443
+ }
444
+
445
+ let gestureStateEventHandler = this.onGestureHandlerStateChange;
446
+ // Another instance of https://github.com/microsoft/TypeScript/issues/13995
447
+ type OnGestureStateChangeHandlers = {
448
+ onHandlerStateChange?: BaseGestureHandlerProps<U>['onHandlerStateChange'];
449
+ onGestureHandlerStateChange?: InternalEventHandlers['onGestureHandlerStateChange'];
450
+ };
451
+ const {
452
+ onHandlerStateChange,
453
+ onGestureHandlerStateChange,
454
+ }: OnGestureStateChangeHandlers = this.props;
455
+ if (onHandlerStateChange && typeof onHandlerStateChange !== 'function') {
456
+ // If it's not a method it should be an native Animated.event
457
+ // object. We set it directly as the handler for the view
458
+ // In this case nested handlers are not going to be supported
459
+ if (onGestureHandlerStateChange) {
460
+ throw new Error(
461
+ 'Nesting touch handlers with native animated driver is not supported yet'
462
+ );
463
+ }
464
+ gestureStateEventHandler = onHandlerStateChange;
465
+ } else {
466
+ if (
467
+ onGestureHandlerStateChange &&
468
+ typeof onGestureHandlerStateChange !== 'function'
469
+ ) {
470
+ throw new Error(
471
+ 'Nesting touch handlers with native animated driver is not supported yet'
472
+ );
473
+ }
474
+ }
475
+ const events = {
476
+ onGestureHandlerEvent: this.state.allowTouches
477
+ ? gestureEventHandler
478
+ : undefined,
479
+ onGestureHandlerStateChange: this.state.allowTouches
480
+ ? gestureStateEventHandler
481
+ : undefined,
482
+ };
483
+
484
+ this.propsRef.current = events;
485
+
486
+ let child: any = null;
487
+ try {
488
+ child = React.Children.only(this.props.children);
489
+ } catch (e) {
490
+ throw new Error(
491
+ tagMessage(
492
+ `${name} got more than one view as a child. If you want the gesture to work on multiple views, wrap them with a common parent and attach the gesture to that view.`
493
+ )
494
+ );
495
+ }
496
+
497
+ let grandChildren = child.props.children;
498
+ if (
499
+ __DEV__ &&
500
+ child.type &&
501
+ (child.type === 'RNGestureHandlerButton' ||
502
+ child.type.name === 'View' ||
503
+ child.type.displayName === 'View')
504
+ ) {
505
+ grandChildren = React.Children.toArray(grandChildren);
506
+ grandChildren.push(
507
+ <PressabilityDebugView
508
+ key="pressabilityDebugView"
509
+ color="mediumspringgreen"
510
+ hitSlop={child.props.hitSlop}
511
+ />
512
+ );
513
+ }
514
+
515
+ return React.cloneElement(
516
+ child,
517
+ {
518
+ ref: this.refHandler,
519
+ collapsable: false,
520
+ ...(isJestEnv()
521
+ ? {
522
+ handlerType: name,
523
+ handlerTag: this.handlerTag,
524
+ }
525
+ : {}),
526
+ testID: this.props.testID ?? child.props.testID,
527
+ ...events,
528
+ },
529
+ grandChildren
530
+ );
531
+ }
532
+ }
533
+ return Handler;
534
+ }