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
@@ -0,0 +1,145 @@
1
+ import type { LayoutChangeEvent } from "react-native";
2
+ import { useAnimatedScrollHandler } from "react-native-reanimated";
3
+ import type { ReanimatedScrollEvent } from "react-native-reanimated/lib/typescript/hook/commonTypes";
4
+ import { useGestureContext } from "../../providers/gestures";
5
+ import type { Any } from "../../types/utils";
6
+ import useStableCallback from "../use-stable-callback";
7
+
8
+ interface ScrollProgressHookProps {
9
+ onScroll?: (event: ReanimatedScrollEvent) => void;
10
+ onContentSizeChange?: (width: number, height: number) => void;
11
+ onLayout?: (event: LayoutChangeEvent) => void;
12
+ }
13
+
14
+ export const useScrollRegistry = (props: ScrollProgressHookProps) => {
15
+ const { scrollConfig, parentContext } = useGestureContext();
16
+
17
+ const scrollHandler = useAnimatedScrollHandler({
18
+ onScroll: (event) => {
19
+ props.onScroll?.(event);
20
+
21
+ scrollConfig.modify((v: Any) => {
22
+ "worklet";
23
+ if (v === null) {
24
+ return {
25
+ x: event.contentOffset.x,
26
+ y: event.contentOffset.y,
27
+ contentHeight: 0,
28
+ contentWidth: 0,
29
+ layoutHeight: 0,
30
+ layoutWidth: 0,
31
+ };
32
+ }
33
+ v.x = event.contentOffset.x;
34
+ v.y = event.contentOffset.y;
35
+ return v;
36
+ });
37
+
38
+ if (parentContext?.scrollConfig) {
39
+ parentContext.scrollConfig.modify((v: Any) => {
40
+ "worklet";
41
+ if (v === null) {
42
+ return {
43
+ x: event.contentOffset.x,
44
+ y: event.contentOffset.y,
45
+ contentHeight: 0,
46
+ contentWidth: 0,
47
+ layoutHeight: 0,
48
+ layoutWidth: 0,
49
+ };
50
+ }
51
+ v.x = event.contentOffset.x;
52
+ v.y = event.contentOffset.y;
53
+ return v;
54
+ });
55
+ }
56
+ },
57
+ });
58
+
59
+ const onContentSizeChange = useStableCallback(
60
+ (width: number, height: number) => {
61
+ props.onContentSizeChange?.(width, height);
62
+
63
+ scrollConfig.modify((v: Any) => {
64
+ "worklet";
65
+ if (v === null) {
66
+ return {
67
+ x: 0,
68
+ y: 0,
69
+ layoutHeight: 0,
70
+ layoutWidth: 0,
71
+ contentWidth: width,
72
+ contentHeight: height,
73
+ };
74
+ }
75
+ v.contentWidth = width;
76
+ v.contentHeight = height;
77
+ return v;
78
+ });
79
+ if (parentContext?.scrollConfig) {
80
+ parentContext.scrollConfig.modify((v: Any) => {
81
+ "worklet";
82
+ if (v === null) {
83
+ return {
84
+ x: 0,
85
+ y: 0,
86
+ layoutHeight: 0,
87
+ layoutWidth: 0,
88
+ contentWidth: width,
89
+ contentHeight: height,
90
+ };
91
+ }
92
+ v.contentWidth = width;
93
+ v.contentHeight = height;
94
+ return v;
95
+ });
96
+ }
97
+ },
98
+ );
99
+
100
+ const onLayout = useStableCallback((event: LayoutChangeEvent) => {
101
+ props.onLayout?.(event);
102
+ const { width, height } = event.nativeEvent.layout;
103
+
104
+ scrollConfig.modify((v: Any) => {
105
+ "worklet";
106
+ if (v === null) {
107
+ return {
108
+ x: 0,
109
+ y: 0,
110
+ contentHeight: 0,
111
+ contentWidth: 0,
112
+ layoutHeight: height,
113
+ layoutWidth: width,
114
+ };
115
+ }
116
+ v.layoutHeight = height;
117
+ v.layoutWidth = width;
118
+ return v;
119
+ });
120
+ if (parentContext?.scrollConfig) {
121
+ parentContext.scrollConfig.modify((v: Any) => {
122
+ "worklet";
123
+ if (v === null) {
124
+ return {
125
+ x: 0,
126
+ y: 0,
127
+ contentHeight: 0,
128
+ contentWidth: 0,
129
+ layoutHeight: height,
130
+ layoutWidth: width,
131
+ };
132
+ }
133
+ v.layoutHeight = height;
134
+ v.layoutWidth = width;
135
+ return v;
136
+ });
137
+ }
138
+ });
139
+
140
+ return {
141
+ scrollHandler,
142
+ onContentSizeChange,
143
+ onLayout,
144
+ };
145
+ };
package/src/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { FlatList, Pressable, ScrollView, View } from "react-native";
2
2
  import { createTransitionAwareComponent } from "./components/create-transition-aware-component";
