react-native-gesture-handler 2.32.0 → 2.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (227) hide show
  1. package/android/build.gradle +27 -11
  2. package/android/gradle.properties +1 -1
  3. package/android/src/main/java/com/swmansion/gesturehandler/core/FlingGestureHandler.kt +1 -1
  4. package/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt +32 -33
  5. package/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt +144 -15
  6. package/android/src/main/java/com/swmansion/gesturehandler/core/LongPressGestureHandler.kt +6 -3
  7. package/android/src/main/java/com/swmansion/gesturehandler/core/NativeViewGestureHandler.kt +23 -0
  8. package/android/src/main/java/com/swmansion/gesturehandler/core/PanGestureHandler.kt +4 -7
  9. package/android/src/main/java/com/swmansion/gesturehandler/core/TapGestureHandler.kt +1 -1
  10. package/android/src/main/java/com/swmansion/gesturehandler/react/Extensions.kt +3 -0
  11. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt +2 -0
  12. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootHelper.kt +9 -0
  13. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootView.kt +8 -6
  14. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerTouchEvent.kt +2 -7
  15. package/apple/Handlers/RNFlingHandler.m +44 -4
  16. package/apple/Handlers/RNHoverHandler.m +24 -26
  17. package/apple/Handlers/RNLongPressHandler.m +4 -0
  18. package/apple/Handlers/RNPanHandler.m +44 -7
  19. package/apple/Handlers/RNTapHandler.m +35 -4
  20. package/apple/RNGHUIKit.h +10 -10
  21. package/apple/RNGestureHandler.h +2 -0
  22. package/apple/RNGestureHandler.mm +47 -6
  23. package/apple/RNGestureHandlerButton.mm +5 -3
  24. package/apple/RNGestureHandlerManager.mm +63 -6
  25. package/apple/RNGestureHandlerModule.mm +20 -0
  26. package/apple/RNGestureHandlerPointerTracker.m +64 -10
  27. package/apple/RNGestureHandlerPointerType.h +1 -0
  28. package/apple/RNManualActivationRecognizer.m +25 -6
  29. package/lib/commonjs/components/GestureComponents.js +21 -1
  30. package/lib/commonjs/components/GestureComponents.js.map +1 -1
  31. package/lib/commonjs/components/GestureHandlerButton.web.js +2 -1
  32. package/lib/commonjs/components/GestureHandlerButton.web.js.map +1 -1
  33. package/lib/commonjs/components/Pressable/Pressable.js +28 -3
  34. package/lib/commonjs/components/Pressable/Pressable.js.map +1 -1
  35. package/lib/commonjs/components/Pressable/index.js.map +1 -1
  36. package/lib/commonjs/components/ReanimatedDrawerLayout.js +4 -2
  37. package/lib/commonjs/components/ReanimatedDrawerLayout.js.map +1 -1
  38. package/lib/commonjs/components/ReanimatedSwipeable/ReanimatedSwipeable.js +32 -9
  39. package/lib/commonjs/components/ReanimatedSwipeable/ReanimatedSwipeable.js.map +1 -1
  40. package/lib/commonjs/components/Swipeable.js.map +1 -1
  41. package/lib/commonjs/components/Text.js.map +1 -1
  42. package/lib/commonjs/components/touchables/TouchableHighlight.js +1 -1
  43. package/lib/commonjs/components/touchables/TouchableHighlight.js.map +1 -1
  44. package/lib/commonjs/components/touchables/TouchableNativeFeedback.android.js.map +1 -1
  45. package/lib/commonjs/components/touchables/TouchableOpacity.js +1 -0
  46. package/lib/commonjs/components/touchables/TouchableOpacity.js.map +1 -1
  47. package/lib/commonjs/getShadowNodeFromRef.js +6 -2
  48. package/lib/commonjs/getShadowNodeFromRef.js.map +1 -1
  49. package/lib/commonjs/handlers/PanGestureHandler.js.map +1 -1
  50. package/lib/commonjs/handlers/gestures/GestureDetector/Wrap.js +56 -11
  51. package/lib/commonjs/handlers/gestures/GestureDetector/Wrap.js.map +1 -1
  52. package/lib/commonjs/handlers/gestures/GestureDetector/index.js +2 -1
  53. package/lib/commonjs/handlers/gestures/GestureDetector/index.js.map +1 -1
  54. package/lib/commonjs/handlers/gestures/GestureDetector/useDetectorUpdater.js +2 -1
  55. package/lib/commonjs/handlers/gestures/GestureDetector/useDetectorUpdater.js.map +1 -1
  56. package/lib/commonjs/handlers/gestures/GestureDetector/useMountReactions.js +6 -0
  57. package/lib/commonjs/handlers/gestures/GestureDetector/useMountReactions.js.map +1 -1
  58. package/lib/commonjs/handlers/gestures/GestureDetector/useViewRefHandler.js +3 -2
  59. package/lib/commonjs/handlers/gestures/GestureDetector/useViewRefHandler.js.map +1 -1
  60. package/lib/commonjs/handlers/gestures/gestureStateManager.web.js.map +1 -1
  61. package/lib/commonjs/handlers/gestures/panGesture.js +6 -3
  62. package/lib/commonjs/handlers/gestures/panGesture.js.map +1 -1
  63. package/lib/commonjs/hostInstance.js +39 -0
  64. package/lib/commonjs/hostInstance.js.map +1 -0
  65. package/lib/commonjs/index.js.map +1 -1
  66. package/lib/commonjs/mocks/mocks.js +1 -0
  67. package/lib/commonjs/mocks/mocks.js.map +1 -1
  68. package/lib/commonjs/specs/NativeRNGestureHandlerModule.js.map +1 -1
  69. package/lib/commonjs/specs/RNGestureHandlerButtonNativeComponent.ts +16 -14
  70. package/lib/commonjs/specs/RNGestureHandlerRootViewNativeComponent.ts +3 -3
  71. package/lib/commonjs/web/detectors/RotationGestureDetector.js +1 -1
  72. package/lib/commonjs/web/handlers/LongPressGestureHandler.js +3 -1
  73. package/lib/commonjs/web/handlers/LongPressGestureHandler.js.map +1 -1
  74. package/lib/commonjs/web/handlers/NativeViewGestureHandler.js +9 -1
  75. package/lib/commonjs/web/handlers/NativeViewGestureHandler.js.map +1 -1
  76. package/lib/commonjs/web/handlers/PanGestureHandler.js +8 -9
  77. package/lib/commonjs/web/handlers/PanGestureHandler.js.map +1 -1
  78. package/lib/commonjs/web/handlers/TapGestureHandler.js +1 -1
  79. package/lib/commonjs/web/tools/GestureHandlerOrchestrator.js +14 -0
  80. package/lib/commonjs/web/tools/GestureHandlerOrchestrator.js.map +1 -1
  81. package/lib/commonjs/web/tools/WheelEventManager.js +4 -0
  82. package/lib/commonjs/web/tools/WheelEventManager.js.map +1 -1
  83. package/lib/module/components/GestureComponents.js +23 -2
  84. package/lib/module/components/GestureComponents.js.map +1 -1
  85. package/lib/module/components/GestureHandlerButton.web.js +2 -1
  86. package/lib/module/components/GestureHandlerButton.web.js.map +1 -1
  87. package/lib/module/components/Pressable/Pressable.js +28 -3
  88. package/lib/module/components/Pressable/Pressable.js.map +1 -1
  89. package/lib/module/components/Pressable/index.js.map +1 -1
  90. package/lib/module/components/ReanimatedDrawerLayout.js +4 -2
  91. package/lib/module/components/ReanimatedDrawerLayout.js.map +1 -1
  92. package/lib/module/components/ReanimatedSwipeable/ReanimatedSwipeable.js +34 -11
  93. package/lib/module/components/ReanimatedSwipeable/ReanimatedSwipeable.js.map +1 -1
  94. package/lib/module/components/Swipeable.js.map +1 -1
  95. package/lib/module/components/Text.js.map +1 -1
  96. package/lib/module/components/touchables/TouchableHighlight.js +2 -2
  97. package/lib/module/components/touchables/TouchableHighlight.js.map +1 -1
  98. package/lib/module/components/touchables/TouchableNativeFeedback.android.js.map +1 -1
  99. package/lib/module/components/touchables/TouchableOpacity.js +1 -0
  100. package/lib/module/components/touchables/TouchableOpacity.js.map +1 -1
  101. package/lib/module/getShadowNodeFromRef.js +7 -2
  102. package/lib/module/getShadowNodeFromRef.js.map +1 -1
  103. package/lib/module/handlers/PanGestureHandler.js.map +1 -1
  104. package/lib/module/handlers/gestures/GestureDetector/Wrap.js +56 -11
  105. package/lib/module/handlers/gestures/GestureDetector/Wrap.js.map +1 -1
  106. package/lib/module/handlers/gestures/GestureDetector/index.js +2 -1
  107. package/lib/module/handlers/gestures/GestureDetector/index.js.map +1 -1
  108. package/lib/module/handlers/gestures/GestureDetector/useDetectorUpdater.js +2 -1
  109. package/lib/module/handlers/gestures/GestureDetector/useDetectorUpdater.js.map +1 -1
  110. package/lib/module/handlers/gestures/GestureDetector/useMountReactions.js +6 -0
  111. package/lib/module/handlers/gestures/GestureDetector/useMountReactions.js.map +1 -1
  112. package/lib/module/handlers/gestures/GestureDetector/useViewRefHandler.js +3 -2
  113. package/lib/module/handlers/gestures/GestureDetector/useViewRefHandler.js.map +1 -1
  114. package/lib/module/handlers/gestures/gestureStateManager.web.js.map +1 -1
  115. package/lib/module/handlers/gestures/panGesture.js +6 -3
  116. package/lib/module/handlers/gestures/panGesture.js.map +1 -1
  117. package/lib/module/hostInstance.js +32 -0
  118. package/lib/module/hostInstance.js.map +1 -0
  119. package/lib/module/index.js.map +1 -1
  120. package/lib/module/mocks/mocks.js +3 -2
  121. package/lib/module/mocks/mocks.js.map +1 -1
  122. package/lib/module/specs/NativeRNGestureHandlerModule.js.map +1 -1
  123. package/lib/module/specs/RNGestureHandlerButtonNativeComponent.ts +16 -14
  124. package/lib/module/specs/RNGestureHandlerRootViewNativeComponent.ts +3 -3
  125. package/lib/module/web/detectors/RotationGestureDetector.js +1 -1
  126. package/lib/module/web/handlers/LongPressGestureHandler.js +3 -1
  127. package/lib/module/web/handlers/LongPressGestureHandler.js.map +1 -1
  128. package/lib/module/web/handlers/NativeViewGestureHandler.js +9 -1
  129. package/lib/module/web/handlers/NativeViewGestureHandler.js.map +1 -1
  130. package/lib/module/web/handlers/PanGestureHandler.js +8 -9
  131. package/lib/module/web/handlers/PanGestureHandler.js.map +1 -1
  132. package/lib/module/web/handlers/TapGestureHandler.js +1 -1
  133. package/lib/module/web/tools/GestureHandlerOrchestrator.js +14 -0
  134. package/lib/module/web/tools/GestureHandlerOrchestrator.js.map +1 -1
  135. package/lib/module/web/tools/WheelEventManager.js +4 -0
  136. package/lib/module/web/tools/WheelEventManager.js.map +1 -1
  137. package/lib/typescript/components/GestureButtons.d.ts +3 -1
  138. package/lib/typescript/components/GestureButtons.d.ts.map +1 -1
  139. package/lib/typescript/components/GestureButtonsProps.d.ts +10 -0
  140. package/lib/typescript/components/GestureButtonsProps.d.ts.map +1 -1
  141. package/lib/typescript/components/GestureComponents.d.ts +8 -7
  142. package/lib/typescript/components/GestureComponents.d.ts.map +1 -1
  143. package/lib/typescript/components/GestureComponents.web.d.ts +12 -4
  144. package/lib/typescript/components/GestureComponents.web.d.ts.map +1 -1
  145. package/lib/typescript/components/GestureHandlerButton.web.d.ts +2 -2
  146. package/lib/typescript/components/GestureHandlerButton.web.d.ts.map +1 -1
  147. package/lib/typescript/components/Pressable/Pressable.d.ts.map +1 -1
  148. package/lib/typescript/components/Pressable/PressableProps.d.ts +1 -1
  149. package/lib/typescript/components/Pressable/PressableProps.d.ts.map +1 -1
  150. package/lib/typescript/components/Pressable/index.d.ts +1 -1
  151. package/lib/typescript/components/Pressable/index.d.ts.map +1 -1
  152. package/lib/typescript/components/ReanimatedDrawerLayout.d.ts.map +1 -1
  153. package/lib/typescript/components/ReanimatedSwipeable/ReanimatedSwipeable.d.ts.map +1 -1
  154. package/lib/typescript/components/Swipeable.d.ts.map +1 -1
  155. package/lib/typescript/components/touchables/TouchableHighlight.d.ts +1 -1
  156. package/lib/typescript/components/touchables/TouchableHighlight.d.ts.map +1 -1
  157. package/lib/typescript/components/touchables/TouchableNativeFeedback.android.d.ts +1 -1
  158. package/lib/typescript/components/touchables/TouchableNativeFeedback.android.d.ts.map +1 -1
  159. package/lib/typescript/components/touchables/TouchableOpacity.d.ts.map +1 -1
  160. package/lib/typescript/getShadowNodeFromRef.d.ts.map +1 -1
  161. package/lib/typescript/handlers/PanGestureHandler.d.ts +12 -0
  162. package/lib/typescript/handlers/PanGestureHandler.d.ts.map +1 -1
  163. package/lib/typescript/handlers/gestures/GestureDetector/Wrap.d.ts +11 -0
  164. package/lib/typescript/handlers/gestures/GestureDetector/Wrap.d.ts.map +1 -1
  165. package/lib/typescript/handlers/gestures/GestureDetector/index.d.ts.map +1 -1
  166. package/lib/typescript/handlers/gestures/GestureDetector/useDetectorUpdater.d.ts.map +1 -1
  167. package/lib/typescript/handlers/gestures/GestureDetector/useMountReactions.d.ts.map +1 -1
  168. package/lib/typescript/handlers/gestures/GestureDetector/useViewRefHandler.d.ts.map +1 -1
  169. package/lib/typescript/handlers/gestures/gestureStateManager.web.d.ts +8 -1
  170. package/lib/typescript/handlers/gestures/gestureStateManager.web.d.ts.map +1 -1
  171. package/lib/typescript/handlers/gestures/panGesture.d.ts +6 -3
  172. package/lib/typescript/handlers/gestures/panGesture.d.ts.map +1 -1
  173. package/lib/typescript/hostInstance.d.ts +10 -0
  174. package/lib/typescript/hostInstance.d.ts.map +1 -0
  175. package/lib/typescript/index.d.ts +1 -1
  176. package/lib/typescript/index.d.ts.map +1 -1
  177. package/lib/typescript/mocks/mocks.d.ts +67 -15
  178. package/lib/typescript/mocks/mocks.d.ts.map +1 -1
  179. package/lib/typescript/specs/NativeRNGestureHandlerModule.d.ts +6 -7
  180. package/lib/typescript/specs/NativeRNGestureHandlerModule.d.ts.map +1 -1
  181. package/lib/typescript/specs/RNGestureHandlerButtonNativeComponent.d.ts +9 -10
  182. package/lib/typescript/specs/RNGestureHandlerButtonNativeComponent.d.ts.map +1 -1
  183. package/lib/typescript/specs/RNGestureHandlerRootViewNativeComponent.d.ts +2 -2
  184. package/lib/typescript/specs/RNGestureHandlerRootViewNativeComponent.d.ts.map +1 -1
  185. package/lib/typescript/web/handlers/LongPressGestureHandler.d.ts.map +1 -1
  186. package/lib/typescript/web/handlers/NativeViewGestureHandler.d.ts +1 -0
  187. package/lib/typescript/web/handlers/NativeViewGestureHandler.d.ts.map +1 -1
  188. package/lib/typescript/web/handlers/PanGestureHandler.d.ts.map +1 -1
  189. package/lib/typescript/web/tools/GestureHandlerOrchestrator.d.ts +1 -0
  190. package/lib/typescript/web/tools/GestureHandlerOrchestrator.d.ts.map +1 -1
  191. package/lib/typescript/web/tools/WheelEventManager.d.ts.map +1 -1
  192. package/package.json +7 -7
  193. package/src/components/GestureButtonsProps.ts +14 -0
  194. package/src/components/GestureComponents.tsx +38 -7
  195. package/src/components/GestureHandlerButton.web.tsx +7 -3
  196. package/src/components/Pressable/Pressable.tsx +33 -4
  197. package/src/components/Pressable/PressableProps.tsx +1 -1
  198. package/src/components/Pressable/index.ts +1 -0
  199. package/src/components/ReanimatedDrawerLayout.tsx +4 -1
  200. package/src/components/ReanimatedSwipeable/ReanimatedSwipeable.tsx +49 -10
  201. package/src/components/Swipeable.tsx +6 -2
  202. package/src/components/Text.tsx +3 -3
  203. package/src/components/touchables/TouchableHighlight.tsx +4 -2
  204. package/src/components/touchables/TouchableNativeFeedback.android.tsx +8 -2
  205. package/src/components/touchables/TouchableOpacity.tsx +1 -0
  206. package/src/getShadowNodeFromRef.ts +11 -4
  207. package/src/handlers/PanGestureHandler.ts +15 -0
  208. package/src/handlers/gestures/GestureDetector/Wrap.tsx +78 -13
  209. package/src/handlers/gestures/GestureDetector/index.tsx +4 -1
  210. package/src/handlers/gestures/GestureDetector/useDetectorUpdater.ts +4 -1
  211. package/src/handlers/gestures/GestureDetector/useMountReactions.ts +6 -0
  212. package/src/handlers/gestures/GestureDetector/useViewRefHandler.ts +5 -2
  213. package/src/handlers/gestures/gestureStateManager.web.ts +9 -1
  214. package/src/handlers/gestures/panGesture.ts +6 -3
  215. package/src/hostInstance.ts +57 -0
  216. package/src/index.ts +1 -0
  217. package/src/mocks/mocks.tsx +6 -2
  218. package/src/specs/NativeRNGestureHandlerModule.ts +16 -10
  219. package/src/specs/RNGestureHandlerButtonNativeComponent.ts +16 -14
  220. package/src/specs/RNGestureHandlerRootViewNativeComponent.ts +3 -3
  221. package/src/web/detectors/RotationGestureDetector.ts +1 -1
  222. package/src/web/handlers/LongPressGestureHandler.ts +3 -1
  223. package/src/web/handlers/NativeViewGestureHandler.ts +11 -2
  224. package/src/web/handlers/PanGestureHandler.ts +8 -11
  225. package/src/web/handlers/TapGestureHandler.ts +1 -1
  226. package/src/web/tools/GestureHandlerOrchestrator.ts +19 -0
  227. package/src/web/tools/WheelEventManager.ts +1 -0
