react-native-gesture-handler 3.0.0-beta.3 → 3.0.0-beta.5

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 (419) hide show
  1. package/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt +42 -38
  2. package/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt +34 -8
  3. package/android/src/main/java/com/swmansion/gesturehandler/core/HoverGestureHandler.kt +3 -6
  4. package/android/src/main/java/com/swmansion/gesturehandler/core/ManualGestureHandler.kt +2 -0
  5. package/android/src/main/java/com/swmansion/gesturehandler/core/NativeViewGestureHandler.kt +68 -7
  6. package/android/src/main/java/com/swmansion/gesturehandler/core/OnJSResponderCancelListener.kt +6 -0
  7. package/android/src/main/java/com/swmansion/gesturehandler/core/PanGestureHandler.kt +2 -0
  8. package/android/src/main/java/com/swmansion/gesturehandler/core/PinchGestureHandler.kt +16 -6
  9. package/android/src/main/java/com/swmansion/gesturehandler/core/RotationGestureHandler.kt +17 -4
  10. package/android/src/main/java/com/swmansion/gesturehandler/core/ViewConfigurationHelper.kt +0 -1
  11. package/android/src/main/java/com/swmansion/gesturehandler/react/Extensions.kt +21 -0
  12. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt +160 -55
  13. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerDetectorView.kt +75 -98
  14. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerInteractionManager.kt +1 -1
  15. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerModule.kt +7 -10
  16. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRegistry.kt +64 -2
  17. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootHelper.kt +18 -8
  18. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootView.kt +15 -4
  19. package/android/src/main/java/com/swmansion/gesturehandler/react/RNViewConfigurationHelper.kt +0 -6
  20. package/apple/Handlers/RNForceTouchHandler.m +1 -1
  21. package/apple/Handlers/RNHoverHandler.m +11 -11
  22. package/apple/Handlers/RNLongPressHandler.m +2 -2
  23. package/apple/Handlers/RNManualHandler.m +5 -0
  24. package/apple/Handlers/RNNativeViewHandler.mm +114 -53
  25. package/apple/Handlers/RNPanHandler.m +7 -3
  26. package/apple/Handlers/RNPinchHandler.m +9 -3
  27. package/apple/Handlers/RNRotationHandler.m +7 -2
  28. package/apple/Handlers/RNTapHandler.m +1 -1
  29. package/apple/RNGestureHandler.h +18 -0
  30. package/apple/RNGestureHandler.mm +82 -33
  31. package/apple/RNGestureHandlerButton.h +12 -2
  32. package/apple/RNGestureHandlerButton.mm +208 -38
  33. package/apple/RNGestureHandlerButtonComponentView.mm +102 -6
  34. package/apple/RNGestureHandlerDetector.mm +99 -75
  35. package/apple/RNGestureHandlerModule.mm +11 -14
  36. package/apple/RNGestureHandlerRegistry.h +14 -1
  37. package/apple/RNGestureHandlerRegistry.m +56 -0
  38. package/apple/RNRootViewGestureRecognizer.m +4 -15
  39. package/lib/module/RNGestureHandlerModule.web.js +5 -1
  40. package/lib/module/RNGestureHandlerModule.web.js.map +1 -1
  41. package/lib/module/components/GestureButtons.js +23 -12
  42. package/lib/module/components/GestureButtons.js.map +1 -1
  43. package/lib/module/components/GestureHandlerButton.js.map +1 -1
  44. package/lib/module/components/GestureHandlerButton.web.js +113 -31
  45. package/lib/module/components/GestureHandlerButton.web.js.map +1 -1
  46. package/lib/module/components/Pressable/Pressable.js +2 -1
  47. package/lib/module/components/Pressable/Pressable.js.map +1 -1
  48. package/lib/module/components/Pressable/stateDefinitions.js +2 -0
  49. package/lib/module/components/Pressable/stateDefinitions.js.map +1 -1
  50. package/lib/module/components/ReanimatedDrawerLayout.js.map +1 -1
  51. package/lib/module/components/ReanimatedSwipeable/ReanimatedSwipeable.js +38 -5
  52. package/lib/module/components/ReanimatedSwipeable/ReanimatedSwipeable.js.map +1 -1
  53. package/lib/module/components/touchables/GenericTouchable.js +2 -6
  54. package/lib/module/components/touchables/GenericTouchable.js.map +1 -1
  55. package/lib/module/handlers/gestures/GestureDetector/useDetectorUpdater.js +1 -2
  56. package/lib/module/handlers/gestures/GestureDetector/useDetectorUpdater.js.map +1 -1
  57. package/lib/module/handlers/gestures/GestureDetector/utils.js +11 -48
  58. package/lib/module/handlers/gestures/GestureDetector/utils.js.map +1 -1
  59. package/lib/module/handlers/gestures/flingGesture.js +8 -0
  60. package/lib/module/handlers/gestures/flingGesture.js.map +1 -1
  61. package/lib/module/handlers/gestures/forceTouchGesture.js +3 -3
  62. package/lib/module/handlers/gestures/gesture.js +8 -0
  63. package/lib/module/handlers/gestures/gesture.js.map +1 -1
  64. package/lib/module/handlers/gestures/gestureComposition.js +28 -0
  65. package/lib/module/handlers/gestures/gestureComposition.js.map +1 -1
  66. package/lib/module/handlers/gestures/gestureObjects.js +27 -1
  67. package/lib/module/handlers/gestures/gestureObjects.js.map +1 -1
  68. package/lib/module/handlers/gestures/gestureStateManager.js +9 -0
  69. package/lib/module/handlers/gestures/gestureStateManager.js.map +1 -1
  70. package/lib/module/handlers/gestures/hoverGesture.js +8 -0
  71. package/lib/module/handlers/gestures/hoverGesture.js.map +1 -1
  72. package/lib/module/handlers/gestures/longPressGesture.js +8 -0
  73. package/lib/module/handlers/gestures/longPressGesture.js.map +1 -1
  74. package/lib/module/handlers/gestures/manualGesture.js +8 -0
  75. package/lib/module/handlers/gestures/manualGesture.js.map +1 -1
  76. package/lib/module/handlers/gestures/nativeGesture.js +8 -0
  77. package/lib/module/handlers/gestures/nativeGesture.js.map +1 -1
  78. package/lib/module/handlers/gestures/panGesture.js +13 -0
  79. package/lib/module/handlers/gestures/panGesture.js.map +1 -1
  80. package/lib/module/handlers/gestures/pinchGesture.js +13 -0
  81. package/lib/module/handlers/gestures/pinchGesture.js.map +1 -1
  82. package/lib/module/handlers/gestures/reanimatedWrapper.js +14 -2
  83. package/lib/module/handlers/gestures/reanimatedWrapper.js.map +1 -1
  84. package/lib/module/handlers/gestures/rotationGesture.js +8 -0
  85. package/lib/module/handlers/gestures/rotationGesture.js.map +1 -1
  86. package/lib/module/handlers/gestures/tapGesture.js +8 -0
  87. package/lib/module/handlers/gestures/tapGesture.js.map +1 -1
  88. package/lib/module/mocks/module.js +3 -2
  89. package/lib/module/mocks/module.js.map +1 -1
  90. package/lib/module/specs/NativeRNGestureHandlerModule.js.map +1 -1
  91. package/lib/module/specs/RNGestureHandlerButtonNativeComponent.ts +28 -13
  92. package/lib/module/v3/NativeProxy.js +5 -3
  93. package/lib/module/v3/NativeProxy.js.map +1 -1
  94. package/lib/module/v3/NativeProxy.web.js +2 -2
  95. package/lib/module/v3/NativeProxy.web.js.map +1 -1
  96. package/lib/module/v3/components/GestureButtons.js +11 -6
  97. package/lib/module/v3/components/GestureButtons.js.map +1 -1
  98. package/lib/module/v3/components/Pressable.js +3 -2
  99. package/lib/module/v3/components/Pressable.js.map +1 -1
  100. package/lib/module/v3/components/Touchable/Touchable.js +119 -32
  101. package/lib/module/v3/components/Touchable/Touchable.js.map +1 -1
  102. package/lib/module/v3/detectors/HostGestureDetector.web.js +180 -59
  103. package/lib/module/v3/detectors/HostGestureDetector.web.js.map +1 -1
  104. package/lib/module/v3/detectors/NativeDetector.js +3 -2
  105. package/lib/module/v3/detectors/NativeDetector.js.map +1 -1
  106. package/lib/module/v3/detectors/VirtualDetector/InterceptingGestureDetector.js +3 -4
  107. package/lib/module/v3/detectors/VirtualDetector/InterceptingGestureDetector.js.map +1 -1
  108. package/lib/module/v3/detectors/VirtualDetector/VirtualDetector.js +4 -2
  109. package/lib/module/v3/detectors/VirtualDetector/VirtualDetector.js.map +1 -1
  110. package/lib/module/v3/detectors/useGestureRelationsUpdater.js +23 -0
  111. package/lib/module/v3/detectors/useGestureRelationsUpdater.js.map +1 -0
  112. package/lib/module/v3/detectors/useNativeGestureRole.js +6 -0
  113. package/lib/module/v3/detectors/useNativeGestureRole.js.map +1 -0
  114. package/lib/module/v3/detectors/useNativeGestureRole.web.js +27 -0
  115. package/lib/module/v3/detectors/useNativeGestureRole.web.js.map +1 -0
  116. package/lib/module/v3/detectors/utils.js +10 -8
  117. package/lib/module/v3/detectors/utils.js.map +1 -1
  118. package/lib/module/v3/hooks/callbacks/useReanimatedEventHandler.js +17 -2
  119. package/lib/module/v3/hooks/callbacks/useReanimatedEventHandler.js.map +1 -1
  120. package/lib/module/v3/hooks/gestures/fling/useFlingGesture.js +2 -1
  121. package/lib/module/v3/hooks/gestures/fling/useFlingGesture.js.map +1 -1
  122. package/lib/module/v3/hooks/gestures/hover/useHoverGesture.js +2 -1
  123. package/lib/module/v3/hooks/gestures/hover/useHoverGesture.js.map +1 -1
  124. package/lib/module/v3/hooks/gestures/longPress/useLongPressGesture.js +2 -1
  125. package/lib/module/v3/hooks/gestures/longPress/useLongPressGesture.js.map +1 -1
  126. package/lib/module/v3/hooks/gestures/manual/useManualGesture.js +2 -1
  127. package/lib/module/v3/hooks/gestures/manual/useManualGesture.js.map +1 -1
  128. package/lib/module/v3/hooks/gestures/native/NativeTypes.js +1 -1
  129. package/lib/module/v3/hooks/gestures/native/NativeTypes.js.map +1 -1
  130. package/lib/module/v3/hooks/gestures/native/useNativeGesture.js +2 -1
  131. package/lib/module/v3/hooks/gestures/native/useNativeGesture.js.map +1 -1
  132. package/lib/module/v3/hooks/gestures/pan/usePanGesture.js +2 -1
  133. package/lib/module/v3/hooks/gestures/pan/usePanGesture.js.map +1 -1
  134. package/lib/module/v3/hooks/gestures/pinch/usePinchGesture.js +2 -1
  135. package/lib/module/v3/hooks/gestures/pinch/usePinchGesture.js.map +1 -1
  136. package/lib/module/v3/hooks/gestures/rotation/useRotationGesture.js +2 -1
  137. package/lib/module/v3/hooks/gestures/rotation/useRotationGesture.js.map +1 -1
  138. package/lib/module/v3/hooks/gestures/tap/useTapGesture.js +2 -1
  139. package/lib/module/v3/hooks/gestures/tap/useTapGesture.js.map +1 -1
  140. package/lib/module/v3/hooks/useGesture.js +4 -22
  141. package/lib/module/v3/hooks/useGesture.js.map +1 -1
  142. package/lib/module/v3/hooks/utils/configUtils.js +8 -6
  143. package/lib/module/v3/hooks/utils/configUtils.js.map +1 -1
  144. package/lib/module/v3/hooks/utils/eventHandlersUtils.js +31 -29
  145. package/lib/module/v3/hooks/utils/eventHandlersUtils.js.map +1 -1
  146. package/lib/module/v3/hooks/utils/index.js +1 -1
  147. package/lib/module/v3/hooks/utils/index.js.map +1 -1
  148. package/lib/module/v3/hooks/utils/propsWhiteList.js +1 -1
  149. package/lib/module/v3/hooks/utils/propsWhiteList.js.map +1 -1
  150. package/lib/module/v3/hooks/utils/reanimatedUtils.js +8 -2
  151. package/lib/module/v3/hooks/utils/reanimatedUtils.js.map +1 -1
  152. package/lib/module/web/constants.js +1 -0
  153. package/lib/module/web/constants.js.map +1 -1
  154. package/lib/module/web/detectors/RotationGestureDetector.js +18 -5
  155. package/lib/module/web/detectors/RotationGestureDetector.js.map +1 -1
  156. package/lib/module/web/detectors/ScaleGestureDetector.js +9 -1
  157. package/lib/module/web/detectors/ScaleGestureDetector.js.map +1 -1
  158. package/lib/module/web/handlers/GestureHandler.js +25 -5
  159. package/lib/module/web/handlers/GestureHandler.js.map +1 -1
  160. package/lib/module/web/handlers/HoverGestureHandler.js +1 -4
  161. package/lib/module/web/handlers/HoverGestureHandler.js.map +1 -1
  162. package/lib/module/web/handlers/ManualGestureHandler.js +1 -0
  163. package/lib/module/web/handlers/ManualGestureHandler.js.map +1 -1
  164. package/lib/module/web/handlers/NativeViewGestureHandler.js +65 -17
  165. package/lib/module/web/handlers/NativeViewGestureHandler.js.map +1 -1
  166. package/lib/module/web/handlers/PanGestureHandler.js +1 -0
  167. package/lib/module/web/handlers/PanGestureHandler.js.map +1 -1
  168. package/lib/module/web/handlers/PinchGestureHandler.js +4 -6
  169. package/lib/module/web/handlers/PinchGestureHandler.js.map +1 -1
  170. package/lib/module/web/handlers/RotationGestureHandler.js +4 -3
  171. package/lib/module/web/handlers/RotationGestureHandler.js.map +1 -1
  172. package/lib/module/web/interfaces.js +6 -0
  173. package/lib/module/web/interfaces.js.map +1 -1
  174. package/lib/module/web/tools/GestureHandlerOrchestrator.js +8 -2
  175. package/lib/module/web/tools/GestureHandlerOrchestrator.js.map +1 -1
  176. package/lib/module/web/tools/GestureLifecycleEvents.js +10 -0
  177. package/lib/module/web/tools/GestureLifecycleEvents.js.map +1 -0
  178. package/lib/module/web/tools/NodeManager.js +44 -0
  179. package/lib/module/web/tools/NodeManager.js.map +1 -1
  180. package/lib/module/web/tools/PointerEventManager.js +9 -0
  181. package/lib/module/web/tools/PointerEventManager.js.map +1 -1
  182. package/lib/typescript/RNGestureHandlerModule.web.d.ts +1 -1
  183. package/lib/typescript/RNGestureHandlerModule.web.d.ts.map +1 -1
  184. package/lib/typescript/components/GestureButtons.d.ts +14 -6
  185. package/lib/typescript/components/GestureButtons.d.ts.map +1 -1
  186. package/lib/typescript/components/GestureHandlerButton.d.ts +62 -8
  187. package/lib/typescript/components/GestureHandlerButton.d.ts.map +1 -1
  188. package/lib/typescript/components/GestureHandlerButton.web.d.ts +14 -3
  189. package/lib/typescript/components/GestureHandlerButton.web.d.ts.map +1 -1
  190. package/lib/typescript/components/Pressable/Pressable.d.ts.map +1 -1
  191. package/lib/typescript/components/Pressable/PressableProps.d.ts +1 -1
  192. package/lib/typescript/components/Pressable/PressableProps.d.ts.map +1 -1
  193. package/lib/typescript/components/Pressable/stateDefinitions.d.ts.map +1 -1
  194. package/lib/typescript/components/ReanimatedDrawerLayout.d.ts +16 -14
  195. package/lib/typescript/components/ReanimatedDrawerLayout.d.ts.map +1 -1
  196. package/lib/typescript/components/ReanimatedSwipeable/ReanimatedSwipeable.d.ts +2 -1
  197. package/lib/typescript/components/ReanimatedSwipeable/ReanimatedSwipeable.d.ts.map +1 -1
  198. package/lib/typescript/components/ReanimatedSwipeable/ReanimatedSwipeableProps.d.ts +30 -34
  199. package/lib/typescript/components/ReanimatedSwipeable/ReanimatedSwipeableProps.d.ts.map +1 -1
  200. package/lib/typescript/components/touchables/GenericTouchable.d.ts.map +1 -1
  201. package/lib/typescript/handlers/gestures/GestureDetector/useDetectorUpdater.d.ts.map +1 -1
  202. package/lib/typescript/handlers/gestures/GestureDetector/utils.d.ts +0 -1
  203. package/lib/typescript/handlers/gestures/GestureDetector/utils.d.ts.map +1 -1
  204. package/lib/typescript/handlers/gestures/flingGesture.d.ts +6 -0
  205. package/lib/typescript/handlers/gestures/flingGesture.d.ts.map +1 -1
  206. package/lib/typescript/handlers/gestures/forceTouchGesture.d.ts +3 -3
  207. package/lib/typescript/handlers/gestures/gesture.d.ts +6 -0
  208. package/lib/typescript/handlers/gestures/gesture.d.ts.map +1 -1
  209. package/lib/typescript/handlers/gestures/gestureComposition.d.ts +21 -0
  210. package/lib/typescript/handlers/gestures/gestureComposition.d.ts.map +1 -1
  211. package/lib/typescript/handlers/gestures/gestureObjects.d.ts +27 -1
  212. package/lib/typescript/handlers/gestures/gestureObjects.d.ts.map +1 -1
  213. package/lib/typescript/handlers/gestures/gestureStateManager.d.ts +6 -0
  214. package/lib/typescript/handlers/gestures/gestureStateManager.d.ts.map +1 -1
  215. package/lib/typescript/handlers/gestures/hoverGesture.d.ts +6 -0
  216. package/lib/typescript/handlers/gestures/hoverGesture.d.ts.map +1 -1
  217. package/lib/typescript/handlers/gestures/longPressGesture.d.ts +6 -0
  218. package/lib/typescript/handlers/gestures/longPressGesture.d.ts.map +1 -1
  219. package/lib/typescript/handlers/gestures/manualGesture.d.ts +6 -0
  220. package/lib/typescript/handlers/gestures/manualGesture.d.ts.map +1 -1
  221. package/lib/typescript/handlers/gestures/nativeGesture.d.ts +6 -0
  222. package/lib/typescript/handlers/gestures/nativeGesture.d.ts.map +1 -1
  223. package/lib/typescript/handlers/gestures/panGesture.d.ts +9 -0
  224. package/lib/typescript/handlers/gestures/panGesture.d.ts.map +1 -1
  225. package/lib/typescript/handlers/gestures/pinchGesture.d.ts +9 -0
  226. package/lib/typescript/handlers/gestures/pinchGesture.d.ts.map +1 -1
  227. package/lib/typescript/handlers/gestures/reanimatedWrapper.d.ts.map +1 -1
  228. package/lib/typescript/handlers/gestures/rotationGesture.d.ts +6 -0
  229. package/lib/typescript/handlers/gestures/rotationGesture.d.ts.map +1 -1
  230. package/lib/typescript/handlers/gestures/tapGesture.d.ts +6 -0
  231. package/lib/typescript/handlers/gestures/tapGesture.d.ts.map +1 -1
  232. package/lib/typescript/mocks/module.d.ts +1 -1
  233. package/lib/typescript/mocks/module.d.ts.map +1 -1
  234. package/lib/typescript/specs/NativeRNGestureHandlerModule.d.ts +2 -2
  235. package/lib/typescript/specs/NativeRNGestureHandlerModule.d.ts.map +1 -1
  236. package/lib/typescript/specs/RNGestureHandlerButtonNativeComponent.d.ts +19 -11
  237. package/lib/typescript/specs/RNGestureHandlerButtonNativeComponent.d.ts.map +1 -1
  238. package/lib/typescript/v3/NativeProxy.d.ts +1 -1
  239. package/lib/typescript/v3/NativeProxy.d.ts.map +1 -1
  240. package/lib/typescript/v3/NativeProxy.web.d.ts +1 -1
  241. package/lib/typescript/v3/NativeProxy.web.d.ts.map +1 -1
  242. package/lib/typescript/v3/components/GestureButtons.d.ts +1 -37
  243. package/lib/typescript/v3/components/GestureButtons.d.ts.map +1 -1
  244. package/lib/typescript/v3/components/GestureButtonsProps.d.ts +1 -1
  245. package/lib/typescript/v3/components/GestureButtonsProps.d.ts.map +1 -1
  246. package/lib/typescript/v3/components/GestureComponents.d.ts +3 -0
  247. package/lib/typescript/v3/components/GestureComponents.d.ts.map +1 -1
  248. package/lib/typescript/v3/components/GestureComponents.web.d.ts +4 -0
  249. package/lib/typescript/v3/components/GestureComponents.web.d.ts.map +1 -1
  250. package/lib/typescript/v3/components/Pressable.d.ts.map +1 -1
  251. package/lib/typescript/v3/components/Touchable/Touchable.d.ts.map +1 -1
  252. package/lib/typescript/v3/components/Touchable/TouchableProps.d.ts +48 -1
  253. package/lib/typescript/v3/components/Touchable/TouchableProps.d.ts.map +1 -1
  254. package/lib/typescript/v3/detectors/HostGestureDetector.web.d.ts +1 -1
  255. package/lib/typescript/v3/detectors/HostGestureDetector.web.d.ts.map +1 -1
  256. package/lib/typescript/v3/detectors/NativeDetector.d.ts.map +1 -1
  257. package/lib/typescript/v3/detectors/VirtualDetector/InterceptingGestureDetector.d.ts.map +1 -1
  258. package/lib/typescript/v3/detectors/VirtualDetector/VirtualDetector.d.ts.map +1 -1
  259. package/lib/typescript/v3/detectors/useGestureRelationsUpdater.d.ts +3 -0
  260. package/lib/typescript/v3/detectors/useGestureRelationsUpdater.d.ts.map +1 -0
  261. package/lib/typescript/v3/detectors/useNativeGestureRole.d.ts +3 -0
  262. package/lib/typescript/v3/detectors/useNativeGestureRole.d.ts.map +1 -0
  263. package/lib/typescript/v3/detectors/useNativeGestureRole.web.d.ts +3 -0
  264. package/lib/typescript/v3/detectors/useNativeGestureRole.web.d.ts.map +1 -0
  265. package/lib/typescript/v3/detectors/utils.d.ts +3 -3
  266. package/lib/typescript/v3/detectors/utils.d.ts.map +1 -1
  267. package/lib/typescript/v3/hooks/callbacks/useReanimatedEventHandler.d.ts.map +1 -1
  268. package/lib/typescript/v3/hooks/gestures/fling/useFlingGesture.d.ts +1 -1
  269. package/lib/typescript/v3/hooks/gestures/fling/useFlingGesture.d.ts.map +1 -1
  270. package/lib/typescript/v3/hooks/gestures/hover/useHoverGesture.d.ts +1 -1
  271. package/lib/typescript/v3/hooks/gestures/hover/useHoverGesture.d.ts.map +1 -1
  272. package/lib/typescript/v3/hooks/gestures/longPress/useLongPressGesture.d.ts +1 -1
  273. package/lib/typescript/v3/hooks/gestures/longPress/useLongPressGesture.d.ts.map +1 -1
  274. package/lib/typescript/v3/hooks/gestures/manual/useManualGesture.d.ts +1 -1
  275. package/lib/typescript/v3/hooks/gestures/manual/useManualGesture.d.ts.map +1 -1
  276. package/lib/typescript/v3/hooks/gestures/native/NativeTypes.d.ts +7 -0
  277. package/lib/typescript/v3/hooks/gestures/native/NativeTypes.d.ts.map +1 -1
  278. package/lib/typescript/v3/hooks/gestures/native/useNativeGesture.d.ts +1 -1
  279. package/lib/typescript/v3/hooks/gestures/native/useNativeGesture.d.ts.map +1 -1
  280. package/lib/typescript/v3/hooks/gestures/pan/usePanGesture.d.ts +1 -1
  281. package/lib/typescript/v3/hooks/gestures/pan/usePanGesture.d.ts.map +1 -1
  282. package/lib/typescript/v3/hooks/gestures/pinch/usePinchGesture.d.ts +1 -1
  283. package/lib/typescript/v3/hooks/gestures/pinch/usePinchGesture.d.ts.map +1 -1
  284. package/lib/typescript/v3/hooks/gestures/rotation/useRotationGesture.d.ts +1 -1
  285. package/lib/typescript/v3/hooks/gestures/rotation/useRotationGesture.d.ts.map +1 -1
  286. package/lib/typescript/v3/hooks/gestures/tap/useTapGesture.d.ts +1 -1
  287. package/lib/typescript/v3/hooks/gestures/tap/useTapGesture.d.ts.map +1 -1
  288. package/lib/typescript/v3/hooks/useGesture.d.ts.map +1 -1
  289. package/lib/typescript/v3/hooks/utils/configUtils.d.ts +2 -2
  290. package/lib/typescript/v3/hooks/utils/configUtils.d.ts.map +1 -1
  291. package/lib/typescript/v3/hooks/utils/eventHandlersUtils.d.ts.map +1 -1
  292. package/lib/typescript/v3/hooks/utils/index.d.ts +1 -1
  293. package/lib/typescript/v3/hooks/utils/index.d.ts.map +1 -1
  294. package/lib/typescript/v3/hooks/utils/propsWhiteList.d.ts +2 -2
  295. package/lib/typescript/v3/hooks/utils/propsWhiteList.d.ts.map +1 -1
  296. package/lib/typescript/v3/hooks/utils/reanimatedUtils.d.ts +1 -0
  297. package/lib/typescript/v3/hooks/utils/reanimatedUtils.d.ts.map +1 -1
  298. package/lib/typescript/v3/types/ConfigTypes.d.ts +1 -0
  299. package/lib/typescript/v3/types/ConfigTypes.d.ts.map +1 -1
  300. package/lib/typescript/web/constants.d.ts +1 -0
  301. package/lib/typescript/web/constants.d.ts.map +1 -1
  302. package/lib/typescript/web/detectors/RotationGestureDetector.d.ts.map +1 -1
  303. package/lib/typescript/web/detectors/ScaleGestureDetector.d.ts.map +1 -1
  304. package/lib/typescript/web/handlers/GestureHandler.d.ts +8 -2
  305. package/lib/typescript/web/handlers/GestureHandler.d.ts.map +1 -1
  306. package/lib/typescript/web/handlers/HoverGestureHandler.d.ts +1 -1
  307. package/lib/typescript/web/handlers/HoverGestureHandler.d.ts.map +1 -1
  308. package/lib/typescript/web/handlers/IGestureHandler.d.ts +2 -0
  309. package/lib/typescript/web/handlers/IGestureHandler.d.ts.map +1 -1
  310. package/lib/typescript/web/handlers/ManualGestureHandler.d.ts +1 -0
  311. package/lib/typescript/web/handlers/ManualGestureHandler.d.ts.map +1 -1
  312. package/lib/typescript/web/handlers/NativeViewGestureHandler.d.ts +13 -3
  313. package/lib/typescript/web/handlers/NativeViewGestureHandler.d.ts.map +1 -1
  314. package/lib/typescript/web/handlers/PanGestureHandler.d.ts +1 -0
  315. package/lib/typescript/web/handlers/PanGestureHandler.d.ts.map +1 -1
  316. package/lib/typescript/web/handlers/PinchGestureHandler.d.ts +1 -0
  317. package/lib/typescript/web/handlers/PinchGestureHandler.d.ts.map +1 -1
  318. package/lib/typescript/web/handlers/RotationGestureHandler.d.ts +1 -0
  319. package/lib/typescript/web/handlers/RotationGestureHandler.d.ts.map +1 -1
  320. package/lib/typescript/web/interfaces.d.ts +6 -0
  321. package/lib/typescript/web/interfaces.d.ts.map +1 -1
  322. package/lib/typescript/web/tools/GestureHandlerOrchestrator.d.ts +1 -0
  323. package/lib/typescript/web/tools/GestureHandlerOrchestrator.d.ts.map +1 -1
  324. package/lib/typescript/web/tools/GestureLifecycleEvents.d.ts +7 -0
  325. package/lib/typescript/web/tools/GestureLifecycleEvents.d.ts.map +1 -0
  326. package/lib/typescript/web/tools/NodeManager.d.ts +7 -0
  327. package/lib/typescript/web/tools/NodeManager.d.ts.map +1 -1
  328. package/lib/typescript/web/tools/PointerEventManager.d.ts.map +1 -1
  329. package/package.json +3 -3
  330. package/src/RNGestureHandlerModule.web.ts +5 -1
  331. package/src/components/GestureButtons.tsx +33 -16
  332. package/src/components/GestureHandlerButton.tsx +70 -8
  333. package/src/components/GestureHandlerButton.web.tsx +184 -48
  334. package/src/components/Pressable/Pressable.tsx +3 -1
  335. package/src/components/Pressable/PressableProps.tsx +2 -1
  336. package/src/components/Pressable/stateDefinitions.ts +3 -0
  337. package/src/components/ReanimatedDrawerLayout.tsx +27 -23
  338. package/src/components/ReanimatedSwipeable/ReanimatedSwipeable.tsx +51 -5
  339. package/src/components/ReanimatedSwipeable/ReanimatedSwipeableProps.ts +31 -39
  340. package/src/components/touchables/GenericTouchable.tsx +2 -5
  341. package/src/handlers/gestures/GestureDetector/useDetectorUpdater.ts +1 -2
  342. package/src/handlers/gestures/GestureDetector/utils.ts +11 -53
  343. package/src/handlers/gestures/flingGesture.ts +6 -0
  344. package/src/handlers/gestures/forceTouchGesture.ts +3 -3
  345. package/src/handlers/gestures/gesture.ts +6 -0
  346. package/src/handlers/gestures/gestureComposition.ts +21 -0
  347. package/src/handlers/gestures/gestureObjects.ts +27 -1
  348. package/src/handlers/gestures/gestureStateManager.ts +6 -0
  349. package/src/handlers/gestures/hoverGesture.ts +6 -0
  350. package/src/handlers/gestures/longPressGesture.ts +6 -0
  351. package/src/handlers/gestures/manualGesture.ts +6 -0
  352. package/src/handlers/gestures/nativeGesture.ts +6 -0
  353. package/src/handlers/gestures/panGesture.ts +9 -0
  354. package/src/handlers/gestures/pinchGesture.ts +9 -0
  355. package/src/handlers/gestures/reanimatedWrapper.ts +20 -2
  356. package/src/handlers/gestures/rotationGesture.ts +6 -0
  357. package/src/handlers/gestures/tapGesture.ts +6 -0
  358. package/src/mocks/module.tsx +4 -2
  359. package/src/specs/NativeRNGestureHandlerModule.ts +2 -4
  360. package/src/specs/RNGestureHandlerButtonNativeComponent.ts +28 -13
  361. package/src/v3/NativeProxy.ts +9 -7
  362. package/src/v3/NativeProxy.web.ts +2 -2
  363. package/src/v3/components/GestureButtons.tsx +18 -10
  364. package/src/v3/components/GestureButtonsProps.ts +1 -0
  365. package/src/v3/components/Pressable.tsx +2 -1
  366. package/src/v3/components/Touchable/Touchable.tsx +144 -50
  367. package/src/v3/components/Touchable/TouchableProps.ts +64 -2
  368. package/src/v3/detectors/HostGestureDetector.web.tsx +268 -108
  369. package/src/v3/detectors/NativeDetector.tsx +3 -2
  370. package/src/v3/detectors/VirtualDetector/InterceptingGestureDetector.tsx +3 -4
  371. package/src/v3/detectors/VirtualDetector/VirtualDetector.tsx +5 -2
  372. package/src/v3/detectors/useGestureRelationsUpdater.ts +30 -0
  373. package/src/v3/detectors/useNativeGestureRole.ts +8 -0
  374. package/src/v3/detectors/useNativeGestureRole.web.ts +42 -0
  375. package/src/v3/detectors/utils.ts +28 -12
  376. package/src/v3/hooks/callbacks/useReanimatedEventHandler.ts +23 -7
  377. package/src/v3/hooks/gestures/fling/useFlingGesture.ts +5 -1
  378. package/src/v3/hooks/gestures/hover/useHoverGesture.ts +5 -1
  379. package/src/v3/hooks/gestures/longPress/useLongPressGesture.ts +3 -1
  380. package/src/v3/hooks/gestures/manual/useManualGesture.ts +5 -1
  381. package/src/v3/hooks/gestures/native/NativeTypes.ts +13 -1
  382. package/src/v3/hooks/gestures/native/useNativeGesture.ts +5 -1
  383. package/src/v3/hooks/gestures/pan/usePanGesture.ts +5 -1
  384. package/src/v3/hooks/gestures/pinch/usePinchGesture.ts +5 -1
  385. package/src/v3/hooks/gestures/rotation/useRotationGesture.ts +3 -1
  386. package/src/v3/hooks/gestures/tap/useTapGesture.ts +5 -1
  387. package/src/v3/hooks/useGesture.ts +4 -18
  388. package/src/v3/hooks/utils/configUtils.ts +18 -8
  389. package/src/v3/hooks/utils/eventHandlersUtils.ts +43 -32
  390. package/src/v3/hooks/utils/index.ts +0 -1
  391. package/src/v3/hooks/utils/propsWhiteList.ts +1 -0
  392. package/src/v3/hooks/utils/reanimatedUtils.ts +10 -10
  393. package/src/v3/types/ConfigTypes.ts +1 -0
  394. package/src/web/constants.ts +1 -0
  395. package/src/web/detectors/RotationGestureDetector.ts +19 -5
  396. package/src/web/detectors/ScaleGestureDetector.ts +9 -3
  397. package/src/web/handlers/GestureHandler.ts +36 -6
  398. package/src/web/handlers/HoverGestureHandler.ts +2 -5
  399. package/src/web/handlers/IGestureHandler.ts +2 -0
  400. package/src/web/handlers/ManualGestureHandler.ts +2 -0
  401. package/src/web/handlers/NativeViewGestureHandler.ts +122 -19
  402. package/src/web/handlers/PanGestureHandler.ts +2 -0
  403. package/src/web/handlers/PinchGestureHandler.ts +5 -7
  404. package/src/web/handlers/RotationGestureHandler.ts +5 -5
  405. package/src/web/interfaces.ts +7 -0
  406. package/src/web/tools/GestureHandlerOrchestrator.ts +11 -3
  407. package/src/web/tools/GestureLifecycleEvents.ts +14 -0
  408. package/src/web/tools/NodeManager.ts +57 -0
  409. package/src/web/tools/PointerEventManager.ts +12 -0
  410. package/lib/module/RNRenderer.js +0 -6
  411. package/lib/module/RNRenderer.js.map +0 -1
  412. package/lib/module/RNRenderer.web.js +0 -6
  413. package/lib/module/RNRenderer.web.js.map +0 -1
  414. package/lib/typescript/RNRenderer.d.ts +0 -2
  415. package/lib/typescript/RNRenderer.d.ts.map +0 -1
  416. package/lib/typescript/RNRenderer.web.d.ts +0 -4
  417. package/lib/typescript/RNRenderer.web.d.ts.map +0 -1
  418. package/src/RNRenderer.ts +0 -3
  419. package/src/RNRenderer.web.ts +0 -3
