react-native-screen-transitions 2.0.6 → 2.1.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 (297) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +100 -77
  3. package/lib/commonjs/components/{bounds-activator.js → bound-capture.js} +4 -4
  4. package/lib/commonjs/components/bound-capture.js.map +1 -0
  5. package/lib/commonjs/components/controllers/screen-lifecycle.js +18 -4
  6. package/lib/commonjs/components/controllers/screen-lifecycle.js.map +1 -1
  7. package/lib/commonjs/components/create-transition-aware-component.js +14 -12
  8. package/lib/commonjs/components/create-transition-aware-component.js.map +1 -1
  9. package/lib/commonjs/components/integrations/masked-view.js +52 -0
  10. package/lib/commonjs/components/integrations/masked-view.js.map +1 -0
  11. package/lib/commonjs/components/root-transition-aware.js +6 -15
  12. package/lib/commonjs/components/root-transition-aware.js.map +1 -1
  13. package/lib/commonjs/configs/index.js +4 -1
  14. package/lib/commonjs/configs/index.js.map +1 -1
  15. package/lib/commonjs/configs/presets.js +378 -7
  16. package/lib/commonjs/configs/presets.js.map +1 -1
  17. package/lib/commonjs/configs/specs.js +2 -1
  18. package/lib/commonjs/configs/specs.js.map +1 -1
  19. package/lib/commonjs/hooks/animation/use-associated-style.js +7 -10
  20. package/lib/commonjs/hooks/animation/use-associated-style.js.map +1 -1
  21. package/lib/commonjs/hooks/animation/use-screen-animation.js +37 -37
  22. package/lib/commonjs/hooks/animation/use-screen-animation.js.map +1 -1
  23. package/lib/commonjs/hooks/bounds/use-bound-registry.js +73 -0
  24. package/lib/commonjs/hooks/bounds/use-bound-registry.js.map +1 -0
  25. package/lib/commonjs/hooks/gestures/use-build-gestures.js +156 -152
  26. package/lib/commonjs/hooks/gestures/use-build-gestures.js.map +1 -1
  27. package/lib/commonjs/hooks/gestures/use-parent-gesture-registry.js +28 -0
  28. package/lib/commonjs/hooks/gestures/use-parent-gesture-registry.js.map +1 -0
  29. package/lib/commonjs/hooks/gestures/use-scroll-registry.js +146 -0
  30. package/lib/commonjs/hooks/gestures/use-scroll-registry.js.map +1 -0
  31. package/lib/commonjs/index.js +3 -0
  32. package/lib/commonjs/index.js.map +1 -1
  33. package/lib/commonjs/integrations/native-stack/views/NativeStackView.native.js +7 -4
  34. package/lib/commonjs/integrations/native-stack/views/NativeStackView.native.js.map +1 -1
  35. package/lib/commonjs/providers/gestures.js +16 -16
  36. package/lib/commonjs/providers/gestures.js.map +1 -1
  37. package/lib/commonjs/providers/transition-styles.js +44 -0
  38. package/lib/commonjs/providers/transition-styles.js.map +1 -0
  39. package/lib/commonjs/stores/bounds.js +142 -1
  40. package/lib/commonjs/stores/bounds.js.map +1 -1
  41. package/lib/commonjs/stores/utils/reset-stores-for-screen.js +4 -2
  42. package/lib/commonjs/stores/utils/reset-stores-for-screen.js.map +1 -1
  43. package/lib/commonjs/types/gesture.js +11 -0
  44. package/lib/commonjs/types/gesture.js.map +1 -1
  45. package/lib/commonjs/utils/animation/derivations.js +39 -0
  46. package/lib/commonjs/utils/animation/derivations.js.map +1 -0
  47. package/lib/commonjs/utils/animation/run-transition.js +6 -2
  48. package/lib/commonjs/utils/animation/run-transition.js.map +1 -1
  49. package/lib/commonjs/utils/bounds/_utils/flatten-styles.js.map +1 -0
  50. package/lib/commonjs/utils/bounds/_utils/geometry.js +179 -0
  51. package/lib/commonjs/utils/bounds/_utils/geometry.js.map +1 -0
  52. package/lib/commonjs/utils/bounds/{get-bounds.js → _utils/get-bounds.js} +7 -9
  53. package/lib/commonjs/utils/bounds/_utils/get-bounds.js.map +1 -0
  54. package/lib/commonjs/utils/bounds/_utils/is-bounds-equal.js +19 -0
  55. package/lib/commonjs/utils/bounds/_utils/is-bounds-equal.js.map +1 -0
  56. package/lib/commonjs/utils/bounds/_utils/style-composers.js +201 -0
  57. package/lib/commonjs/utils/bounds/_utils/style-composers.js.map +1 -0
  58. package/lib/commonjs/utils/bounds/constants.js +14 -3
  59. package/lib/commonjs/utils/bounds/constants.js.map +1 -1
  60. package/lib/commonjs/utils/bounds/index.js +210 -17
  61. package/lib/commonjs/utils/bounds/index.js.map +1 -1
  62. package/lib/commonjs/utils/gesture/apply-offset-rules.js +233 -0
  63. package/lib/commonjs/utils/gesture/apply-offset-rules.js.map +1 -0
  64. package/lib/commonjs/utils/gesture/check-gesture-activation.js +231 -0
  65. package/lib/commonjs/utils/gesture/check-gesture-activation.js.map +1 -0
  66. package/lib/commonjs/utils/gesture/determine-dismissal.js +98 -0
  67. package/lib/commonjs/utils/gesture/determine-dismissal.js.map +1 -0
  68. package/lib/module/components/{bounds-activator.js → bound-capture.js} +2 -2
  69. package/lib/module/components/bound-capture.js.map +1 -0
  70. package/lib/module/components/controllers/screen-lifecycle.js +18 -4
  71. package/lib/module/components/controllers/screen-lifecycle.js.map +1 -1
  72. package/lib/module/components/create-transition-aware-component.js +14 -12
  73. package/lib/module/components/create-transition-aware-component.js.map +1 -1
  74. package/lib/module/components/integrations/masked-view.js +48 -0
  75. package/lib/module/components/integrations/masked-view.js.map +1 -0
  76. package/lib/module/components/root-transition-aware.js +7 -16
  77. package/lib/module/components/root-transition-aware.js.map +1 -1
  78. package/lib/module/configs/index.js +6 -3
  79. package/lib/module/configs/index.js.map +1 -1
  80. package/lib/module/configs/presets.js +374 -6
  81. package/lib/module/configs/presets.js.map +1 -1
  82. package/lib/module/configs/specs.js +2 -1
  83. package/lib/module/configs/specs.js.map +1 -1
  84. package/lib/module/hooks/animation/use-associated-style.js +6 -10
  85. package/lib/module/hooks/animation/use-associated-style.js.map +1 -1
  86. package/lib/module/hooks/animation/use-screen-animation.js +37 -37
  87. package/lib/module/hooks/animation/use-screen-animation.js.map +1 -1
  88. package/lib/module/hooks/bounds/use-bound-registry.js +68 -0
  89. package/lib/module/hooks/bounds/use-bound-registry.js.map +1 -0
  90. package/lib/module/hooks/gestures/use-build-gestures.js +156 -153
  91. package/lib/module/hooks/gestures/use-build-gestures.js.map +1 -1
  92. package/lib/module/hooks/gestures/use-parent-gesture-registry.js +23 -0
  93. package/lib/module/hooks/gestures/use-parent-gesture-registry.js.map +1 -0
  94. package/lib/module/hooks/gestures/use-scroll-registry.js +140 -0
  95. package/lib/module/hooks/gestures/use-scroll-registry.js.map +1 -0
  96. package/lib/module/index.js +2 -0
  97. package/lib/module/index.js.map +1 -1
  98. package/lib/module/integrations/native-stack/views/NativeStackView.native.js +7 -4
  99. package/lib/module/integrations/native-stack/views/NativeStackView.native.js.map +1 -1
  100. package/lib/module/providers/gestures.js +16 -16
  101. package/lib/module/providers/gestures.js.map +1 -1
  102. package/lib/module/providers/transition-styles.js +39 -0
  103. package/lib/module/providers/transition-styles.js.map +1 -0
  104. package/lib/module/stores/bounds.js +142 -1
  105. package/lib/module/stores/bounds.js.map +1 -1
  106. package/lib/module/stores/utils/reset-stores-for-screen.js +4 -2
  107. package/lib/module/stores/utils/reset-stores-for-screen.js.map +1 -1
  108. package/lib/module/types/gesture.js +7 -0
  109. package/lib/module/types/gesture.js.map +1 -1
  110. package/lib/module/utils/animation/derivations.js +34 -0
  111. package/lib/module/utils/animation/derivations.js.map +1 -0
  112. package/lib/module/utils/animation/run-transition.js +6 -2
  113. package/lib/module/utils/animation/run-transition.js.map +1 -1
  114. package/lib/module/utils/bounds/_utils/flatten-styles.js.map +1 -0
  115. package/lib/module/utils/bounds/_utils/geometry.js +174 -0
  116. package/lib/module/utils/bounds/_utils/geometry.js.map +1 -0
  117. package/lib/module/utils/bounds/{get-bounds.js → _utils/get-bounds.js} +7 -9
  118. package/lib/module/utils/bounds/_utils/get-bounds.js.map +1 -0
  119. package/lib/module/utils/bounds/_utils/is-bounds-equal.js +14 -0
  120. package/lib/module/utils/bounds/_utils/is-bounds-equal.js.map +1 -0
  121. package/lib/module/utils/bounds/_utils/style-composers.js +194 -0
  122. package/lib/module/utils/bounds/_utils/style-composers.js.map +1 -0
  123. package/lib/module/utils/bounds/constants.js +14 -3
  124. package/lib/module/utils/bounds/constants.js.map +1 -1
  125. package/lib/module/utils/bounds/index.js +208 -15
  126. package/lib/module/utils/bounds/index.js.map +1 -1
  127. package/lib/module/utils/gesture/apply-offset-rules.js +228 -0
  128. package/lib/module/utils/gesture/apply-offset-rules.js.map +1 -0
  129. package/lib/module/utils/gesture/check-gesture-activation.js +226 -0
  130. package/lib/module/utils/gesture/check-gesture-activation.js.map +1 -0
  131. package/lib/module/utils/gesture/determine-dismissal.js +93 -0
  132. package/lib/module/utils/gesture/determine-dismissal.js.map +1 -0
  133. package/lib/typescript/components/bound-capture.d.ts +8 -0
  134. package/lib/typescript/components/bound-capture.d.ts.map +1 -0
  135. package/lib/typescript/components/controllers/screen-lifecycle.d.ts.map +1 -1
  136. package/lib/typescript/components/create-transition-aware-component.d.ts.map +1 -1
  137. package/lib/typescript/components/integrations/masked-view.d.ts +6 -0
  138. package/lib/typescript/components/integrations/masked-view.d.ts.map +1 -0
  139. package/lib/typescript/components/root-transition-aware.d.ts +3 -3
  140. package/lib/typescript/components/root-transition-aware.d.ts.map +1 -1
  141. package/lib/typescript/configs/index.d.ts +3 -0
  142. package/lib/typescript/configs/index.d.ts.map +1 -1
  143. package/lib/typescript/configs/presets.d.ts +3 -0
  144. package/lib/typescript/configs/presets.d.ts.map +1 -1
  145. package/lib/typescript/configs/specs.d.ts.map +1 -1
  146. package/lib/typescript/hooks/animation/use-associated-style.d.ts +6 -4
  147. package/lib/typescript/hooks/animation/use-associated-style.d.ts.map +1 -1
  148. package/lib/typescript/hooks/animation/use-screen-animation.d.ts.map +1 -1
  149. package/lib/typescript/hooks/bounds/{use-bound-measurer.d.ts → use-bound-registry.d.ts} +5 -4
  150. package/lib/typescript/hooks/bounds/{use-bound-measurer.d.ts.map → use-bound-registry.d.ts.map} +1 -1
  151. package/lib/typescript/hooks/gestures/use-build-gestures.d.ts +6 -5
  152. package/lib/typescript/hooks/gestures/use-build-gestures.d.ts.map +1 -1
  153. package/lib/typescript/hooks/gestures/use-parent-gesture-registry.d.ts +6 -0
  154. package/lib/typescript/hooks/gestures/use-parent-gesture-registry.d.ts.map +1 -0
  155. package/lib/typescript/hooks/gestures/{use-scroll-progress.d.ts → use-scroll-registry.d.ts} +2 -2
  156. package/lib/typescript/hooks/gestures/use-scroll-registry.d.ts.map +1 -0
  157. package/lib/typescript/index.d.ts +13 -8
  158. package/lib/typescript/index.d.ts.map +1 -1
  159. package/lib/typescript/integrations/native-stack/views/NativeStackView.native.d.ts.map +1 -1
  160. package/lib/typescript/providers/gestures.d.ts +4 -2
  161. package/lib/typescript/providers/gestures.d.ts.map +1 -1
  162. package/lib/typescript/providers/transition-styles.d.ts +8 -0
  163. package/lib/typescript/providers/transition-styles.d.ts.map +1 -0
  164. package/lib/typescript/stores/bounds.d.ts +11 -0
  165. package/lib/typescript/stores/bounds.d.ts.map +1 -1
  166. package/lib/typescript/stores/utils/reset-stores-for-screen.d.ts +3 -1
  167. package/lib/typescript/stores/utils/reset-stores-for-screen.d.ts.map +1 -1
  168. package/lib/typescript/types/bounds.d.ts +5 -1
  169. package/lib/typescript/types/bounds.d.ts.map +1 -1
  170. package/lib/typescript/types/gesture.d.ts +14 -0
  171. package/lib/typescript/types/gesture.d.ts.map +1 -1
  172. package/lib/typescript/types/navigator.d.ts +5 -1
  173. package/lib/typescript/types/navigator.d.ts.map +1 -1
  174. package/lib/typescript/utils/animation/derivations.d.ts +19 -0
  175. package/lib/typescript/utils/animation/derivations.d.ts.map +1 -0
  176. package/lib/typescript/utils/animation/run-transition.d.ts +2 -1
  177. package/lib/typescript/utils/animation/run-transition.d.ts.map +1 -1
  178. package/lib/typescript/utils/bounds/_types/builder.d.ts +96 -14
  179. package/lib/typescript/utils/bounds/_types/builder.d.ts.map +1 -1
  180. package/lib/typescript/utils/bounds/_types/geometry.d.ts +0 -1
  181. package/lib/typescript/utils/bounds/_types/geometry.d.ts.map +1 -1
  182. package/lib/typescript/utils/bounds/_utils/flatten-styles.d.ts.map +1 -0
  183. package/lib/typescript/utils/bounds/{geometry.d.ts → _utils/geometry.d.ts} +8 -5
  184. package/lib/typescript/utils/bounds/_utils/geometry.d.ts.map +1 -0
  185. package/lib/typescript/utils/bounds/_utils/get-bounds.d.ts +4 -0
  186. package/lib/typescript/utils/bounds/_utils/get-bounds.d.ts.map +1 -0
  187. package/lib/typescript/utils/bounds/_utils/is-bounds-equal.d.ts +7 -0
  188. package/lib/typescript/utils/bounds/_utils/is-bounds-equal.d.ts.map +1 -0
  189. package/lib/typescript/utils/bounds/{style-composers.d.ts → _utils/style-composers.d.ts} +7 -10
  190. package/lib/typescript/utils/bounds/_utils/style-composers.d.ts.map +1 -0
  191. package/lib/typescript/utils/bounds/constants.d.ts +5 -5
  192. package/lib/typescript/utils/bounds/constants.d.ts.map +1 -1
  193. package/lib/typescript/utils/bounds/index.d.ts +2 -4
  194. package/lib/typescript/utils/bounds/index.d.ts.map +1 -1
  195. package/lib/typescript/utils/gesture/apply-offset-rules.d.ts +38 -0
  196. package/lib/typescript/utils/gesture/apply-offset-rules.d.ts.map +1 -0
  197. package/lib/typescript/utils/gesture/check-gesture-activation.d.ts +38 -0
  198. package/lib/typescript/utils/gesture/check-gesture-activation.d.ts.map +1 -0
  199. package/lib/typescript/utils/gesture/determine-dismissal.d.ts +25 -0
  200. package/lib/typescript/utils/gesture/determine-dismissal.d.ts.map +1 -0
  201. package/package.json +2 -2
  202. package/src/__tests__/geometry.test.ts +15 -12
  203. package/src/components/{bounds-activator.tsx → bound-capture.tsx} +1 -1
  204. package/src/components/controllers/screen-lifecycle.tsx +13 -5
  205. package/src/components/create-transition-aware-component.tsx +17 -11
  206. package/src/components/integrations/masked-view.tsx +56 -0
  207. package/src/components/root-transition-aware.tsx +31 -39
  208. package/src/configs/index.ts +20 -8
  209. package/src/configs/presets.ts +401 -6
  210. package/src/configs/specs.ts +1 -0
  211. package/src/hooks/animation/use-associated-style.tsx +12 -11
  212. package/src/hooks/animation/use-screen-animation.tsx +48 -49
  213. package/src/hooks/bounds/{use-bound-measurer.tsx → use-bound-registry.tsx} +32 -20
  214. package/src/hooks/gestures/use-build-gestures.tsx +193 -228
  215. package/src/hooks/gestures/use-parent-gesture-registry.tsx +18 -0
  216. package/src/hooks/gestures/use-scroll-registry.tsx +145 -0
  217. package/src/index.ts +2 -0
  218. package/src/integrations/native-stack/views/NativeStackView.native.tsx +8 -5
  219. package/src/providers/gestures.tsx +19 -22
  220. package/src/providers/transition-styles.tsx +52 -0
  221. package/src/stores/bounds.ts +156 -0
  222. package/src/stores/utils/reset-stores-for-screen.ts +7 -2
  223. package/src/types/bounds.ts +8 -1
  224. package/src/types/gesture.ts +19 -0
  225. package/src/types/navigator.ts +5 -1
  226. package/src/utils/animation/derivations.ts +38 -0
  227. package/src/utils/animation/run-transition.ts +4 -1
  228. package/src/utils/bounds/_types/builder.ts +127 -11
  229. package/src/utils/bounds/_types/geometry.ts +0 -1
  230. package/src/utils/bounds/_utils/geometry.ts +166 -0
  231. package/src/utils/bounds/_utils/get-bounds.ts +54 -0
  232. package/src/utils/bounds/_utils/is-bounds-equal.ts +24 -0
  233. package/src/utils/bounds/_utils/style-composers.ts +216 -0
  234. package/src/utils/bounds/constants.ts +37 -22
  235. package/src/utils/bounds/index.ts +269 -19
  236. package/src/utils/gesture/apply-offset-rules.ts +314 -0
  237. package/src/utils/gesture/check-gesture-activation.ts +310 -0
  238. package/src/utils/gesture/determine-dismissal.ts +131 -0
  239. package/lib/commonjs/components/bounds-activator.js.map +0 -1
  240. package/lib/commonjs/hooks/bounds/use-bound-measurer.js +0 -52
  241. package/lib/commonjs/hooks/bounds/use-bound-measurer.js.map +0 -1
  242. package/lib/commonjs/hooks/gestures/use-scroll-progress.js +0 -57
  243. package/lib/commonjs/hooks/gestures/use-scroll-progress.js.map +0 -1
  244. package/lib/commonjs/utils/bounds/build-bound-styles.js +0 -145
  245. package/lib/commonjs/utils/bounds/build-bound-styles.js.map +0 -1
  246. package/lib/commonjs/utils/bounds/flatten-styles.js.map +0 -1
  247. package/lib/commonjs/utils/bounds/geometry.js +0 -94
  248. package/lib/commonjs/utils/bounds/geometry.js.map +0 -1
  249. package/lib/commonjs/utils/bounds/get-bounds.js.map +0 -1
  250. package/lib/commonjs/utils/bounds/style-composers.js +0 -199
  251. package/lib/commonjs/utils/bounds/style-composers.js.map +0 -1
  252. package/lib/commonjs/utils/gesture/apply-gesture-activation-criteria.js +0 -81
  253. package/lib/commonjs/utils/gesture/apply-gesture-activation-criteria.js.map +0 -1
  254. package/lib/commonjs/utils/gesture/normalize-gesture-translation.js +0 -21
  255. package/lib/commonjs/utils/gesture/normalize-gesture-translation.js.map +0 -1
  256. package/lib/module/components/bounds-activator.js.map +0 -1
  257. package/lib/module/hooks/bounds/use-bound-measurer.js +0 -47
  258. package/lib/module/hooks/bounds/use-bound-measurer.js.map +0 -1
  259. package/lib/module/hooks/gestures/use-scroll-progress.js +0 -52
  260. package/lib/module/hooks/gestures/use-scroll-progress.js.map +0 -1
  261. package/lib/module/utils/bounds/build-bound-styles.js +0 -141
  262. package/lib/module/utils/bounds/build-bound-styles.js.map +0 -1
  263. package/lib/module/utils/bounds/flatten-styles.js.map +0 -1
  264. package/lib/module/utils/bounds/geometry.js +0 -89
  265. package/lib/module/utils/bounds/geometry.js.map +0 -1
  266. package/lib/module/utils/bounds/get-bounds.js.map +0 -1
  267. package/lib/module/utils/bounds/style-composers.js +0 -191
  268. package/lib/module/utils/bounds/style-composers.js.map +0 -1
  269. package/lib/module/utils/gesture/apply-gesture-activation-criteria.js +0 -76
  270. package/lib/module/utils/gesture/apply-gesture-activation-criteria.js.map +0 -1
  271. package/lib/module/utils/gesture/normalize-gesture-translation.js +0 -16
  272. package/lib/module/utils/gesture/normalize-gesture-translation.js.map +0 -1
  273. package/lib/typescript/components/bounds-activator.d.ts +0 -8
  274. package/lib/typescript/components/bounds-activator.d.ts.map +0 -1
  275. package/lib/typescript/hooks/gestures/use-scroll-progress.d.ts.map +0 -1
  276. package/lib/typescript/utils/bounds/build-bound-styles.d.ts +0 -4
  277. package/lib/typescript/utils/bounds/build-bound-styles.d.ts.map +0 -1
  278. package/lib/typescript/utils/bounds/flatten-styles.d.ts.map +0 -1
  279. package/lib/typescript/utils/bounds/geometry.d.ts.map +0 -1
  280. package/lib/typescript/utils/bounds/get-bounds.d.ts +0 -4
  281. package/lib/typescript/utils/bounds/get-bounds.d.ts.map +0 -1
  282. package/lib/typescript/utils/bounds/style-composers.d.ts.map +0 -1
  283. package/lib/typescript/utils/gesture/apply-gesture-activation-criteria.d.ts +0 -17
  284. package/lib/typescript/utils/gesture/apply-gesture-activation-criteria.d.ts.map +0 -1
  285. package/lib/typescript/utils/gesture/normalize-gesture-translation.d.ts +0 -6
  286. package/lib/typescript/utils/gesture/normalize-gesture-translation.d.ts.map +0 -1
  287. package/src/hooks/gestures/use-scroll-progress.tsx +0 -60
  288. package/src/utils/bounds/build-bound-styles.ts +0 -184
  289. package/src/utils/bounds/geometry.ts +0 -113
  290. package/src/utils/bounds/get-bounds.ts +0 -56
  291. package/src/utils/bounds/style-composers.ts +0 -172
  292. package/src/utils/gesture/apply-gesture-activation-criteria.ts +0 -109
  293. package/src/utils/gesture/normalize-gesture-translation.ts +0 -20
  294. /package/lib/commonjs/utils/bounds/{flatten-styles.js → _utils/flatten-styles.js} +0 -0
  295. /package/lib/module/utils/bounds/{flatten-styles.js → _utils/flatten-styles.js} +0 -0
  296. /package/lib/typescript/utils/bounds/{flatten-styles.d.ts → _utils/flatten-styles.d.ts} +0 -0
  297. /package/src/utils/bounds/{flatten-styles.ts → _utils/flatten-styles.ts} +0 -0