3
+ import MaskedView from "./components/integrations/masked-view";
3
4
  import { presets, specs } from "./configs";
4
5
 
5
6
  export default {
@@ -11,6 +12,7 @@ export default {
11
12
  FlatList: createTransitionAwareComponent(FlatList, {
12
13
  isScrollable: true,
13
14
  }),
15
+ MaskedView: MaskedView,
14
16
  presets,
15
17
  specs,
16
18
  createTransitionAwareComponent,
@@ -36,6 +36,7 @@ import { ScreenLifecycleController } from "../../../components/controllers/scree
36
36
  import { RootTransitionAware } from "../../../components/root-transition-aware";
37
37
  import { ScreenGestureProvider } from "../../../providers/gestures";
38
38
  import { KeysProvider } from "../../../providers/keys";
39
+ import { TransitionStylesProvider } from "../../../providers/transition-styles";
39
40
  import type {
40
41
  NativeStackDescriptor,
41
42
  NativeStackDescriptorMap,
@@ -473,11 +474,13 @@ const SceneView = ({
473
474
  current={descriptor}
474
475
  next={nextDescriptor}
475
476
  >
476
- <ScreenLifecycleController>
477
- <ScreenGestureProvider>
478
- <RootTransitionAware>{render()}</RootTransitionAware>
479
- </ScreenGestureProvider>
480
- </ScreenLifecycleController>
477
+ <ScreenGestureProvider>
478
+ <ScreenLifecycleController>
479
+ <TransitionStylesProvider>
480
+ <RootTransitionAware>{render()}</RootTransitionAware>
481
+ </TransitionStylesProvider>
482
+ </ScreenLifecycleController>
483
+ </ScreenGestureProvider>
481
484
  </KeysProvider>
482
485
  </HeaderBackContext.Provider>
483
486
  </HeaderShownContext.Provider>
@@ -1,15 +1,12 @@
1
1
  import { createContext, useContext, useMemo } from "react";
2
2
  import { StyleSheet, View } from "react-native";
3
3
  import type { GestureType } from "react-native-gesture-handler";
4
- import {
5
- GestureDetector,
6
- GestureHandlerRootView,
7
- } from "react-native-gesture-handler";
4
+ import { GestureDetector } from "react-native-gesture-handler";
8
5
  import type { SharedValue } from "react-native-reanimated";
9
6
  import { useSharedValue } from "react-native-reanimated";
10
7
  import { useBuildGestures } from "../hooks/gestures/use-build-gestures";
11
8
 
12
- export type ScrollProgress = {
9
+ export type ScrollConfig = {
13
10
  x: number;
14
11
  y: number;
15
12
  contentHeight: number;
@@ -21,14 +18,15 @@ export type ScrollProgress = {
21
18
  export interface GestureContextType {
22
19
  panGesture: GestureType;
23
20
  nativeGesture: GestureType;
24
- scrollProgress: SharedValue<ScrollProgress>;
21
+ scrollConfig: SharedValue<ScrollConfig | null>;
22
+ parentContext: GestureContextType | null;
25
23
  }
26
24
 
27
25
  type ScreenGestureProviderProps = {
28
26
  children: React.ReactNode;
29
27
  };
30
28
 
31
- const DEFAULT_SCROLL_PROGRESS: ScrollProgress = {
29
+ export const DEFAULT_SCROLL_CONFIG: ScrollConfig = {
32
30
  x: 0,
33
31
  y: 0,
34
32
  contentHeight: 0,
@@ -42,31 +40,30 @@ const GestureContext = createContext<GestureContextType | undefined>(undefined);
42
40
  export const ScreenGestureProvider = ({
43
41
  children,
44
42
  }: ScreenGestureProviderProps) => {
45
- const scrollProgress = useSharedValue<ScrollProgress>(
46
- DEFAULT_SCROLL_PROGRESS,
47
- );
43
+ const parentContext = useContext(GestureContext);
44
+
45
+ const scrollConfig = useSharedValue<ScrollConfig | null>(null);
48
46
 
49
47
  const { panGesture, nativeGesture } = useBuildGestures({
50
- scrollProgress,
48
+ scrollConfig,
51
49
  });
52
50
 
53
- const value = useMemo(
51
+ const value: GestureContextType = useMemo(
54
52
  () => ({
55
53
  panGesture,
56
- scrollProgress,
54
+ scrollConfig,
57
55
  nativeGesture,
56
+ parentContext: parentContext || null,
58
57
  }),
59
- [panGesture, scrollProgress, nativeGesture],
60
- ) satisfies GestureContextType;
58
+ [panGesture, scrollConfig, nativeGesture, parentContext],
59
+ );
61
60
 
62
61
  return (
63
- <GestureHandlerRootView>
64
- <GestureContext.Provider value={value}>
65
- <GestureDetector gesture={panGesture}>
66
- <View style={styles.container}>{children}</View>
67
- </GestureDetector>
68
- </GestureContext.Provider>
69
- </GestureHandlerRootView>
62
+ <GestureContext.Provider value={value}>
63
+ <GestureDetector gesture={panGesture}>
64
+ <View style={styles.container}>{children}</View>
65
+ </GestureDetector>
66
+ </GestureContext.Provider>
70
67
  );
71
68
  };
72
69
 
@@ -0,0 +1,52 @@
1
+ import { createContext, useContext, useMemo } from "react";
2
+ import { isWorkletFunction, useDerivedValue } from "react-native-reanimated";
3
+ import { _useScreenAnimation } from "../hooks/animation/use-screen-animation";
4
+ import type { TransitionInterpolatedStyle } from "../types/animation";
5
+
6
+ type Props = {
7
+ children: React.ReactNode;
8
+ };
9
+
10
+ const EMPTY_MAP = Object.freeze({});
11
+
12
+ const TransitionStylesContext = createContext<ReturnType<
13
+ typeof useDerivedValue<TransitionInterpolatedStyle>
14
+ > | null>(null);
15
+
16
+ export function TransitionStylesProvider({ children }: Props) {
17
+ const { screenInterpolatorProps, screenStyleInterpolator } =
18
+ _useScreenAnimation();
19
+
20
+ const isFunctionWorklet = isWorkletFunction(screenStyleInterpolator);
21
+
22
+ const stylesMap = useDerivedValue<TransitionInterpolatedStyle>(() => {
23
+ "worklet";
24
+
25
+ if (screenStyleInterpolator && !isFunctionWorklet && __DEV__) {
26
+ console.warn("screenStyleInterpolator is not a worklet function");
27
+ return EMPTY_MAP;
28
+ }
29
+
30
+ return screenStyleInterpolator
31
+ ? screenStyleInterpolator(screenInterpolatorProps.value)
32
+ : EMPTY_MAP;
33
+ });
34
+
35
+ const value = useMemo(() => stylesMap, [stylesMap]);
36
+
37
+ return (
38
+ <TransitionStylesContext.Provider value={value}>
39
+ {children}
40
+ </TransitionStylesContext.Provider>
41
+ );
42
+ }
43
+
44
+ export function useTransitionStyles() {
45
+ const ctx = useContext(TransitionStylesContext);
46
+ if (!ctx) {
47
+ throw new Error(
48
+ "useTransitionStyles must be used within a TransitionStylesProvider",
49
+ );
50
+ }
51
+ return ctx;
52
+ }
@@ -3,6 +3,7 @@ import {
3
3
  makeMutable,
4
4
  type StyleProps,
5
5
  } from "react-native-reanimated";
6
+ import type { ScreenTransitionState } from "../types/animation";
6
7
  import type { ScreenKey } from "../types/navigator";
7
8
  import type { Any } from "../types/utils";
8
9
 
@@ -13,6 +14,13 @@ type BoundsDict = Record<
13
14
 
14
15
  const registry = makeMutable<BoundsDict>({});
15
16
  const activeBoundId = makeMutable<string | null>(null);
17
+ const lastActiveByRoute = makeMutable<Record<string, string>>({});
18
+ const pairHints = makeMutable<Record<string, string>>({});
19
+
20
+ function pairKey(fromKey?: string, toKey?: string) {
21
+ "worklet";
22
+ return fromKey && toKey ? `${fromKey}|${toKey}` : "";
23
+ }
16
24
 
17
25
  function setBounds(
18
26
  screenId: string,
@@ -47,6 +55,38 @@ function getActiveBoundId() {
47
55
  return activeBoundId.value;
48
56
  }
49
57
 
58
+ function setRouteActive(routeKey: string, boundId: string) {
59
+ "worklet";
60
+ lastActiveByRoute.modify((state: Any) => {
61
+ "worklet";
62
+ state[routeKey] = boundId;
63
+ return state;
64
+ });
65
+ }
66
+
67
+ function getRouteActive(routeKey: string) {
68
+ "worklet";
69
+ return lastActiveByRoute.value[routeKey] ?? null;
70
+ }
71
+
72
+ function setTransitionHint(fromKey: string, toKey: string, boundId: string) {
73
+ "worklet";
74
+ const key = pairKey(fromKey, toKey);
75
+ if (!key) return;
76
+ pairHints.modify((state: Any) => {
77
+ "worklet";
78
+ state[key] = boundId;
79
+ return state;
80
+ });
81
+ }
82
+
83
+ function getTransitionHint(fromKey: string, toKey: string) {
84
+ "worklet";
85
+ const key = pairKey(fromKey, toKey);
86
+ if (!key) return null;
87
+ return pairHints.value[key] ?? null;
88
+ }
89
+
50
90
  function clear(routeKey: ScreenKey) {
51
91
  "worklet";
52
92
  registry.modify((state: Any) => {
@@ -61,11 +101,127 @@ function clearActive() {
61
101
  activeBoundId.value = null;
62
102
  }
63
103
 
104
+ // Helpers for readability
105
+ function hasBound(s: ScreenTransitionState | undefined, id?: string | null) {
106
+ "worklet";
107
+ return !!id && !!s && !!s.bounds && !!s.bounds[id];
108
+ }
109
+
110
+ function keysOf(s: ScreenTransitionState | undefined) {
111
+ "worklet";
112
+ return Object.keys(s?.bounds || {});
113
+ }
114
+
115
+ function getRoutePair(
116
+ current: ScreenTransitionState,
117
+ next: ScreenTransitionState | undefined,
118
+ previous: ScreenTransitionState | undefined,
119
+ ) {
120
+ "worklet";
121
+ const isClosing = !!next;
122
+ const fromKey = isClosing ? current.route.key : previous?.route.key;
123
+ const toKey = isClosing ? next?.route.key : current.route.key;
124
+ const other = next ?? previous;
125
+ return { fromKey, toKey, other } as const;
126
+ }
127
+
128
+ function resolveFromHints(
129
+ fromKey: string | undefined,
130
+ toKey: string | undefined,
131
+ other: ScreenTransitionState | undefined,
132
+ ) {
133
+ "worklet";
134
+ if (fromKey && toKey) {
135
+ const hinted = getTransitionHint(fromKey, toKey);
136
+ if (hasBound(other, hinted)) return hinted as string;
137
+ }
138
+ return "";
139
+ }
140
+
141
+ function resolveFromRequested(
142
+ reqId: string | null,
143
+ current: ScreenTransitionState,
144
+ other: ScreenTransitionState | undefined,
145
+ ) {
146
+ "worklet";
147
+ const otherHasAny = !!other && keysOf(other).length > 0;
148
+ if (hasBound(other, reqId)) return reqId as string;
149
+ if (!otherHasAny && hasBound(current, reqId)) return reqId as string;
150
+ return "";
151
+ }
152
+
153
+ function resolveFromSets(
154
+ current: ScreenTransitionState,
155
+ other: ScreenTransitionState | undefined,
156
+ fromKey: string | undefined,
157
+ ) {
158
+ "worklet";
159
+ if (!other) return "";
160
+ const a = keysOf(current);
161
+ const b = keysOf(other);
162
+ const inter = a.filter((k) => b.includes(k));
163
+ const otherHasAny = b.length > 0;
164
+ const routeActive = fromKey ? getRouteActive(fromKey) : null;
165
+
166
+ if (inter.length > 0) {
167
+ if (routeActive && inter.includes(routeActive)) return routeActive;
168
+ return inter[0];
169
+ }
170
+
171
+ if (routeActive && hasBound(other, routeActive)) return routeActive;
172
+ if (b.length === 1) return b[0];
173
+
174
+ if (!otherHasAny) {
175
+ if (routeActive && hasBound(current, routeActive)) return routeActive;
176
+ if (a.length === 1) return a[0];
177
+ }
178
+
179
+ return "";
180
+ }
181
+
182
+ function getActiveBound(
183
+ current: ScreenTransitionState,
184
+ next: ScreenTransitionState | undefined,
185
+ previous: ScreenTransitionState | undefined,
186
+ ) {
187
+ "worklet";
188
+ const requestedId = activeBoundId.value;
189
+ const { fromKey, toKey, other } = getRoutePair(current, next, previous);
190
+
191
+ // check last remembered hint
192
+ const byHint = resolveFromHints(fromKey, toKey, other);
193
+ if (byHint) {
194
+ if (fromKey && toKey) setTransitionHint(fromKey, toKey, byHint);
195
+ return byHint;
196
+ }
197
+
198
+ // check the active id
199
+ const byRequested = resolveFromRequested(requestedId, current, other);
200
+ if (byRequested) {
201
+ if (fromKey && toKey) setTransitionHint(fromKey, toKey, byRequested);
202
+ return byRequested;
203
+ }
204
+
205
+ // check the sets (intersection/MRU/fallbacks)
206
+ const bySets = resolveFromSets(current, other, fromKey);
207
+ if (bySets) {
208
+ if (fromKey && toKey) setTransitionHint(fromKey, toKey, bySets);
209
+ return bySets;
210
+ }
211
+
212
+ return "";
213
+ }
214
+
64
215
  export const Bounds = {
65
216
  setBounds,
66
217
  getBounds,
67
218
  setActiveBoundId,
68
219
  getActiveBoundId,
220
+ setRouteActive,
221
+ getRouteActive,
222
+ setTransitionHint,
223
+ getTransitionHint,
69
224
  clear,
70
225
  clearActive,
226
+ getActiveBound,
71
227
  };
@@ -6,9 +6,14 @@ import { Gestures } from "../gestures";
6
6
  /**
7
7
  * Reset all stores for a given screen
8
8
  */
9
- export const resetStoresForScreen = (current: NativeStackDescriptor) => {
9
+ export const resetStoresForScreen = (
10
+ current: NativeStackDescriptor,
11
+ options: { clearActive?: boolean } = {},
12
+ ) => {
10
13
  Animations.clear(current.route.key);
11
14
  Gestures.clear(current.route.key);
12
15
  Bounds.clear(current.route.key);
13
- Bounds.clearActive();
16
+ if (options.clearActive) {
17
+ Bounds.clearActive();
18
+ }
14
19
  };
@@ -1,4 +1,8 @@
1
1
  import type { MeasuredDimensions, StyleProps } from "react-native-reanimated";
2
+ import type {
3
+ BoundsBuilderOptions,
4
+ BoundsReturnType,
5
+ } from "../utils/bounds/_types/builder";
2
6
  import type { ScreenPhase } from "./core";
3
7
 
4
8
  /**
@@ -77,6 +81,9 @@ export type BoundEntry = {
77
81
  styles: StyleProps;
78
82
  };
79
83
 
80
- export type BoundsAccessor = ((id?: string) => BoundsBuilder) & {
84
+ export type BoundsAccessor = {
85
+ (id: string): BoundsBuilder;
86
+ (): BoundsBuilder;
87
+ <T extends BoundsBuilderOptions>(options: T): BoundsReturnType<T>;
81
88
  get: (id?: string, phase?: ScreenPhase) => BoundEntry;
82
89
  };
@@ -5,6 +5,25 @@ export type GestureDirection =
5
5
  | "vertical-inverted"
6
6
  | "bidirectional";
7
7
 
8
+ export type ActivationArea = "edge" | "screen";
9
+
10
+ export type SideActivation = {
11
+ left?: ActivationArea;
12
+ right?: ActivationArea;
13
+ top?: ActivationArea;
14
+ bottom?: ActivationArea;
15
+ };
16
+
17
+ export enum GestureOffsetState {
18
+ PENDING,
19
+ PASSED,
20
+ FAILED,
21
+ }
22
+
23
+ export type AxisActivation = ActivationArea | SideActivation;
24
+
25
+ export type GestureActivationArea = ActivationArea | SideActivation;
26
+
8
27
  export type GestureValues = {
9
28
  /**
10
29
  * A `SharedValue` indicating if the user's finger is on the screen (0 or 1).
@@ -23,7 +23,7 @@ import type {
23
23
  SearchBarProps,
24
24
  } from "react-native-screens";
25
25
  import type { ScreenStyleInterpolator, TransitionSpec } from "./animation";
26
- import type { GestureDirection } from "./gesture";
26
+ import type { GestureActivationArea, GestureDirection } from "./gesture";
27
27
 
28
28
  export type NativeStackNavigationEventMap = {
29
29
  /**
@@ -168,6 +168,10 @@ export type ScreenTransitionConfig = {
168
168
  * Whether the gesture drives the progress.
169
169
  */
170
170
  gestureDrivesProgress?: boolean;
171
+ /**
172
+ * The area of the screen where the gesture is activated.
173
+ */
174
+ gestureActivationArea?: GestureActivationArea;
171
175
  /**
172
176
  * Whether to enable transitions. It sets the presentation to containedTransparentModal, animation none, and headerShown to false.
173
177
  */
@@ -0,0 +1,38 @@
1
+ import type { ScaledSize } from "react-native";
2
+ import { Bounds } from "../../stores/bounds";
3
+ import type { ScreenTransitionState } from "../../types/animation";
4
+ import { createBounds } from "../bounds";
5
+
6
+ interface DerivationsParams {
7
+ current: ScreenTransitionState;
8
+ next?: ScreenTransitionState;
9
+ previous?: ScreenTransitionState;
10
+ dimensions: ScaledSize;
11
+ }
12
+
13
+ /**
14
+ * Additional values to help make defining animations easier.
15
+ */
16
+ export const derivations = ({
17
+ current,
18
+ next,
19
+ previous,
20
+ dimensions,
21
+ }: DerivationsParams) => {
22
+ "worklet";
23
+ const progress = current.progress + (next?.progress ?? 0);
24
+ const focused = !next;
25
+
26
+ const activeBoundId = Bounds.getActiveBound(current, next, previous);
27
+
28
+ const bounds = createBounds({
29
+ activeBoundId,
30
+ current,
31
+ previous,
32
+ next,
33
+ progress,
34
+ dimensions,
35
+ });
36
+
37
+ return { progress, focused, activeBoundId, bounds };
38
+ };
@@ -8,6 +8,7 @@ interface RunTransitionProps {
8
8
  spec?: TransitionSpec;
9
9
  onFinish?: (finished: boolean) => void;
10
10
  animations: AnimationMap;
11
+ velocity?: number;
11
12
  }
12
13
 
13
14
  export const runTransition = ({
@@ -15,6 +16,7 @@ export const runTransition = ({
15
16
  spec,
16
17
  onFinish,
17
18
  animations,
19
+ velocity,
18
20
  }: RunTransitionProps) => {
19
21
  "worklet";
20
22
  const value = target === "open" ? 1 : 0;
@@ -37,7 +39,8 @@ export const runTransition = ({
37
39
  }
38
40
 
39
41
  animating.value = 1;
40
- progress.value = animate(value, config, (finished) => {
42
+
43
+ progress.value = animate(value, { ...config, velocity }, (finished) => {
41
44
  "worklet";
42
45
  if (finished) {
43
46
  animating.value = 0;