@@ -41,6 +41,7 @@
41
41
  */
42
42
  @implementation RNGestureHandlerButton {
43
43
  BOOL _isTouchInsideBounds;
44
+ BOOL _suppressSuperControlActionDispatch;
44
45
  CALayer *_underlayLayer;
45
46
  CGFloat _underlayCornerRadii[8]; // [tlH, tlV, trH, trV, blH, blV, brH, brV] outer radii in points
46
47
  UIEdgeInsets _underlayBorderInsets; // border widths for padding-box inset
@@ -48,7 +49,7 @@
48
49
  dispatch_block_t _pendingPressOutBlock;
49
50
  }
50
51
 
51
- @synthesize pressAndHoldAnimationDuration = _pressAndHoldAnimationDuration;
52
+ @synthesize longPressAnimationOutDuration = _longPressAnimationOutDuration;
52
53
 
53
54
  - (void)commonInit
54
55
  {
@@ -56,8 +57,10 @@
56
57
  _hitTestEdgeInsets = UIEdgeInsetsZero;
57
58
  _userEnabled = YES;
58
59
  _pointerEvents = RNGestureHandlerPointerEventsAuto;
59
- _pressAndHoldAnimationDuration = -1;
60
- _tapAnimationDuration = 100;
60
+ _tapAnimationInDuration = 50;
61
+ _tapAnimationOutDuration = 100;
62
+ _longPressDuration = -1;
63
+ _longPressAnimationOutDuration = -1;
61
64
  _activeOpacity = 1.0;
62
65
  _defaultOpacity = 1.0;
63
66
  _activeScale = 1.0;
@@ -79,7 +82,9 @@
79
82
 
80
83
  #if !TARGET_OS_TV && !TARGET_OS_OSX
81
84
  [self setExclusiveTouch:YES];
82
- [self addTarget:self action:@selector(handleAnimatePressIn) forControlEvents:UIControlEventTouchDown];
85
+ [self addTarget:self
86
+ action:@selector(handleAnimatePressIn)
87
+ forControlEvents:UIControlEventTouchDown | UIControlEventTouchDragEnter];
83
88
  [self addTarget:self
84
89
  action:@selector(handleAnimatePressOut)
85
90
  forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside | UIControlEventTouchDragExit |
@@ -114,12 +119,38 @@
114
119
  [_underlayLayer removeAllAnimations];
115
120
  }
116
121
 
122
+ - (void)prepareForRecycle
123
+ {
124
+ // Fabric reuses the same wrapper + button instance across mounts. Without
125
+ // this reset, residual press-in transform/alpha/underlay-opacity from a
126
+ // prior use leaks into the recycled view, and `updateProps:` won't undo it
127
+ // when defaults are unchanged between mounts.
128
+ [self cancelPendingPressOutAnimation];
129
+
130
+ RNGHUIView *target = self.animationTarget ?: self;
131
+ target.layer.transform = CATransform3DIdentity;
132
+ #if !TARGET_OS_OSX
133
+ target.alpha = 1.0;
134
+ #else
135
+ target.alphaValue = 1.0;
136
+ #endif
137
+ _underlayLayer.opacity = 0;
138
+
139
+ _isTouchInsideBounds = NO;
140
+ _suppressSuperControlActionDispatch = NO;
141
+ _pressInTimestamp = 0;
142
+ }
143
+
117
144
  #if TARGET_OS_OSX
118
145
  - (void)viewWillMoveToWindow:(RNGHWindow *)newWindow
119
146
  {
120
147
  [super viewWillMoveToWindow:newWindow];
121
148
  if (newWindow == nil) {
122
149
  [self cancelPendingPressOutAnimation];
150
+ [self applyStartAnimationState];
151
+ _isTouchInsideBounds = NO;
152
+ _suppressSuperControlActionDispatch = NO;
153
+ _pressInTimestamp = 0;
123
154
  }
124
155
  }
125
156
  #else
@@ -128,13 +159,17 @@
128
159
  [super willMoveToWindow:newWindow];
129
160
  if (newWindow == nil) {
130
161
  [self cancelPendingPressOutAnimation];
162
+ [self applyStartAnimationState];
163
+ _isTouchInsideBounds = NO;
164
+ _suppressSuperControlActionDispatch = NO;
165
+ _pressInTimestamp = 0;
131
166
  }
132
167
  }