@@ -1 +1 @@
1
- {"version":3,"file":"WheelEventManager.d.ts","sourceRoot":"","sources":["../../../../src/web/tools/WheelEventManager.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAc,MAAM,eAAe,CAAC;AAGzD,MAAM,CAAC,OAAO,OAAO,iBAAkB,SAAQ,YAAY,CAAC,WAAW,CAAC;IACtE,OAAO,CAAC,UAAU,CAAkB;IAEpC,OAAO,CAAC,UAAU,CAEhB;IAEF,OAAO,CAAC,aAAa,CAMnB;IAEK,iBAAiB,IAAI,IAAI;IAKzB,mBAAmB,IAAI,IAAI;IAKlC,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,YAAY;IAe5C,YAAY,IAAI,IAAI;CAG5B"}
1
+ {"version":3,"file":"WheelEventManager.d.ts","sourceRoot":"","sources":["../../../../src/web/tools/WheelEventManager.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAc,MAAM,eAAe,CAAC;AAGzD,MAAM,CAAC,OAAO,OAAO,iBAAkB,SAAQ,YAAY,CAAC,WAAW,CAAC;IACtE,OAAO,CAAC,UAAU,CAAkB;IAEpC,OAAO,CAAC,UAAU,CAEhB;IAEF,OAAO,CAAC,aAAa,CAMnB;IAEK,iBAAiB,IAAI,IAAI;IAKzB,mBAAmB,IAAI,IAAI;IAKlC,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,YAAY;IAe5C,YAAY,IAAI,IAAI;CAI5B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-gesture-handler",
3
- "version": "2.32.0",
3
+ "version": "2.33.0",
4
4
  "description": "Declarative API exposing native platform touch and gesture system to React Native",
5
5
  "scripts": {
6
6
  "test": "jest",
@@ -80,8 +80,8 @@
80
80
  "@babel/core": "^7.25.2",
81
81
  "@babel/preset-env": "^7.25.3",
82
82
  "@babel/preset-typescript": "^7.12.7",
83
- "@react-native/babel-preset": "0.86.0",
84
- "@react-native/jest-preset": "0.86.0",
83
+ "@react-native/babel-preset": "0.87.1",
84
+ "@react-native/jest-preset": "0.87.1",
85
85
  "@testing-library/react-native": "^12.5.1",
86
86
  "@types/hoist-non-react-statics": "^3.3.1",
87
87
  "@types/invariant": "^2.2.37",
@@ -103,12 +103,12 @@
103
103
  "madge": "^6.1.0",
104
104
  "prettier": "3.3.3",
105
105
  "react": "19.2.3",
106
- "react-native": "0.86.0",
106
+ "react-native": "0.87.1",
107
107
  "react-native-builder-bob": "^0.40.13",
108
- "react-native-reanimated": "~4.4.1",
109
- "react-native-worklets": "0.9.1",
108
+ "react-native-reanimated": "~4.6.0",
109
+ "react-native-worklets": "0.12.1",
110
110
  "react-test-renderer": "19.2.3",
111
- "typescript": "~5.8.3"
111
+ "typescript": "~6.0.3"
112
112
  },
113
113
  "peerDependencies": {
114
114
  "react": "*",
@@ -89,6 +89,20 @@ export interface RawButtonProps
89
89
  */
90
90
  // eslint-disable-next-line @typescript-eslint/ban-types
91
91
  testOnly_onLongPress?: Function | null | undefined;
92
+
93
+ /**
94
+ * Used for testing-library compatibility, not passed to the native component.
95
+ * @deprecated test-only props are deprecated and will be removed in the future.
96
+ */
97
+ // eslint-disable-next-line @typescript-eslint/ban-types
98
+ testOnly_onHoverIn?: Function | null | undefined;
99
+
100
+ /**
101
+ * Used for testing-library compatibility, not passed to the native component.
102
+ * @deprecated test-only props are deprecated and will be removed in the future.
103
+ */
104
+ // eslint-disable-next-line @typescript-eslint/ban-types
105
+ testOnly_onHoverOut?: Function | null | undefined;
92
106
  }
93
107
  interface ButtonWithRefProps {
94
108
  innerRef?: React.ForwardedRef<React.ComponentType<any>> | undefined;
@@ -5,6 +5,8 @@ import {
5
5
  RefAttributes,
6
6
  ReactElement,
7
7
  } from 'react';
8
+ // Type-only: the value export is a deprecation-warning getter on RN 0.87+ (see below).
9
+ import type { DrawerLayoutAndroid as RNDrawerLayoutAndroid } from 'react-native';
8
10
  import {
9
11
  ScrollView as RNScrollView,
10
12
  ScrollViewProps as RNScrollViewProps,
@@ -12,7 +14,6 @@ import {
12
14
  SwitchProps as RNSwitchProps,
13
15
  TextInput as RNTextInput,
14
16
  TextInputProps as RNTextInputProps,
15
- DrawerLayoutAndroid as RNDrawerLayoutAndroid,
16
17
  DrawerLayoutAndroidProps as RNDrawerLayoutAndroidProps,
17
18
  FlatList as RNFlatList,
18
19
  FlatListProps as RNFlatListProps,
@@ -43,7 +44,7 @@ const GHScrollView = createNativeWrapper<PropsWithChildren<RNScrollViewProps>>(
43
44
  }
44
45
  );
45
46
  export const ScrollView = React.forwardRef<
46
- RNScrollView,
47
+ React.ComponentRef<typeof RNScrollView>,
47
48
  RNScrollViewProps & NativeViewGestureHandlerProps
48
49
  >((props, ref) => {
49
50
  const refreshControlGestureRef = React.useRef<RefreshControl>(null);
@@ -70,7 +71,8 @@ export const ScrollView = React.forwardRef<
70
71
  // Backward type compatibility with https://github.com/software-mansion/react-native-gesture-handler/blob/db78d3ca7d48e8ba57482d3fe9b0a15aa79d9932/react-native-gesture-handler.d.ts#L440-L457
71
72
  // include methods of wrapped components by creating an intersection type with the RN component instead of duplicating them.
72
73
  // eslint-disable-next-line @typescript-eslint/no-redeclare
73
- export type ScrollView = typeof GHScrollView & RNScrollView;
74
+ export type ScrollView = typeof GHScrollView &
75
+ React.ComponentRef<typeof RNScrollView>;
74
76
 
75
77
  export const Switch = createNativeWrapper<RNSwitchProps>(RNSwitch, {
76
78
  shouldCancelWhenOutside: false,
@@ -84,12 +86,41 @@ export const TextInput = createNativeWrapper<RNTextInputProps>(RNTextInput);
84
86
  // eslint-disable-next-line @typescript-eslint/no-redeclare
85
87
  export type TextInput = typeof TextInput & RNTextInput;
86
88
 
87
- export const DrawerLayoutAndroid = createNativeWrapper<
88
- PropsWithChildren<RNDrawerLayoutAndroidProps>
89
- >(RNDrawerLayoutAndroid, { disallowInterruption: true });
89
+ // RN's `DrawerLayoutAndroid` export is a getter that logs a deprecation
90
+ // warning on access, so resolve it on first render instead of module load.
91
+ // `require` is used on purpose: `import * as RN` would read every export
92
+ // eagerly under Metro's `experimentalImportSupport`.
93
+ let DrawerLayoutAndroidImpl: typeof RNDrawerLayoutAndroid | undefined;
94
+
95
+ const LazyDrawerLayoutAndroid = (
96
+ props: PropsWithChildren<RNDrawerLayoutAndroidProps> & {
97
+ ref?: React.Ref<React.ComponentRef<typeof RNDrawerLayoutAndroid> | null>;
98
+ }
99
+ ) => {
100
+ if (!DrawerLayoutAndroidImpl) {
101
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
102
+ const { DrawerLayoutAndroid } = require('react-native') as {
103
+ DrawerLayoutAndroid: typeof RNDrawerLayoutAndroid;
104
+ };
105
+ DrawerLayoutAndroidImpl = DrawerLayoutAndroid;
106
+ }
107
+ return <DrawerLayoutAndroidImpl {...props} />;
108
+ };
109
+ LazyDrawerLayoutAndroid.displayName = 'DrawerLayoutAndroid';
110
+
111
+ export const DrawerLayoutAndroid: React.ComponentType<
112
+ PropsWithChildren<RNDrawerLayoutAndroidProps> &
113
+ NativeViewGestureHandlerProps & {
114
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
115
+ ref?: React.Ref<React.ComponentType<any> | null>;
116
+ }
117
+ > = createNativeWrapper<PropsWithChildren<RNDrawerLayoutAndroidProps>>(
118
+ LazyDrawerLayoutAndroid,
119
+ { disallowInterruption: true }
120
+ );
90
121
  // eslint-disable-next-line @typescript-eslint/no-redeclare
91
122
  export type DrawerLayoutAndroid = typeof DrawerLayoutAndroid &
92
- RNDrawerLayoutAndroid;
123
+ React.ComponentRef<typeof RNDrawerLayoutAndroid>;
93
124
 
94
125
  export const FlatList = React.forwardRef((props, ref) => {
95
126
  const refreshControlGestureRef = React.useRef<RefreshControl>(null);
@@ -1,6 +1,10 @@
1
1
  import * as React from 'react';
2
2
  import { View } from 'react-native';
3
3
 
4
- export default React.forwardRef<React.ComponentRef<typeof View>>(
5
- (props, ref) => <View ref={ref} accessibilityRole="button" {...props} />
6
- );
4
+ const GestureHandlerButton: React.ForwardRefExoticComponent<
5
+ React.RefAttributes<React.ComponentRef<typeof View>>
6
+ > = React.forwardRef<React.ComponentRef<typeof View>>((props, ref) => (
7
+ <View ref={ref} accessibilityRole="button" {...props} />
8
+ ));
9
+
10
+ export default GestureHandlerButton;
@@ -69,6 +69,7 @@ const Pressable = (props: PressableProps) => {
69
69
  simultaneousWithExternalGesture,
70
70
  requireExternalGestureToFail,
71
71
  blocksExternalGesture,
72
+ ref,
72
73
  ...remainingProps
73
74
  } = props;
74
75
 
@@ -78,7 +79,7 @@ const Pressable = (props: PressableProps) => {
78
79
  blocksExternalGesture,
79
80
  };
80
81
 
81
- const [pressedState, setPressedState] = useState(testOnly_pressed ?? false);
82
+ const [pressedState, setPressedState] = useState(false);
82
83
 
83
84
  const longPressTimeoutRef = useRef<number | null>(null);
84
85
  const pressDelayTimeoutRef = useRef<number | null>(null);
@@ -217,6 +218,24 @@ const Pressable = (props: PressableProps) => {
217
218
  const hoverInTimeout = useRef<number | null>(null);
218
219
  const hoverOutTimeout = useRef<number | null>(null);
219
220
 
221
+ useEffect(
222
+ () => () => {
223
+ if (longPressTimeoutRef.current) {
224
+ clearTimeout(longPressTimeoutRef.current);
225
+ }
226
+ if (pressDelayTimeoutRef.current) {
227
+ clearTimeout(pressDelayTimeoutRef.current);
228
+ }
229
+ if (hoverInTimeout.current) {
230
+ clearTimeout(hoverInTimeout.current);
231
+ }
232
+ if (hoverOutTimeout.current) {
233
+ clearTimeout(hoverOutTimeout.current);
234
+ }
235
+ },
236
+ []
237
+ );
238
+
220
239
  const hoverGesture = useMemo(
221
240
  () =>
222
241
  Gesture.Hover()
@@ -353,12 +372,17 @@ const Pressable = (props: PressableProps) => {
353
372
  const pointerStyle: StyleProp<ViewStyle> =
354
373
  Platform.OS === 'web' ? { cursor: 'pointer' } : {};
355
374
 
375
+ // `testOnly_pressed` forces the pressed state for snapshots/tests. Derive the
376
+ // displayed value from it each render, keeping the interactive `pressedState`
377
+ // independent (seeded to false) so clearing the prop doesn't leave it stuck.
378
+ const displayPressed = testOnly_pressed ?? pressedState;
379
+
356
380
  const styleProp =
357
- typeof style === 'function' ? style({ pressed: pressedState }) : style;
381
+ typeof style === 'function' ? style({ pressed: displayPressed }) : style;
358
382
 
359
383
  const childrenProp =
360
384
  typeof children === 'function'
361
- ? children({ pressed: pressedState })
385
+ ? children({ pressed: displayPressed })
362
386
  : children;
363
387
 
364
388
  const rippleColor = useMemo(() => {
@@ -385,6 +409,7 @@ const Pressable = (props: PressableProps) => {
385
409
  <GestureDetector gesture={gesture}>
386
410
  <NativeButton
387
411
  {...remainingProps}
412
+ ref={ref as React.Ref<React.ComponentRef<typeof NativeButton>>}
388
413
  onLayout={setDimensions}
389
414
  accessible={accessible !== false}
390
415
  hitSlop={appliedHitSlop}
@@ -392,11 +417,15 @@ const Pressable = (props: PressableProps) => {
392
417
  touchSoundDisabled={android_disableSound ?? undefined}
393
418
  rippleColor={rippleColor}
394
419
  rippleRadius={android_ripple?.radius ?? undefined}
420
+ borderless={android_ripple?.borderless ?? undefined}
421
+ foreground={android_ripple?.foreground ?? undefined}
395
422
  style={[pointerStyle, styleProp]}
396
423
  testOnly_onPress={IS_TEST_ENV ? onPress : undefined}
397
424
  testOnly_onPressIn={IS_TEST_ENV ? onPressIn : undefined}
398
425
  testOnly_onPressOut={IS_TEST_ENV ? onPressOut : undefined}
399
- testOnly_onLongPress={IS_TEST_ENV ? onLongPress : undefined}>
426
+ testOnly_onLongPress={IS_TEST_ENV ? onLongPress : undefined}
427
+ testOnly_onHoverIn={IS_TEST_ENV ? onHoverIn : undefined}
428
+ testOnly_onHoverOut={IS_TEST_ENV ? onHoverOut : undefined}>
400
429
  {childrenProp}
401
430
  {__DEV__ ? (
402
431
  <PressabilityDebugView color="red" hitSlop={normalizedHitSlop} />
@@ -66,7 +66,7 @@ export interface PressableProps
66
66
  /**
67
67
  * A reference to the pressable element.
68
68
  */
69
- ref?: React.Ref<View>;
69
+ ref?: React.Ref<React.ComponentRef<typeof View>>;
70
70
 
71
71
  /**
72
72
  * Either children or a render prop that receives a boolean reflecting whether
@@ -1,4 +1,5 @@
1
1
  export type {
2
+ PressableEvent,
2
3
  PressableProps,
3
4
  PressableStateCallbackType,
4
5
  } from './PressableProps';
@@ -263,7 +263,9 @@ const defaultProps = {
263
263
  };
264
264
 
265
265
  // StatusBar.setHidden and Keyboard.dismiss cannot be directly referenced in worklets.
266
+ // eslint-disable-next-line @typescript-eslint/unbound-method
266
267
  const setStatusBarHidden = StatusBar.setHidden;
268
+ // eslint-disable-next-line @typescript-eslint/unbound-method
267
269
  const dismissKeyboard = Keyboard.dismiss;
268
270
 
269
271
  const DrawerLayout = forwardRef<DrawerLayoutMethods, DrawerLayoutProps>(
@@ -320,7 +322,7 @@ const DrawerLayout = forwardRef<DrawerLayoutMethods, DrawerLayoutProps>(
320
322
 
321
323
  useDerivedValue(() => {
322
324
  onDrawerSlide && runOnJS(onDrawerSlide)(openValue.value);
323
- }, []);
325
+ });
324
326
 
325
327
  const isDrawerOpen = useSharedValue(false);
326
328
 
@@ -420,6 +422,7 @@ const DrawerLayout = forwardRef<DrawerLayoutMethods, DrawerLayoutProps>(
420
422
  );
421
423
  },
422
424
  [
425
+ animationSpeedProp,
423
426
  openValue,
424
427
  emitStateChanged,
425
428
  isDrawerOpen,
@@ -4,8 +4,15 @@ import {
4
4
  useImperativeHandle,
5
5
  ForwardedRef,
6
6
  useState,
7
+ useRef,
7
8
  } from 'react';
8
- import { LayoutChangeEvent, View, I18nManager, StyleSheet } from 'react-native';
9
+ import {
10
+ LayoutChangeEvent,
11
+ View,
12
+ I18nManager,
13
+ Platform,
14
+ StyleSheet,
15
+ } from 'react-native';
9
16
  import Animated, {
10
17
  useSharedValue,
11
18
  interpolate,
@@ -42,6 +49,21 @@ const DEFAULT_OVERSHOOT_FRICTION = 1;
42
49
  const DEFAULT_DRAG_OFFSET = 10;
43
50
  const DEFAULT_ENABLE_TRACKING_TWO_FINGER_GESTURE = false;
44
51
 
52
+ function useEventCallback<Args extends unknown[]>(
53
+ callback: ((...args: Args) => void) | undefined
54
+ ): ((...args: Args) => void) | undefined {
55
+ const callbackRef = useRef(callback);
56
+ callbackRef.current = callback;
57
+
58
+ const stableCallback = useCallback((...args: Args) => {
59
+ callbackRef.current?.(...args);
60
+ }, []);
61
+
62
+ // Keep a stable wrapper only while a user callback exists, so the existing
63
+ // truthiness checks can still skip `runOnJS` when the prop is absent.
64
+ return callback ? stableCallback : undefined;
65
+ }
66
+
45
67
  const Swipeable = (props: SwipeableProps) => {
46
68
  const {
47
69
  ref,
@@ -60,12 +82,12 @@ const Swipeable = (props: SwipeableProps) => {
60
82
  dragOffsetFromRightEdge = DEFAULT_DRAG_OFFSET,
61
83
  friction = DEFAULT_FRICTION,
62
84
  overshootFriction = DEFAULT_OVERSHOOT_FRICTION,
63
- onSwipeableOpenStartDrag,
64
- onSwipeableCloseStartDrag,
65
- onSwipeableWillOpen,
66
- onSwipeableWillClose,
67
- onSwipeableOpen,
68
- onSwipeableClose,
85
+ onSwipeableOpenStartDrag: onSwipeableOpenStartDragProp,
86
+ onSwipeableCloseStartDrag: onSwipeableCloseStartDragProp,
87
+ onSwipeableWillOpen: onSwipeableWillOpenProp,
88
+ onSwipeableWillClose: onSwipeableWillCloseProp,
89
+ onSwipeableOpen: onSwipeableOpenProp,
90
+ onSwipeableClose: onSwipeableCloseProp,
69
91
  renderLeftActions,
70
92
  renderRightActions,
71
93
  simultaneousWithExternalGesture,
@@ -88,6 +110,17 @@ const Swipeable = (props: SwipeableProps) => {
88
110
  ]
89
111
  );
90
112
 
113
+ const onSwipeableOpenStartDrag = useEventCallback(
114
+ onSwipeableOpenStartDragProp
115
+ );
116
+ const onSwipeableCloseStartDrag = useEventCallback(
117
+ onSwipeableCloseStartDragProp
118
+ );
119
+ const onSwipeableWillOpen = useEventCallback(onSwipeableWillOpenProp);
120
+ const onSwipeableWillClose = useEventCallback(onSwipeableWillCloseProp);
121
+ const onSwipeableOpen = useEventCallback(onSwipeableOpenProp);
122
+ const onSwipeableClose = useEventCallback(onSwipeableCloseProp);
123
+
91
124
  const [shouldEnableTap, setShouldEnableTap] = useState(false);
92
125
  const rowState = useSharedValue<number>(0);
93
126
 
@@ -371,7 +404,10 @@ const Swipeable = (props: SwipeableProps) => {
371
404
 
372
405
  const leftActionAnimation = useAnimatedStyle(() => {
373
406
  return {
374
- opacity: showLeftProgress.value === 0 ? 0 : 1,
407
+ // Both action containers use `absoluteFill` and overlap, so the
408
+ // inactive one must not intercept touches meant for the visible
409
+ // actions.
410
+ pointerEvents: showLeftProgress.value === 0 ? 'none' : 'auto',
375
411
  };
376
412
  });
377
413
 
@@ -401,7 +437,10 @@ const Swipeable = (props: SwipeableProps) => {
401
437
 
402
438
  const rightActionAnimation = useAnimatedStyle(() => {
403
439
  return {
404
- opacity: showRightProgress.value === 0 ? 0 : 1,
440
+ // Both action containers use `absoluteFill` and overlap, so the
441
+ // inactive one must not intercept touches meant for the visible
442
+ // actions.
443
+ pointerEvents: showRightProgress.value === 0 ? 'none' : 'auto',
405
444
  };
406
445
  });
407
446
 
@@ -570,7 +609,7 @@ const Swipeable = (props: SwipeableProps) => {
570
609
  transform: [{ translateX: appliedTranslation.value }],
571
610
  pointerEvents: rowState.value === 0 ? 'auto' : 'box-only',
572
611
  }),
573
- [appliedTranslation, rowState]
612
+ Platform.OS === 'web' ? [appliedTranslation, rowState] : undefined
574
613
  );
575
614
 
576
615
  const swipeableComponent = (
@@ -317,7 +317,9 @@ export default class Swipeable extends Component<
317
317
  outputRange: [0, 0, 1],
318
318
  })
319
319
  : new Animated.Value(0);
320
- this.leftActionTranslate = this.showLeftAction.interpolate({
320
+ this.leftActionTranslate = (
321
+ this.showLeftAction as Animated.Value
322
+ ).interpolate({
321
323
  inputRange: [0, Number.MIN_VALUE],
322
324
  outputRange: [-10000, 0],
323
325
  extrapolate: 'clamp',
@@ -329,7 +331,9 @@ export default class Swipeable extends Component<
329
331
  outputRange: [1, 0, 0],
330
332
  })
331
333
  : new Animated.Value(0);
332
- this.rightActionTranslate = this.showRightAction.interpolate({
334
+ this.rightActionTranslate = (
335
+ this.showRightAction as Animated.Value
336
+ ).interpolate({
333
337
  inputRange: [0, Number.MIN_VALUE],
334
338
  outputRange: [-10000, 0],
335
339
  extrapolate: 'clamp',
@@ -11,16 +11,16 @@ import { GestureDetector } from '../handlers/gestures/GestureDetector';
11
11
  type TextProps = RNTextProps & {
12
12
  ref?: Ref<ComponentRef<typeof RNText> | null>;
13
13
  };
14
- type RNGHTextRef = Ref<RNText | null> & { rngh?: boolean };
14
+ type RNGHTextRef = Ref<ComponentRef<typeof RNText> | null> & { rngh?: boolean };
15
15
 
16
16
  export const Text = (props: TextProps) => {
17
17
  const { onPress, onLongPress, ref, ...rest } = props;
18
18
 
19
- const textRef = useRef<RNText | null>(null);
19
+ const textRef = useRef<ComponentRef<typeof RNText> | null>(null);
20
20
  const native = useMemo(() => Gesture.Native().runOnJS(true), []);
21
21
 
22
22
  const refHandler = useMemo(() => {
23
- const handler: RNGHTextRef = (node: RNText | null) => {
23
+ const handler: RNGHTextRef = (node: ComponentRef<typeof RNText> | null) => {
24
24
  textRef.current = node;
25
25
 
26
26
  if (!ref) {
@@ -3,11 +3,11 @@ import { Component } from 'react';
3
3
  import GenericTouchable, { TOUCHABLE_STATE } from './GenericTouchable';
4
4
  import type { GenericTouchableProps } from './GenericTouchableProps';
5
5
  import {
6
- StyleSheet,
7
6
  View,
8
7
  TouchableHighlightProps as RNTouchableHighlightProps,
9
8
  ColorValue,
10
9
  ViewProps,
10
+ ViewStyle,
11
11
  } from 'react-native';
12
12
 
13
13
  interface State {
@@ -88,7 +88,9 @@ export default class TouchableHighlight extends Component<
88
88
  this.props.children
89
89
  ) as React.ReactElement<ViewProps>; // TODO: not sure if OK but fixes error
90
90
  return React.cloneElement(child, {
91
- style: StyleSheet.compose(child.props.style, this.state.extraChildStyle),
91
+ style: this.state.extraChildStyle
92
+ ? [child.props.style, this.state.extraChildStyle as ViewStyle]
93
+ : child.props.style,
92
94
  });
93
95
  }
94
96
 
@@ -41,7 +41,12 @@ export default class TouchableNativeFeedback extends Component<TouchableNativeFe
41
41
  color: ColorValue,
42
42
  borderless: boolean,
43
43
  rippleRadius?: number
44
- ) => ({
44
+ ): {
45
+ type: 'RippleAndroid';
46
+ color: ColorValue;
47
+ borderless: boolean;
48
+ rippleRadius: number | undefined;
49
+ } => ({
45
50
  type: 'RippleAndroid',
46
51
  color,
47
52
  borderless,
@@ -59,7 +64,8 @@ export default class TouchableNativeFeedback extends Component<TouchableNativeFe
59
64
  // TODO(TS): check if it works the same as previous implementation - looks like it works the same as RN component, so it should be ok
60
65
  if (background.type === 'RippleAndroid') {
61
66
  extraProps['borderless'] = background.borderless;
62
- extraProps['rippleColor'] = background.color;
67
+ extraProps['rippleColor'] =
68
+ background.color as TouchableNativeFeedbackExtraProps['rippleColor'];
63
69
  } else if (background.type === 'ThemeAttrAndroid') {
64
70
  extraProps['borderless'] =
65
71
  background.attribute === 'selectableItemBackgroundBorderless';
@@ -43,6 +43,7 @@ export default class TouchableOpacity extends Component<TouchableOpacityProps> {
43
43
  Animated.timing(this.opacity, {
44
44
  toValue: value,
45
45
  duration: duration,
46
+ // eslint-disable-next-line @typescript-eslint/unbound-method
46
47
  easing: Easing.inOut(Easing.quad),
47
48
  useNativeDriver: this.props.useNativeAnimations ?? true,
48
49
  }).start();
@@ -1,3 +1,5 @@
1
+ import { isHostInstance } from './hostInstance';
2
+
1
3
  // Used by GestureDetector (unsupported on web at the moment) to check whether the
2
4
  // attached view may get flattened on Fabric. This implementation causes errors
3
5
  // on web due to the static resolution of `require` statements by webpack breaking
@@ -8,8 +10,10 @@ let getInternalInstanceHandleFromPublicInstance: (ref: unknown) => {
8
10
  };
9
11
 
10
12
  export function getShadowNodeFromRef(ref: unknown) {
13
+ const isAlreadyHostInstance = isHostInstance(ref);
14
+
11
15
  // Load findHostInstance_DEPRECATED lazily because it may not be available before render
12
- if (findHostInstance_DEPRECATED === undefined) {
16
+ if (!isAlreadyHostInstance && findHostInstance_DEPRECATED === undefined) {
13
17
  try {
14
18
  // eslint-disable-next-line @typescript-eslint/no-var-requires
15
19
  const ReactFabric = require('react-native/Libraries/Renderer/shims/ReactFabric');
@@ -43,8 +47,11 @@ export function getShadowNodeFromRef(ref: unknown) {
43
47
  }
44
48
  }
45
49
 
50
+ const hostInstance = isAlreadyHostInstance
51
+ ? ref
52
+ : findHostInstance_DEPRECATED(ref);
53
+
46
54
  // @ts-ignore Fabric
47
- return getInternalInstanceHandleFromPublicInstance(
48
- findHostInstance_DEPRECATED(ref)
49
- ).stateNode.node;
55
+ return getInternalInstanceHandleFromPublicInstance(hostInstance).stateNode
56
+ .node;
50
57
  }
@@ -65,9 +65,24 @@ interface CommonPanProperties {
65
65
  */
66
66
  maxPointers?: number;
67
67
 
68
+ /**
69
+ * Minimum speed the pointer has to reach in order to activate the handler.
70
+ * Expressed in points per second.
71
+ */
68
72
  minVelocity?: number;
73
+
74
+ /**
75
+ * Minimum speed along X axis the pointer has to reach in order to activate
76
+ * the handler. Expressed in points per second.
77
+ */
69
78
  minVelocityX?: number;
79
+
80
+ /**
81
+ * Minimum speed along Y axis the pointer has to reach in order to activate
82
+ * the handler. Expressed in points per second.
83
+ */
70
84
  minVelocityY?: number;
85
+
71
86
  activateAfterLongPress?: number;
72
87
  }
73
88
 
@@ -1,4 +1,10 @@
1
1
  import React from 'react';
2
+ import type { WrapRef } from '../../../hostInstance';
3
+ import {
4
+ assignRef,
5
+ isHostInstance,
6
+ preferHostInstance,
7
+ } from '../../../hostInstance';
2
8
  import { Reanimated } from '../reanimatedWrapper';
3
9
  import { tagMessage } from '../../../utils';
4
10
 
@@ -7,20 +13,69 @@ export class Wrap extends React.Component<{
7
13
  // Implicit `children` prop has been removed in @types/react^18.0.0
8
14
  children?: React.ReactNode;
9
15
  }> {
10
- render() {
16
+ private childInstance: unknown = null;
17
+ private hostInstance: unknown = null;
18
+ private childRef: WrapRef = undefined;
19
+ private attachedChildRef: WrapRef = undefined;
20
+ private childRefCleanup: (() => void) | undefined = undefined;
21
+
22
+ // eslint-disable-next-line @eslint-react/no-unused-class-component-members
23
+ public getHostInstance() {
24
+ return this.hostInstance;
25
+ }
26
+
27
+ private detachChildRef() {
28
+ if (this.childRefCleanup !== undefined) {
29
+ this.childRefCleanup();
30
+ } else if (this.attachedChildRef) {
31
+ assignRef(this.attachedChildRef, null);
32
+ }
33
+
34
+ this.childRefCleanup = undefined;
35
+ this.attachedChildRef = undefined;
36
+ }
37
+
38
+ private attachChildRef(instance: unknown) {
39
+ this.attachedChildRef = this.childRef;
40
+
41
+ this.childRefCleanup = assignRef(this.attachedChildRef, instance);
42
+ }
43
+
44
+ private handleChildRef = (instance: unknown) => {
45
+ this.childInstance = instance;
46
+
47
+ const resolved = preferHostInstance(instance);
48
+ this.hostInstance = isHostInstance(resolved) ? resolved : null;
49
+
50
+ this.detachChildRef();
51
+
52
+ if (instance !== null && instance !== undefined) {
53
+ this.attachChildRef(instance);
54
+ }
55
+ };
56
+
57
+ override componentDidUpdate() {
58
+ if (
59
+ this.childRef === this.attachedChildRef ||
60
+ this.childInstance === null
61
+ ) {
62
+ return;
63
+ }
64
+
65
+ this.detachChildRef();
66
+ this.attachChildRef(this.childInstance);
67
+ }
68
+
69
+ override render() {
70
+ // I don't think that fighting with types over such a simple function is worth it
71
+ // The only thing it does is add 'collapsable: false' to the child component
72
+ // to make sure it is in the native view hierarchy so the detector can find
73
+ // correct viewTag to attach to.
74
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
75
+ let child: any;
76
+
11
77
  try {
12
- // I don't think that fighting with types over such a simple function is worth it
13
- // The only thing it does is add 'collapsable: false' to the child component
14
- // to make sure it is in the native view hierarchy so the detector can find
15
- // correct viewTag to attach to.
16
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
- const child: any = React.Children.only(this.props.children);
18
- return React.cloneElement(
19
- child,
20
- { collapsable: false },
21
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
22
- child.props.children
23
- );
78
+ child = React.Children.only(this.props.children);
24
79
  } catch (e) {
25
80
  throw new Error(
26
81
  tagMessage(
@@ -28,6 +83,16 @@ export class Wrap extends React.Component<{
28
83
  )
29
84
  );
30
85
  }
86
+
87
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
88
+ this.childRef = child.props.ref as WrapRef;
89
+
90
+ return React.cloneElement(
91
+ child,
92
+ { collapsable: false, ref: this.handleChildRef },
93
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
94
+ child.props.children
95
+ );
31
96
  }
32
97
  }
33
98