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

Sign up to get free protection for your applications and to get access to all the features.
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
+ }