@@ -8,7 +8,8 @@ import {
8
8
  } from "react-native-reanimated";
9
9
  import { useKeys } from "../../providers/keys";
10
10
  import { Bounds } from "../../stores/bounds";
11
- import { flattenStyle } from "../../utils/bounds/flatten-styles";
11
+ import { flattenStyle } from "../../utils/bounds/_utils/flatten-styles";
12
+ import { isBoundsEqual } from "../../utils/bounds/_utils/is-bounds-equal";
12
13
  import { useScreenAnimation } from "../animation/use-screen-animation";
13
14
 
14
15
  interface BoundMeasurerHookProps {
@@ -18,7 +19,7 @@ interface BoundMeasurerHookProps {
18
19
  style: StyleProps;
19
20
  }
20
21
 
21
- export const useBoundMeasurer = ({
22
+ export const useBoundsRegistry = ({
22
23
  sharedBoundTag,
23
24
  animatedRef,
24
25
  current,
@@ -26,46 +27,57 @@ export const useBoundMeasurer = ({
26
27
  }: BoundMeasurerHookProps) => {
27
28
  const { previous } = useKeys();
28
29
  const interpolatorProps = useScreenAnimation();
29
- const hasAlreadyMeasured = useSharedValue(false);
30
+ const isMeasured = useSharedValue(false);
30
31
 
31
- const measureAndSet = useCallback(() => {
32
+ const measureBounds = useCallback(() => {
32
33
  "worklet";
33
34
  if (!sharedBoundTag) return;
34
35
  const measured = measure(animatedRef);
35
36
  if (measured) {
36
- Bounds.setBounds(
37
- current.route.key,
38
- sharedBoundTag,
39
- measured,
40
- flattenStyle(style),
41
- );
37
+ const key = current.route.key;
38
+ if (isBoundsEqual({ measured, key, sharedBoundTag })) {
39
+ Bounds.setRouteActive(key, sharedBoundTag);
40
+ return;
41
+ }
42
+
43
+ Bounds.setBounds(key, sharedBoundTag, measured, flattenStyle(style));
44
+ Bounds.setRouteActive(key, sharedBoundTag);
42
45
  }
43
46
  }, [sharedBoundTag, animatedRef, current.route.key, style]);
44
47
 
45
- const measureOnLayout = useCallback(() => {
48
+ const handleLayout = useCallback(() => {
46
49
  "worklet";
47
- if (!sharedBoundTag || hasAlreadyMeasured.value) return;
48
-
49
50
  const previousRouteKey = previous?.route.key;
50
- if (!previousRouteKey) return;
51
+ if (!sharedBoundTag || isMeasured.value || !previousRouteKey) {
52
+ return;
53
+ }
51
54
 
52
55
  const previousBounds = Bounds.getBounds(previousRouteKey);
53
56
  const hasPreviousBoundForTag = previousBounds[sharedBoundTag];
54
57
 
55
58
  if (interpolatorProps.value.current.animating && hasPreviousBoundForTag) {
56
- measureAndSet();
57
- hasAlreadyMeasured.value = true;
59
+ measureBounds();
60
+ isMeasured.value = true;
58
61
  }
59
62
  }, [
60
- measureAndSet,
63
+ measureBounds,
61
64
  interpolatorProps,
62
65
  sharedBoundTag,
63
66
  previous?.route.key,
64
- hasAlreadyMeasured,
67
+ isMeasured,
65
68
  ]);
66
69
 
70
+ const measureOnTouchStart = useCallback(() => {
71
+ "worklet";
72
+ if (sharedBoundTag) {
73
+ Bounds.setActiveBoundId(sharedBoundTag);
74
+ measure(animatedRef);
75
+ }
76
+ }, [sharedBoundTag, animatedRef]);
77
+
67
78
  return {
68
- measureAndSet,
69
- measureOnLayout,
79
+ measureBounds,
80
+ handleLayout,
81
+ measureOnTouchStart,
70
82
  };
71
83
  };
@@ -4,39 +4,45 @@ import {
4
4
  Gesture,
5
5
  type GestureStateChangeEvent,
6
6
  type GestureTouchEvent,
7
+ type GestureType,
7
8
  type GestureUpdateEvent,
8
9
  type PanGestureHandlerEventPayload,
9
10
  } from "react-native-gesture-handler";
10
11
  import type { GestureStateManagerType } from "react-native-gesture-handler/lib/typescript/handlers/gestures/gestureStateManager";
11
12
  import {
12
- interpolate,
13
13
  runOnJS,
14
14
  type SharedValue,
15
15
  useSharedValue,
16
16
  } from "react-native-reanimated";
17
- import type { ScrollProgress } from "../../providers/gestures";
17
+ import type { ScrollConfig } from "../../providers/gestures";
18
18
  import { useKeys } from "../../providers/keys";
19
19
  import { Animations } from "../../stores/animations";
20
20
  import { Gestures } from "../../stores/gestures";
21
21
  import { NavigatorDismissState } from "../../stores/navigator-dismiss-state";
22
+ import { type ActivationArea, GestureOffsetState } from "../../types/gesture";
22
23
  import { animate } from "../../utils/animation/animate";
23
24
  import { runTransition } from "../../utils/animation/run-transition";
24
- import { applyGestureActivationCriteria } from "../../utils/gesture/apply-gesture-activation-criteria";
25
+ import { applyOffsetRules } from "../../utils/gesture/check-gesture-activation";
26
+ import { determineDismissal } from "../../utils/gesture/determine-dismissal";
25
27
  import { mapGestureToProgress } from "../../utils/gesture/map-gesture-to-progress";
28
+ import useStableCallback from "../use-stable-callback";
26
29
 
27
30
  const GESTURE_VELOCITY_IMPACT = 0.3;
28
- const DEFAULT_GESTURE_RESPONSE_DISTANCE = 50;
29
31
  const DEFAULT_GESTURE_DIRECTION = "horizontal";
30
32
  const DEFAULT_GESTURE_ENABLED = false;
31
33
  const DEFAULT_GESTURE_DRIVES_PROGRESS = true;
34
+ const DEFAULT_GESTURE_ACTIVATION_AREA: ActivationArea = "screen";
32
35
 
33
36
  interface BuildGesturesHookProps {
34
- scrollProgress: SharedValue<ScrollProgress>;
37
+ scrollConfig: SharedValue<ScrollConfig | null>;
35
38
  }
36
39
 
37
40
  export const useBuildGestures = ({
38
- scrollProgress,
39
- }: BuildGesturesHookProps) => {
41
+ scrollConfig,
42
+ }: BuildGesturesHookProps): {
43
+ panGesture: GestureType;
44
+ nativeGesture: GestureType;
45
+ } => {
40
46
  const dimensions = useWindowDimensions();
41
47
  const { current } = useKeys();
42
48
 
@@ -44,44 +50,59 @@ export const useBuildGestures = ({
44
50
  x: 0,
45
51
  y: 0,
46
52
  });
53
+ const gestureOffsetState = useSharedValue<GestureOffsetState>(
54
+ GestureOffsetState.PENDING,
55
+ );
47
56
 
48
57
  const gestures = Gestures.getRouteGestures(current.route.key);
49
-
50
58
  const animations = Animations.getAll(current.route.key);
51
59
 
52
60
  const {
53
61
  gestureDirection = DEFAULT_GESTURE_DIRECTION,
54
62
  gestureEnabled = DEFAULT_GESTURE_ENABLED,
55
- transitionSpec,
56
63
  gestureVelocityImpact = GESTURE_VELOCITY_IMPACT,
57
- gestureResponseDistance = DEFAULT_GESTURE_RESPONSE_DISTANCE,
58
64
  gestureDrivesProgress = DEFAULT_GESTURE_DRIVES_PROGRESS,
65
+ gestureActivationArea = DEFAULT_GESTURE_ACTIVATION_AREA,
66
+ gestureResponseDistance,
67
+ transitionSpec,
59
68
  } = current.options;
60
69
 
61
- const directions = Array.isArray(gestureDirection)
62
- ? gestureDirection
63
- : [gestureDirection];
64
-
65
- const allowed = useMemo(
66
- () => ({
67
- bidirectional: directions.includes("bidirectional"),
68
- vertical: directions.includes("vertical"),
69
- verticalInverted: directions.includes("vertical-inverted"),
70
- horizontal: directions.includes("horizontal"),
71
- horizontalInverted: directions.includes("horizontal-inverted"),
72
- }),
73
- [directions],
74
- );
70
+ const directions = useMemo(() => {
71
+ const directionsArray = Array.isArray(gestureDirection)
72
+ ? gestureDirection
73
+ : [gestureDirection];
74
+ const isBidirectional = directionsArray.includes("bidirectional");
75
+
76
+ return {
77
+ vertical: directionsArray.includes("vertical") || isBidirectional,
78
+ verticalInverted:
79
+ directionsArray.includes("vertical-inverted") || isBidirectional,
80
+ horizontal: directionsArray.includes("horizontal") || isBidirectional,
81
+ horizontalInverted:
82
+ directionsArray.includes("horizontal-inverted") || isBidirectional,
83
+ };
84
+ }, [gestureDirection]);
85
+
86
+ const setNavigatorDismissal = useStableCallback(() => {
87
+ const key = current.navigation.getState().key;
75
88
 
76
- const nativeGesture = useMemo(() => Gesture.Native(), []);
89
+ NavigatorDismissState.set(key, true);
90
+ });
91
+
92
+ const handleDismiss = useStableCallback(() => {
93
+ const key = current.navigation.getState().key;
94
+ current.navigation.goBack();
95
+ NavigatorDismissState.remove(key);
96
+ });
77
97
 
78
98
  const onTouchesDown = useCallback(
79
99
  (e: GestureTouchEvent) => {
80
100
  "worklet";
81
101
  const firstTouch = e.changedTouches[0];
82
102
  initialTouch.value = { x: firstTouch.x, y: firstTouch.y };
103
+ gestureOffsetState.value = GestureOffsetState.PENDING;
83
104
  },
84
- [initialTouch],
105
+ [initialTouch, gestureOffsetState],
85
106
  );
86
107
 
87
108
  const onTouchesMove = useCallback(
@@ -89,68 +110,83 @@ export const useBuildGestures = ({
89
110
  "worklet";
90
111
 
91
112
  const touch = e.changedTouches[0];
92
- const deltaX = touch.x - initialTouch.value.x;
93
- const deltaY = touch.y - initialTouch.value.y;
94
-
95
- const isVerticalSwipe = Math.abs(deltaY) > Math.abs(deltaX);
96
- const isHorizontalSwipe = Math.abs(deltaX) > Math.abs(deltaY);
97
-
98
- const isSwipingDown = isVerticalSwipe && deltaY > 0;
99
- const isSwipingUp = isVerticalSwipe && deltaY < 0;
100
- const isSwipingRight = isHorizontalSwipe && deltaX > 0;
101
- const isSwipingLeft = isHorizontalSwipe && deltaX < 0;
102
-
103
- const minMovement = 5;
104
- const hasEnoughMovement =
105
- Math.abs(deltaX) > minMovement || Math.abs(deltaY) > minMovement;
106
113
 
107
- if (!hasEnoughMovement) return;
114
+ const { isSwipingDown, isSwipingUp, isSwipingRight, isSwipingLeft } =
115
+ applyOffsetRules({
116
+ touch,
117
+ directions,
118
+ manager,
119
+ dimensions,
120
+ gestureOffsetState,
121
+ initialTouch: initialTouch.value,
122
+ activationArea: gestureActivationArea,
123
+ responseDistance: gestureResponseDistance,
124
+ });
125
+
126
+ if (gestureOffsetState.value === GestureOffsetState.FAILED) {
127
+ manager.fail();
128
+ return;
129
+ }
108
130
 
131
+ // Keep pending until thresholds are met; no eager activation.
109
132
  if (gestures.isDragging?.value) {
110
133
  manager.activate();
111
134
  return;
112
135
  }
113
136
 
114
- let shouldActivate = false;
137
+ const maxScrollY = scrollConfig.value?.contentHeight
138
+ ? scrollConfig.value.contentHeight - scrollConfig.value.layoutHeight
139
+ : 0;
115
140
 
116
- if (allowed.vertical && isSwipingDown) {
117
- shouldActivate = scrollProgress.value.y <= 0;
118
- }
119
- if (allowed.verticalInverted && isSwipingUp) {
120
- const maxScrollableY =
121
- scrollProgress.value.contentHeight -
122
- scrollProgress.value.layoutHeight;
141
+ const maxScrollX = scrollConfig.value?.contentWidth
142
+ ? scrollConfig.value.contentWidth - scrollConfig.value.layoutWidth
143
+ : 0;
123
144
 
124
- shouldActivate = scrollProgress.value.y >= maxScrollableY;
125
- }
126
- if (allowed.horizontal && isSwipingRight) {
127
- shouldActivate = scrollProgress.value.x <= 0;
128
- }
129
- if (allowed.horizontalInverted && isSwipingLeft) {
130
- const maxProgress =
131
- scrollProgress.value.contentWidth - scrollProgress.value.layoutWidth;
132
- shouldActivate = scrollProgress.value.x >= maxProgress;
133
- }
134
- if (allowed.bidirectional) {
135
- if (isSwipingDown) {
136
- shouldActivate = scrollProgress.value.y >= 0;
137
- } else if (isSwipingUp) {
138
- shouldActivate = scrollProgress.value.y <= 0;
139
- } else if (isSwipingRight || isSwipingLeft) {
140
- shouldActivate = true;
145
+ const recognizedDirection =
146
+ isSwipingDown || isSwipingUp || isSwipingRight || isSwipingLeft;
147
+
148
+ const scrollCfg = scrollConfig.value;
149
+
150
+ let shouldActivate = false;
151
+ if (recognizedDirection) {
152
+ if (directions.vertical && isSwipingDown) {
153
+ shouldActivate = scrollCfg ? scrollCfg.y <= 0 : true;
154
+ }
155
+ if (directions.horizontal && isSwipingRight) {
156
+ shouldActivate = scrollCfg ? scrollCfg.x <= 0 : true;
157
+ }
158
+ if (directions.verticalInverted && isSwipingUp) {
159
+ shouldActivate = scrollCfg ? scrollCfg.y >= maxScrollY : true;
160
+ }
161
+ if (directions.horizontalInverted && isSwipingLeft) {
162
+ shouldActivate = scrollCfg ? scrollCfg.x >= maxScrollX : true;
141
163
  }
142
164
  }
143
165
 
166
+ if (recognizedDirection && !shouldActivate) {
167
+ manager.fail();
168
+ return;
169
+ }
170
+
144
171
  if (
145
- (shouldActivate || gestures.isDragging?.value) &&
172
+ shouldActivate &&
173
+ gestureOffsetState.value === GestureOffsetState.PASSED &&
146
174
  !gestures.isDismissing?.value
147
175
  ) {
148
176
  manager.activate();
149
- } else {
150
- manager.fail();
177
+ return;
151
178
  }
152
179
  },
153
- [initialTouch, scrollProgress, gestures, allowed],
180
+ [
181
+ initialTouch,
182
+ scrollConfig,
183
+ gestures,
184
+ directions,
185
+ gestureOffsetState,
186
+ dimensions,
187
+ gestureActivationArea,
188
+ gestureResponseDistance,
189
+ ],
154
190
  );
155
191
 
156
192
  const onStart = useCallback(() => {
@@ -165,205 +201,134 @@ export const useBuildGestures = ({
165
201
 
166
202
  let gestureProgress = 0;
167
203
 
168
- gestures.x.value = event.translationX;
169
- gestures.y.value = event.translationY;
204
+ const { translationX, translationY } = event;
205
+ const { width, height } = dimensions;
170
206
 
171
- gestures.normalizedX.value = interpolate(
172
- event.translationX,
173
- [-dimensions.width, dimensions.width],
174
- [-1, 1],
175
- "clamp",
207
+ gestures.x.value = translationX;
208
+ gestures.y.value = translationY;
209
+ gestures.normalizedX.value = Math.max(
210
+ -1,
211
+ Math.min(1, translationX / width),
176
212
  );
177
- gestures.normalizedY.value = interpolate(
178
- event.translationY,
179
- [-dimensions.height, dimensions.height],
180
- [-1, 1],
181
- "clamp",
213
+ gestures.normalizedY.value = Math.max(
214
+ -1,
215
+ Math.min(1, translationY / height),
182
216
  );
183
217
 
184
- if (allowed.bidirectional) {
185
- const distance = Math.sqrt(
186
- event.translationX ** 2 + event.translationY ** 2,
187
- );
188
- gestureProgress = mapGestureToProgress(distance, dimensions.width);
189
- } else {
190
- let maxProgress = 0;
191
-
192
- const allowedDown = allowed.vertical;
193
- const allowedUp = allowed.verticalInverted;
194
- const allowedRight = allowed.horizontal;
195
- const allowedLeft = allowed.horizontalInverted;
196
-
197
- if (allowedRight && event.translationX > 0) {
198
- const currentProgress = mapGestureToProgress(
199
- event.translationX,
200
- dimensions.width,
201
- );
202
- maxProgress = Math.max(maxProgress, currentProgress);
203
- }
218
+ let maxProgress = 0;
204
219
 
205
- if (allowedLeft && event.translationX < 0) {
206
- const currentProgress = mapGestureToProgress(
207
- -event.translationX,
208
- dimensions.width,
209
- );
210
- maxProgress = Math.max(maxProgress, currentProgress);
211
- }
220
+ const allowedDown = directions.vertical;
221
+ const allowedUp = directions.verticalInverted;
222
+ const allowedRight = directions.horizontal;
223
+ const allowedLeft = directions.horizontalInverted;
212
224
 
213
- if (allowedDown && event.translationY > 0) {
214
- const currentProgress = mapGestureToProgress(
215
- event.translationY,
216
- dimensions.height,
217
- );
218
- maxProgress = Math.max(maxProgress, currentProgress);
219
- }
225
+ if (allowedRight && event.translationX > 0) {
226
+ const currentProgress = mapGestureToProgress(
227
+ translationX,
228
+ dimensions.width,
229
+ );
230
+ maxProgress = Math.max(maxProgress, currentProgress);
231
+ }
220
232
 
221
- if (allowedUp && event.translationY < 0) {
222
- const currentProgress = mapGestureToProgress(
223
- -event.translationY,
224
- dimensions.height,
225
- );
226
- maxProgress = Math.max(maxProgress, currentProgress);
227
- }
233
+ if (allowedLeft && event.translationX < 0) {
234
+ const currentProgress = mapGestureToProgress(
235
+ -translationX,
236
+ dimensions.width,
237
+ );
238
+ maxProgress = Math.max(maxProgress, currentProgress);
239
+ }
228
240
 
229
- gestureProgress = maxProgress;
241
+ if (allowedDown && event.translationY > 0) {
242
+ const currentProgress = mapGestureToProgress(
243
+ translationY,
244
+ dimensions.height,
245
+ );
246
+ maxProgress = Math.max(maxProgress, currentProgress);
247
+ }
248
+
249
+ if (allowedUp && event.translationY < 0) {
250
+ const currentProgress = mapGestureToProgress(
251
+ -translationY,
252
+ dimensions.height,
253
+ );
254
+ maxProgress = Math.max(maxProgress, currentProgress);
230
255
  }
231
256
 
257
+ gestureProgress = maxProgress;
258
+
232
259
  if (gestureDrivesProgress) {
233
260
  animations.progress.value = 1 - gestureProgress;
234
261
  }
235
262
  },
236
- [dimensions, gestures, animations, gestureDrivesProgress, allowed],
263
+ [dimensions, gestures, animations, gestureDrivesProgress, directions],
237
264
  );
238
265
 
239
- const setNavigatorDismissal = useCallback(() => {
240
- const key = current.navigation.getState().key;
241
-
242
- NavigatorDismissState.set(key, true);
243
- }, [current]);
244
-
245
- const handleDismiss = useCallback(() => {
246
- const key = current.navigation.getState().key;
247
- current.navigation.goBack();
248
- NavigatorDismissState.remove(key);
249
- }, [current]);
250
-
251
266
  const onEnd = useCallback(
252
267
  (event: GestureStateChangeEvent<PanGestureHandlerEventPayload>) => {
253
268
  "worklet";
254
269
 
255
- const { translationX, translationY, velocityX, velocityY } = event;
256
-
257
- // reminder: we should make this into an option
258
- const dismissThreshold = 0.5;
259
-
260
- const finalX = translationX + velocityX * gestureVelocityImpact;
261
- const finalY = translationY + velocityY * gestureVelocityImpact;
262
-
263
- const diagonal = Math.sqrt(
264
- dimensions.width * dimensions.width +
265
- dimensions.height * dimensions.height,
266
- );
270
+ const { shouldDismiss, velocity } = determineDismissal({
271
+ event,
272
+ directions,
273
+ dimensions,
274
+ gestureVelocityImpact,
275
+ });
267
276
 
268
- let shouldDismiss = false;
269
-
270
- const horizontalDistance = Math.abs(finalX);
271
- const verticalDistance = Math.abs(finalY);
272
- const crossAxisThreshold = diagonal * dismissThreshold * 0.7;
273
-
274
- if (allowed.bidirectional) {
275
- // For bidirectional, use the original distance-based logic
276
- const finalDistance = Math.sqrt(finalX * finalX + finalY * finalY);
277
- shouldDismiss = finalDistance > diagonal * dismissThreshold;
278
- } else {
279
- // Check primary direction dismissal
280
- if (allowed.vertical && finalY > 0) {
281
- shouldDismiss = verticalDistance > diagonal * dismissThreshold;
282
- } else if (allowed.verticalInverted && finalY < 0) {
283
- shouldDismiss = verticalDistance > diagonal * dismissThreshold;
284
- } else if (allowed.horizontal && finalX > 0) {
285
- shouldDismiss = horizontalDistance > diagonal * dismissThreshold;
286
- } else if (allowed.horizontalInverted && finalX < 0) {
287
- shouldDismiss = horizontalDistance > diagonal * dismissThreshold;
288
- }
289
-
290
- // Allow dismissal on perpendicular axis if movement is significant
291
- if (!shouldDismiss) {
292
- if (
293
- (allowed.vertical || allowed.verticalInverted) &&
294
- horizontalDistance > crossAxisThreshold
295
- ) {
296
- shouldDismiss = true;
297
- } else if (
298
- (allowed.horizontal || allowed.horizontalInverted) &&
299
- verticalDistance > crossAxisThreshold
300
- ) {
301
- shouldDismiss = true;
302
- }
303
- }
304
- }
277
+ const spec = shouldDismiss ? transitionSpec?.close : transitionSpec?.open;
305
278
 
306
279
  gestures.isDismissing.value = Number(shouldDismiss);
307
280
 
308
- if (gestures.isDismissing.value) {
281
+ // Provide per-axis velocities so drag return can bounce naturally
282
+ const vxPx = event.velocityX;
283
+ const vyPx = event.velocityY;
284
+ const vxNorm = vxPx / Math.max(1, dimensions.width);
285
+ const vyNorm = vyPx / Math.max(1, dimensions.height);
286
+ gestures.x.value = animate(0, { ...spec, velocity: vxPx });
287
+ gestures.y.value = animate(0, { ...spec, velocity: vyPx });
288
+ gestures.normalizedX.value = animate(0, { ...spec, velocity: vxNorm });
289
+ gestures.normalizedY.value = animate(0, { ...spec, velocity: vyNorm });
290
+ gestures.isDragging.value = 0;
291
+
292
+ if (shouldDismiss) {
309
293
  runOnJS(setNavigatorDismissal)();
310
294
  }
311
295
 
312
296
  runTransition({
313
- target: gestures.isDismissing.value ? "close" : "open",
297
+ target: shouldDismiss ? "close" : "open",
298
+ onFinish: shouldDismiss ? handleDismiss : undefined,
314
299
  spec: transitionSpec,
315
- onFinish: gestures.isDismissing.value ? handleDismiss : undefined,
300
+ velocity,
316
301
  animations,
317
302
  });
318
-
319
- const spec = gestures.isDismissing.value
320
- ? transitionSpec?.close
321
- : transitionSpec?.open;
322
-
323
- gestures.x.value = animate(0, spec);
324
- gestures.y.value = animate(0, spec);
325
- gestures.normalizedX.value = animate(0, spec);
326
- gestures.normalizedY.value = animate(0, spec);
327
- gestures.isDragging.value = 0;
328
303
  },
329
304
  [
330
305
  dimensions,
331
306
  animations,
332
307
  transitionSpec,
333
- gestureVelocityImpact,
334
308
  setNavigatorDismissal,
335
309
  handleDismiss,
336
310
  gestures,
337
- allowed,
311
+ directions,
312
+ gestureVelocityImpact,
338
313
  ],
339
314
  );
340
315
 
341
- const panGesture = useMemo(
342
- () =>
343
- Gesture.Pan()
344
- .enabled(gestureEnabled)
345
- .manualActivation(true)
346
- .onTouchesDown(onTouchesDown)
347
- .onTouchesMove(onTouchesMove)
348
- .onStart(onStart)
349
- .onUpdate(onUpdate)
350
- .onEnd(onEnd)
351
- .blocksExternalGesture(nativeGesture),
352
- [
353
- gestureEnabled,
316
+ return useMemo(() => {
317
+ const nativeGesture = Gesture.Native();
318
+
319
+ const panGesture = Gesture.Pan()
320
+ .enabled(gestureEnabled)
321
+ .manualActivation(true)
322
+ .onTouchesDown(onTouchesDown)
323
+ .onTouchesMove(onTouchesMove)
324
+ .onStart(onStart)
325
+ .onUpdate(onUpdate)
326
+ .onEnd(onEnd)
327
+ .blocksExternalGesture(nativeGesture);
328
+
329
+ return {
330
+ panGesture,
354
331
  nativeGesture,
355
- onTouchesDown,
356
- onTouchesMove,
357
- onStart,
358
- onUpdate,
359
- onEnd,
360
- ],
361
- );
362
-
363
- applyGestureActivationCriteria({
364
- gestureDirection,
365
- gestureResponseDistance,
366
- panGesture,
367
- });
368
- return { panGesture, nativeGesture };
332
+ };
333
+ }, [gestureEnabled, onTouchesDown, onTouchesMove, onStart, onUpdate, onEnd]);
369
334
  };
@@ -0,0 +1,18 @@
1
+ import { useEffect } from "react";
2
+ import { useGestureContext } from "../../providers/gestures";
3
+ import useStableCallback from "../use-stable-callback";
4
+
5
+ /**
6
+ * Registers native gestures with parent gestures to enable proper gesture handling
7
+ * in nested navigators that contain scrollable content.
8
+ */
9
+ export const useParentGestureRegistry = () => {
10
+ const { parentContext, nativeGesture } = useGestureContext();
11
+ const registerNativeGesture = useStableCallback(() => {
12
+ if (parentContext?.panGesture && nativeGesture) {
13
+ parentContext.panGesture.blocksExternalGesture(nativeGesture);
14
+ }
15
+ });
16
+
17
+ useEffect(registerNativeGesture);
18
+ };