133
168
  #endif
134
169
 
135
- - (NSInteger)pressAndHoldAnimationDuration
170
+ - (NSInteger)longPressAnimationOutDuration
136
171
  {
137
- return _pressAndHoldAnimationDuration < 0 ? _tapAnimationDuration : _pressAndHoldAnimationDuration;
172
+ return _longPressAnimationOutDuration < 0 ? _tapAnimationOutDuration : _longPressAnimationOutDuration;
138
173
  }
139
174
 
140
175
  - (void)setUnderlayColor:(RNGHColor *)underlayColor
@@ -168,10 +203,26 @@
168
203
 
169
204
  - (void)animateUnderlayToOpacity:(float)toOpacity duration:(NSTimeInterval)durationMs
170
205
  {
171
- _underlayLayer.opacity =
172
- _underlayLayer.presentationLayer ? [_underlayLayer.presentationLayer opacity] : _underlayLayer.opacity;
206
+ // Only sync the model from the presentation layer when an animation is actually
207
+ // in flight.
208
+ CALayer *presentation = _underlayLayer.presentationLayer;
209
+ BOOL hasInFlightAnimation = presentation != nil && _underlayLayer.animationKeys.count > 0;
210
+ if (hasInFlightAnimation) {
211
+ _underlayLayer.opacity = presentation.opacity;
212
+ }
173
213
  [_underlayLayer removeAllAnimations];
174
214
 
215
+ // CABasicAnimation with duration 0 resolves to the current CATransaction's
216
+ // default duration (0.25s), not "no animation". Snap the value directly
217
+ // with implicit actions disabled to get a true instant update.
218
+ if (durationMs <= 0) {
219
+ [CATransaction begin];
220
+ [CATransaction setDisableActions:YES];
221
+ _underlayLayer.opacity = toOpacity;
222
+ [CATransaction commit];
223
+ return;
224
+ }
225
+
175
226
  CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"opacity"];
176
227
  anim.fromValue = @(_underlayLayer.opacity);
177
228
  anim.toValue = @(toOpacity);
@@ -220,19 +271,60 @@ static CATransform3D RNGHCenterScaleTransform(NSRect bounds, CGFloat scale)
220
271
  #endif
221
272
  }
222
273
 
274
+ // Duration of a single frame at the current screen's max refresh rate, in ms.
275
+ - (NSTimeInterval)minFrameDurationMs
276
+ {
277
+ #if !TARGET_OS_OSX
278
+ UIScreen *screen = self.window.screen ?: UIScreen.mainScreen;
279
+ NSInteger maxFps = screen.maximumFramesPerSecond;
280
+ #else
281
+ NSScreen *screen = self.window.screen ?: NSScreen.mainScreen;
282
+ NSInteger maxFps = 60;
283
+ if (@available(macOS 12.0, *)) {
284
+ maxFps = screen.maximumFramesPerSecond;
285
+ }
286
+ #endif
287
+ return maxFps > 0 ? 1000.0 / (NSTimeInterval)maxFps : 1000.0 / 60.0;
288
+ }
289
+
223
290
  - (void)animateTarget:(RNGHUIView *)target
224
291
  toOpacity:(CGFloat)opacity
225
292
  scale:(CGFloat)scale
226
293
  duration:(NSTimeInterval)durationMs
227
294
  {
228
- target.layer.transform =
229
- target.layer.presentationLayer ? target.layer.presentationLayer.transform : target.layer.transform;
230
- NSTimeInterval duration = durationMs / 1000.0;
295
+ CALayer *layer = target.layer;
296
+ CALayer *presentation = layer.presentationLayer;
297
+ NSTimeInterval snapThresholdMs = [self minFrameDurationMs];
298
+
299
+ // Only snap to the presentation layer when an animation is in flight,
300
+ // that's the only case where it tells us something the model layer doesn't.
301
+ BOOL hasInFlightAnimation = presentation != nil && layer.animationKeys.count > 0;
302
+ if (hasInFlightAnimation) {
303
+ layer.transform = presentation.transform;
304
+ }
231
305
 
232
306
  #if !TARGET_OS_OSX
233
- target.alpha = target.layer.presentationLayer ? target.layer.presentationLayer.opacity : target.alpha;
234
- [target.layer removeAllAnimations];
307
+ if (hasInFlightAnimation) {
308
+ target.alpha = presentation.opacity;
309
+ }
310
+ [layer removeAllAnimations];
311
+
312
+ // Sub-frame durations: snap with implicit actions disabled instead of
313
+ // routing through UIView.animate. Same rationale as animateUnderlayToOpacity.
314
+ if (durationMs < snapThresholdMs) {
315
+ [CATransaction begin];
316
+ [CATransaction setDisableActions:YES];
317
+ if (_activeOpacity != 1.0 || _defaultOpacity != 1.0) {
318
+ target.alpha = opacity;
319
+ }
320
+ if (_activeScale != 1.0 || _defaultScale != 1.0) {
321
+ layer.transform = CATransform3DMakeScale(scale, scale, 1.0);
322
+ }
323
+ [CATransaction commit];
324
+ return;
325
+ }
235
326
 
327
+ NSTimeInterval duration = durationMs / 1000.0;
236
328
  [UIView animateWithDuration:duration
237
329
  delay:0
238
330
  options:UIViewAnimationOptionCurveEaseInOut
@@ -247,9 +339,25 @@ static CATransform3D RNGHCenterScaleTransform(NSRect bounds, CGFloat scale)
247
339
  completion:nil];
248
340
  #else
249
341
  target.wantsLayer = YES;
250
- target.alphaValue = target.layer.presentationLayer ? target.layer.presentationLayer.opacity : target.alphaValue;
251
- [target.layer removeAllAnimations];
342
+ if (hasInFlightAnimation) {
343
+ target.alphaValue = presentation.opacity;
344
+ }
345
+ [layer removeAllAnimations];
346
+
347
+ if (durationMs < snapThresholdMs) {
348
+ [CATransaction begin];
349
+ [CATransaction setDisableActions:YES];
350
+ if (_activeOpacity != 1.0 || _defaultOpacity != 1.0) {
351
+ target.alphaValue = opacity;
352
+ }
353
+ if (_activeScale != 1.0 || _defaultScale != 1.0) {
354
+ layer.transform = RNGHCenterScaleTransform(target.bounds, scale);
355
+ }
356
+ [CATransaction commit];
357
+ return;
358
+ }
252
359
 
360
+ NSTimeInterval duration = durationMs / 1000.0;
253
361
  [NSAnimationContext
254
362
  runAnimationGroup:^(NSAnimationContext *context) {
255
363
  context.allowsImplicitAnimation = YES;
@@ -274,9 +382,9 @@ static CATransform3D RNGHCenterScaleTransform(NSRect bounds, CGFloat scale)
274
382
  }
275
383
  _pressInTimestamp = CACurrentMediaTime();
276
384
  RNGHUIView *target = self.animationTarget ?: self;
277
- [self animateTarget:target toOpacity:_activeOpacity scale:_activeScale duration:self.pressAndHoldAnimationDuration];
385
+ [self animateTarget:target toOpacity:_activeOpacity scale:_activeScale duration:_tapAnimationInDuration];
278
386
  if (_activeUnderlayOpacity != _defaultUnderlayOpacity) {
279
- [self animateUnderlayToOpacity:_activeUnderlayOpacity duration:self.pressAndHoldAnimationDuration];
387
+ [self animateUnderlayToOpacity:_activeUnderlayOpacity duration:_tapAnimationInDuration];
280
388
  }
281
389
  }
282
390
 
@@ -287,17 +395,24 @@ static CATransform3D RNGHCenterScaleTransform(NSRect bounds, CGFloat scale)
287
395
  }
288
396
 
289
397
  NSTimeInterval elapsed = (CACurrentMediaTime() - _pressInTimestamp) * 1000.0;
290
- NSInteger pressAndHoldAnimationDuration = self.pressAndHoldAnimationDuration;
291
398
 
292
- if (elapsed >= pressAndHoldAnimationDuration) {
293
- // Press-in animation fully finished, animate out in pressAndHoldAnimationDuration
399
+ if (_longPressDuration >= 0 && elapsed >= _longPressDuration) {
400
+ // Long-press release - use the configured long-press out duration.
401
+ NSInteger longPressOut = self.longPressAnimationOutDuration;
402
+ RNGHUIView *target = self.animationTarget ?: self;
403
+ [self animateTarget:target toOpacity:_defaultOpacity scale:_defaultScale duration:longPressOut];
404
+ if (_activeUnderlayOpacity != _defaultUnderlayOpacity) {
405
+ [self animateUnderlayToOpacity:_defaultUnderlayOpacity duration:longPressOut];
406
+ }
407
+ } else if (elapsed >= _tapAnimationInDuration) {
408
+ // Press-in animation fully finished - release with the configured out duration.
294
409
  RNGHUIView *target = self.animationTarget ?: self;
295
- [self animateTarget:target toOpacity:_defaultOpacity scale:_defaultScale duration:pressAndHoldAnimationDuration];
410
+ [self animateTarget:target toOpacity:_defaultOpacity scale:_defaultScale duration:_tapAnimationOutDuration];
296
411
  if (_activeUnderlayOpacity != _defaultUnderlayOpacity) {
297
- [self animateUnderlayToOpacity:_defaultUnderlayOpacity duration:pressAndHoldAnimationDuration];
412
+ [self animateUnderlayToOpacity:_defaultUnderlayOpacity duration:_tapAnimationOutDuration];
298
413
  }
299
- // elapsed * 2 to ensure there is at least half of the minDuration left for the animation to play
300
- } else if (elapsed * 2 >= _tapAnimationDuration) {
414
+ // elapsed * 2 to ensure there is at least half of the tapAnimationOutDuration left for the animation to play
415
+ } else if (elapsed * 2 >= _tapAnimationOutDuration) {
301
416
  // Past minimum but press-in animation still playing, animate out in elapsed time
302
417
  RNGHUIView *target = self.animationTarget ?: self;
303
418
  [self animateTarget:target toOpacity:_defaultOpacity scale:_defaultScale duration:elapsed];
@@ -305,8 +420,8 @@ static CATransform3D RNGHCenterScaleTransform(NSRect bounds, CGFloat scale)
305
420
  [self animateUnderlayToOpacity:_defaultUnderlayOpacity duration:elapsed];
306
421
  }
307
422
  } else {
308
- // Before minimum duration, finish press-in in remaining time then animate out in minDuration
309
- NSTimeInterval remaining = _tapAnimationDuration - elapsed;
423
+ // Before minimum duration, finish press-in in remaining time then animate out in tapAnimationOutDuration.
424
+ NSTimeInterval remaining = _tapAnimationInDuration - elapsed;
310
425
 
311
426
  RNGHUIView *target = self.animationTarget ?: self;
312
427
  [self animateTarget:target toOpacity:_activeOpacity scale:_activeScale duration:remaining];
@@ -323,10 +438,10 @@ static CATransform3D RNGHCenterScaleTransform(NSRect bounds, CGFloat scale)
323
438
  [strongSelf animateTarget:target
324
439
  toOpacity:strongSelf->_defaultOpacity
325
440
  scale:strongSelf->_defaultScale
326
- duration:strongSelf->_tapAnimationDuration];
441
+ duration:strongSelf->_tapAnimationOutDuration];
327
442
  if (strongSelf->_activeUnderlayOpacity != strongSelf->_defaultUnderlayOpacity) {
328
443
  [strongSelf animateUnderlayToOpacity:strongSelf->_defaultUnderlayOpacity
329
- duration:strongSelf->_tapAnimationDuration];
444
+ duration:strongSelf->_tapAnimationOutDuration];
330
445
  }
331
446
  }
332
447
  });
@@ -554,6 +669,7 @@ static CATransform3D RNGHCenterScaleTransform(NSRect bounds, CGFloat scale)
554
669
  #if TARGET_OS_OSX
555
670
  - (void)mouseDown:(NSEvent *)event
556
671
  {
672
+ _isTouchInsideBounds = YES;
557
673
  [self handleAnimatePressIn];
558
674
  [super mouseDown:event];
559
675
  }
@@ -561,6 +677,7 @@ static CATransform3D RNGHCenterScaleTransform(NSRect bounds, CGFloat scale)
561
677
  - (void)mouseUp:(NSEvent *)event
562
678
  {
563
679
  [self handleAnimatePressOut];
680
+ _isTouchInsideBounds = NO;
564
681
  [super mouseUp:event];
565
682
  }
566
683
 
@@ -568,8 +685,13 @@ static CATransform3D RNGHCenterScaleTransform(NSRect bounds, CGFloat scale)
568
685
  {
569
686
  NSPoint locationInWindow = [event locationInWindow];
570
687
  NSPoint locationInView = [self convertPoint:locationInWindow fromView:nil];
688
+ BOOL currentlyInside = NSPointInRect(locationInView, self.bounds);
571
689
 
572
- if (!NSPointInRect(locationInView, self.bounds)) {
690
+ if (currentlyInside && !_isTouchInsideBounds) {
691
+ _isTouchInsideBounds = YES;
692
+ [self handleAnimatePressIn];
693
+ } else if (!currentlyInside && _isTouchInsideBounds) {
694
+ _isTouchInsideBounds = NO;
573
695
  [self handleAnimatePressOut];
574
696
  }
575
697
  }
@@ -591,9 +713,52 @@ static CATransform3D RNGHCenterScaleTransform(NSRect bounds, CGFloat scale)
591
713
  return [super beginTrackingWithTouch:touch withEvent:event];
592
714
  }
593
715
 
716
+ // Mirrors `sendActionsForControlEvents:` but preserves the real `UIEvent`
717
+ // so target-actions with a `forEvent:` parameter receive the touches.
718
+ // The public `sendActionsForControlEvents:` passes a nil event, which would
719
+ // make handlers reading `event.allTouches.count` observe 0 pointers.
720
+ - (void)rngh_sendActionsForControlEvents:(UIControlEvents)controlEvents withEvent:(UIEvent *)event
721
+ {
722
+ for (id target in [self allTargets]) {
723
+ for (NSString *actionName in [self actionsForTarget:target forControlEvent:controlEvents]) {
724
+ [self sendAction:NSSelectorFromString(actionName) to:target forEvent:event];
725
+ }
726
+ }
727
+ }
728
+
729
+ // UIControl's default `touchesMoved:` / `touchesEnded:` invoke
730
+ // `{continue|end}TrackingWithTouch:` and THEN dispatch their own Drag* / Up*
731
+ // actions via `sendAction:to:forEvent:` using Apple's 70-point retention-offset
732
+ // hit-test. That double-fires our handlers (once from our manual dispatch in
733
+ // the tracking hooks, once from UIControl's retention-offset path). We swallow
734
+ // UIControl's dispatch via this override; the flag is armed by our tracking
735
+ // hooks only after our own dispatch has already run.
736
+ - (void)sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event
737
+ {
738
+ if (_suppressSuperControlActionDispatch) {
739
+ return;
740
+ }
741
+ [super sendAction:action to:target forEvent:event];
742
+ }
743
+
744
+ - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
745
+ {
746
+ [super touchesMoved:touches withEvent:event];
747
+ _suppressSuperControlActionDispatch = NO;
748
+ }
749
+
750
+ - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
751
+ {
752
+ [super touchesEnded:touches withEvent:event];
753
+ _suppressSuperControlActionDispatch = NO;
754
+ }
755
+
594
756
  - (BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
595
757
  {
596
- // DO NOT call super. We are entirely taking over the drag event generation.
758
+ // We take over drag event generation to enforce strict hitslop bounds
759
+ // (bypassing Apple's retention offset). After our dispatch, set the
760
+ // suppress flag so UIControl's default post-tracking dispatch in
761
+ // `touchesMoved:` gets swallowed by our `sendAction:to:forEvent:` override.
597
762
 
598
763
  CGPoint location = [touch locationInView:self];
599
764
  CGRect hitFrame = UIEdgeInsetsInsetRect(self.bounds, self.hitTestEdgeInsets);
@@ -601,43 +766,48 @@ static CATransform3D RNGHCenterScaleTransform(NSRect bounds, CGFloat scale)
601
766
 
602
767
  if (currentlyInside) {
603
768
  if (!_isTouchInsideBounds) {
604
- [self sendActionsForControlEvents:UIControlEventTouchDragEnter];
769
+ [self rngh_sendActionsForControlEvents:UIControlEventTouchDragEnter withEvent:event];
605
770
  _isTouchInsideBounds = YES;
606
771
  }
607
772
 
608
773
  // Targets may call `cancelTrackingWithEvent:` in response to DragEnter.
609
774
  if (self.tracking) {
610
- [self sendActionsForControlEvents:UIControlEventTouchDragInside];
775
+ [self rngh_sendActionsForControlEvents:UIControlEventTouchDragInside withEvent:event];
611
776
  }
612
777
  } else {
613
778
  if (_isTouchInsideBounds) {
614
- [self sendActionsForControlEvents:UIControlEventTouchDragExit];
779
+ [self rngh_sendActionsForControlEvents:UIControlEventTouchDragExit withEvent:event];
615
780
  _isTouchInsideBounds = NO;
616
781
  }
617
782
 
618
783
  // Targets may call `cancelTrackingWithEvent:` in response to DragExit.
619
784
  if (self.tracking) {
620
- [self sendActionsForControlEvents:UIControlEventTouchDragOutside];
785
+ [self rngh_sendActionsForControlEvents:UIControlEventTouchDragOutside withEvent:event];
621
786
  }
622
787
  }
623
788
 
789
+ _suppressSuperControlActionDispatch = YES;
790
+
624
791
  // If `cancelTrackingWithEvent` was called, `self.tracking` will be NO.
625
792
  return self.tracking;
626
793
  }
627
794
 
628
795
  - (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
629
796
  {
630
- // Also bypass super here so that the final "up" event respects the
631
- // strict bounds, rather than Apple's 70-point.
797
+ // Same rationale as `continueTrackingWithTouch:` we dispatch the final
798
+ // Up* event ourselves using strict hitslop bounds, then set the suppress
799
+ // flag so UIControl's default dispatch in `touchesEnded:` gets swallowed.
632
800
 
633
801
  if (touch != nil) {
634
802
  CGPoint location = [touch locationInView:self];
635
803
  CGRect hitFrame = UIEdgeInsetsInsetRect(self.bounds, self.hitTestEdgeInsets);
636
804
  if (CGRectContainsPoint(hitFrame, location)) {
637
- [self sendActionsForControlEvents:UIControlEventTouchUpInside];
805
+ [self rngh_sendActionsForControlEvents:UIControlEventTouchUpInside withEvent:event];
638
806
  } else {
639
- [self sendActionsForControlEvents:UIControlEventTouchUpOutside];
807
+ [self rngh_sendActionsForControlEvents:UIControlEventTouchUpOutside withEvent:event];
640
808
  }
809
+
810
+ _suppressSuperControlActionDispatch = YES;
641
811
  }
642
812
 
643
813
  _isTouchInsideBounds = NO;
@@ -34,6 +34,7 @@ static RNGestureHandlerPointerEvents RCTPointerEventsToEnum(facebook::react::Poi
34
34
 
35
35
  @implementation RNGestureHandlerButtonComponentView {
36
36
  RNGestureHandlerButton *_buttonView;
37
+ BOOL _needsAnimationStateReset;
37
38
  }
38
39
 
39
40
  #if TARGET_OS_OSX
@@ -67,6 +68,20 @@ static RNGestureHandlerPointerEvents RCTPointerEventsToEnum(facebook::react::Poi
67
68
  return self;
68
69
  }
69
70
 
71
+ - (void)prepareForRecycle
72
+ {
73
+ [self.layer removeAnimationForKey:@"transform"];
74
+ self.layer.transform = CATransform3DIdentity;
75
+
76
+ [_buttonView prepareForRecycle];
77
+
78
+ // Force the next updateProps: to re-run applyStartAnimationState even if
79
+ // the new mount's defaults match the previous mount's.
80
+ _needsAnimationStateReset = YES;
81
+
82
+ [super prepareForRecycle];
83
+ }
84
+
70
85
  - (void)mountChildComponentView:(RNGHUIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
71
86
  {
72
87
  [_buttonView mountChildComponentView:childComponentView index:index];
@@ -111,14 +126,65 @@ static RNGestureHandlerPointerEvents RCTPointerEventsToEnum(facebook::react::Poi
111
126
  const LayoutMetrics buttonMetrics = [self buildButtonMetrics:layoutMetrics];
112
127
  const LayoutMetrics oldbuttonMetrics = [self buildButtonMetrics:oldLayoutMetrics];
113
128
 
129
+ // The press-in animation sets a scale transform on `self.layer` (animationTarget
130
+ // is this wrapper). RN's layout path sets `self.frame = frame`, which is undefined
131
+ // behavior when the layer's transform is non-identity, so mid-press child re-layouts
132
+ // get squished against the old bounds before snapping to the new ones. Neutralize
133
+ // the transform and any in-flight animation around super's frame update, then
134
+ // restore both atomically within the same transaction.
135
+ CATransform3D savedTransform = self.layer.transform;
136
+ CAAnimation *savedTransformAnimation = [[self.layer animationForKey:@"transform"] copy];
137
+ BOOL hasPendingTransform = !CATransform3DIsIdentity(savedTransform) || savedTransformAnimation != nil;
138
+
139
+ if (hasPendingTransform) {
140
+ [CATransaction begin];
141
+ [CATransaction setDisableActions:YES];
142
+ [self.layer removeAnimationForKey:@"transform"];
143
+ self.layer.transform = CATransform3DIdentity;
144
+ }
145
+
114
146
  [super updateLayoutMetrics:wrapperMetrics oldLayoutMetrics:oldWrapperMetrics];
147
+
148
+ if (hasPendingTransform) {
149
+ self.layer.transform = savedTransform;
150
+ if (savedTransformAnimation) {
151
+ [self.layer addAnimation:savedTransformAnimation forKey:@"transform"];
152
+ }
153
+ [CATransaction commit];
154
+ }
155
+
115
156
  [_buttonView updateLayoutMetrics:buttonMetrics oldLayoutMetrics:oldbuttonMetrics];
116
157
  }
117
158
 
118
159
  - (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask
119
160
  {
161
+ // super's invalidateLayer (called via finalizeUpdates) unconditionally sets
162
+ // self.layer.opacity to the React style.opacity, overwriting our
163
+ // applyStartAnimationState alpha and interrupting in-flight press
164
+ // animations. Save/restore around super, but only touch what super actually
165
+ // disturbed — re-adding an unchanged animation resets its progress.
166
+ float savedOpacity = self.layer.opacity;
167
+ CAAnimation *savedOpacityAnimation = [self.layer animationForKey:@"opacity"];
168
+
120
169
  [super finalizeUpdates:updateMask];
121
170
 
171
+ BOOL opacityChanged = savedOpacity != self.layer.opacity;
172
+ BOOL animationChanged = savedOpacityAnimation != [self.layer animationForKey:@"opacity"];
173
+ if (opacityChanged || animationChanged) {
174
+ [CATransaction begin];
175
+ [CATransaction setDisableActions:YES];
176
+ if (animationChanged) {
177
+ [self.layer removeAnimationForKey:@"opacity"];
178
+ if (savedOpacityAnimation) {
179
+ [self.layer addAnimation:savedOpacityAnimation forKey:@"opacity"];
180
+ }
181
+ }
182
+ if (opacityChanged) {
183
+ self.layer.opacity = savedOpacity;
184
+ }
185
+ [CATransaction commit];
186
+ }
187
+
122
188
  // Resolve per-corner border radii from props and forward to the button
123
189
  // so its underlay CALayer gets the matching shape.
124
190
  const auto borderMetrics = _props->resolveBorderMetrics(_layoutMetrics);
@@ -134,8 +200,6 @@ static RNGestureHandlerPointerEvents RCTPointerEventsToEnum(facebook::react::Poi
134
200
  right:borderMetrics.borderWidths.right
135
201
  bottom:borderMetrics.borderWidths.bottom
136
202
  left:borderMetrics.borderWidths.left];
137
-
138
- [_buttonView applyStartAnimationState];
139
203
  }
140
204
 
141
205
  #pragma mark - RCTComponentViewProtocol
@@ -243,9 +307,26 @@ static RNGestureHandlerPointerEvents RCTPointerEventsToEnum(facebook::react::Poi
243
307
  {
244
308
  const auto &newProps = *std::static_pointer_cast<const RNGestureHandlerButtonProps>(props);
245
309
 
310
+ // After recycling, treat diffing branches as a fresh mount so values that
311
+ // survived recycling on _buttonView (e.g. pointerEvents) get re-applied.
312
+ BOOL treatAsFirstMount = !oldProps || _needsAnimationStateReset;
313
+ _needsAnimationStateReset = NO;
314
+
315
+ // Avoid re-running applyStartAnimationState on every commit — it would
316
+ // interrupt in-flight press animations during mid-press re-renders.
317
+ BOOL shouldApplyStartAnimationState = treatAsFirstMount;
318
+ if (!treatAsFirstMount) {
319
+ const auto &oldButtonProps = *std::static_pointer_cast<const RNGestureHandlerButtonProps>(oldProps);
320
+ shouldApplyStartAnimationState = oldButtonProps.defaultOpacity != newProps.defaultOpacity ||
321
+ oldButtonProps.defaultScale != newProps.defaultScale ||
322
+ oldButtonProps.defaultUnderlayOpacity != newProps.defaultUnderlayOpacity;
323
+ }
324
+
246
325
  _buttonView.userEnabled = newProps.enabled;
247
- _buttonView.pressAndHoldAnimationDuration = newProps.pressAndHoldAnimationDuration;
248
- _buttonView.tapAnimationDuration = newProps.tapAnimationDuration > 0 ? newProps.tapAnimationDuration : 0;
326
+ _buttonView.tapAnimationInDuration = newProps.tapAnimationInDuration > 0 ? newProps.tapAnimationInDuration : 0;
327
+ _buttonView.tapAnimationOutDuration = newProps.tapAnimationOutDuration > 0 ? newProps.tapAnimationOutDuration : 0;
328
+ _buttonView.longPressDuration = newProps.longPressDuration;
329
+ _buttonView.longPressAnimationOutDuration = newProps.longPressAnimationOutDuration;
249
330
  _buttonView.activeOpacity = newProps.activeOpacity;
250
331
  _buttonView.defaultOpacity = newProps.defaultOpacity;
251
332
  _buttonView.activeScale = newProps.activeScale;
@@ -268,7 +349,7 @@ static RNGestureHandlerPointerEvents RCTPointerEventsToEnum(facebook::react::Poi
268
349
  // This is necessary because pointerEvents is redefined in the spec,
269
350
  // which shadows the base property with a different, incompatible type.
270
351
  const auto &newViewProps = static_cast<const ViewProps &>(newProps);
271
- if (!oldProps) {
352
+ if (treatAsFirstMount) {
272
353
  _buttonView.pointerEvents = RCTPointerEventsToEnum(newViewProps.pointerEvents);
273
354
  } else {
274
355
  const auto &oldButtonProps = *std::static_pointer_cast<const RNGestureHandlerButtonProps>(oldProps);
@@ -279,7 +360,22 @@ static RNGestureHandlerPointerEvents RCTPointerEventsToEnum(facebook::react::Poi
279
360
  }
280
361
 
281
362
  [super updateProps:props oldProps:oldProps];
282
- [_buttonView applyStartAnimationState];
363
+
364
+ #if !TARGET_OS_TV && !TARGET_OS_OSX
365
+ // super's updateProps sets self.accessibilityIdentifier from testID via the
366
+ // standard Fabric mechanism. However, setAccessibilityProps already forwards
367
+ // testID to _buttonView.accessibilityIdentifier (the actual button element).
368
+ // Having the identifier on both views causes testing frameworks (e.g. Detox)
369
+ // to report multiple matches for the same testID. Clear it from the wrapper so
370
+ // only _buttonView carries the identifier.
371
+ if (!newProps.testId.empty()) {
372
+ self.accessibilityIdentifier = nil;
373
+ }
374
+ #endif
375
+
376
+ if (shouldApplyStartAnimationState) {
377
+ [_buttonView applyStartAnimationState];
378
+ }
283
379
  }
284
380
 
285
381
  #if !TARGET_OS_OSX