react-native-screen-transitions 3.11.3 → 3.12.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 (221) hide show
  1. package/lib/commonjs/blank-stack/components/stack-view.js +1 -2
  2. package/lib/commonjs/blank-stack/components/stack-view.js.map +1 -1
  3. package/lib/commonjs/component-stack/components/stack-view.js +1 -2
  4. package/lib/commonjs/component-stack/components/stack-view.js.map +1 -1
  5. package/lib/commonjs/native-stack/views/NativeStackView.native.js +2 -3
  6. package/lib/commonjs/native-stack/views/NativeStackView.native.js.map +1 -1
  7. package/lib/commonjs/shared/adapters/with-screen-transitions/stack-layout.js +1 -1
  8. package/lib/commonjs/shared/adapters/with-screen-transitions/stack-layout.js.map +1 -1
  9. package/lib/commonjs/shared/components/boundary/portal/components/boundary-content-portal/hooks/use-boundary-content-portal-attachment.js +7 -4
  10. package/lib/commonjs/shared/components/boundary/portal/components/boundary-content-portal/hooks/use-boundary-content-portal-attachment.js.map +1 -1
  11. package/lib/commonjs/shared/components/overlay/helpers/create-overlay-interpolator-frame.js +30 -0
  12. package/lib/commonjs/shared/components/overlay/helpers/create-overlay-interpolator-frame.js.map +1 -0
  13. package/lib/commonjs/shared/components/overlay/helpers/get-active-overlay.js +40 -22
  14. package/lib/commonjs/shared/components/overlay/helpers/get-active-overlay.js.map +1 -1
  15. package/lib/commonjs/shared/components/overlay/helpers/retain-ready-overlay-resources.js +21 -0
  16. package/lib/commonjs/shared/components/overlay/helpers/retain-ready-overlay-resources.js.map +1 -0
  17. package/lib/commonjs/shared/components/overlay/helpers/run-overlay-slot-interpolator.js +41 -0
  18. package/lib/commonjs/shared/components/overlay/helpers/run-overlay-slot-interpolator.js.map +1 -0
  19. package/lib/commonjs/shared/components/overlay/hooks/use-overlay-slot.js +85 -0
  20. package/lib/commonjs/shared/components/overlay/hooks/use-overlay-slot.js.map +1 -0
  21. package/lib/commonjs/shared/components/overlay/variations/float-overlay.js +14 -65
  22. package/lib/commonjs/shared/components/overlay/variations/float-overlay.js.map +1 -1
  23. package/lib/commonjs/shared/components/overlay/variations/overlay-host.js +89 -16
  24. package/lib/commonjs/shared/components/overlay/variations/overlay-host.js.map +1 -1
  25. package/lib/commonjs/shared/components/screen-lifecycle/hooks/use-close-transition-intent.js +4 -1
  26. package/lib/commonjs/shared/components/screen-lifecycle/hooks/use-close-transition-intent.js.map +1 -1
  27. package/lib/commonjs/shared/providers/screen/animation/animation.provider.js +10 -7
  28. package/lib/commonjs/shared/providers/screen/animation/animation.provider.js.map +1 -1
  29. package/lib/commonjs/shared/providers/screen/animation/helpers/accessors/use-build-transition-accessor.js +6 -8
  30. package/lib/commonjs/shared/providers/screen/animation/helpers/accessors/use-build-transition-accessor.js.map +1 -1
  31. package/lib/commonjs/shared/providers/screen/animation/use-screen-animation.js +8 -2
  32. package/lib/commonjs/shared/providers/screen/animation/use-screen-animation.js.map +1 -1
  33. package/lib/commonjs/shared/providers/screen/gestures/gestures.provider.js +9 -5
  34. package/lib/commonjs/shared/providers/screen/gestures/gestures.provider.js.map +1 -1
  35. package/lib/commonjs/shared/providers/screen/gestures/hooks/use-screen-gesture-config.js +1 -3
  36. package/lib/commonjs/shared/providers/screen/gestures/hooks/use-screen-gesture-config.js.map +1 -1
  37. package/lib/commonjs/shared/providers/screen/gestures/ownership/{use-walk-up-and-register-shadowing-claims.js → gesture-ownership-bridge.js} +36 -50
  38. package/lib/commonjs/shared/providers/screen/gestures/ownership/gesture-ownership-bridge.js.map +1 -0
  39. package/lib/commonjs/shared/providers/screen/styles/constants.js +1 -0
  40. package/lib/commonjs/shared/providers/screen/styles/constants.js.map +1 -1
  41. package/lib/commonjs/shared/providers/screen/styles/helpers/transition-visual-state.js +20 -1
  42. package/lib/commonjs/shared/providers/screen/styles/helpers/transition-visual-state.js.map +1 -1
  43. package/lib/commonjs/shared/providers/screen/styles/hooks/slot-resolvers.js +14 -15
  44. package/lib/commonjs/shared/providers/screen/styles/hooks/slot-resolvers.js.map +1 -1
  45. package/lib/commonjs/shared/providers/screen/styles/hooks/use-interpolated-style-maps.js +34 -11
  46. package/lib/commonjs/shared/providers/screen/styles/hooks/use-interpolated-style-maps.js.map +1 -1
  47. package/lib/commonjs/shared/providers/screen/styles/slot.provider.js +18 -29
  48. package/lib/commonjs/shared/providers/screen/styles/slot.provider.js.map +1 -1
  49. package/lib/commonjs/shared/providers/stack/blank-stack-state/helpers/resolve-presented-index.js +18 -0
  50. package/lib/commonjs/shared/providers/stack/blank-stack-state/helpers/resolve-presented-index.js.map +1 -0
  51. package/lib/commonjs/shared/providers/stack/blank-stack.provider.js +2 -1
  52. package/lib/commonjs/shared/providers/stack/blank-stack.provider.js.map +1 -1
  53. package/lib/commonjs/shared/utils/create-provider.js +119 -10
  54. package/lib/commonjs/shared/utils/create-provider.js.map +1 -1
  55. package/lib/module/blank-stack/components/stack-view.js +1 -2
  56. package/lib/module/blank-stack/components/stack-view.js.map +1 -1
  57. package/lib/module/component-stack/components/stack-view.js +1 -2
  58. package/lib/module/component-stack/components/stack-view.js.map +1 -1
  59. package/lib/module/native-stack/views/NativeStackView.native.js +2 -3
  60. package/lib/module/native-stack/views/NativeStackView.native.js.map +1 -1
  61. package/lib/module/shared/adapters/with-screen-transitions/stack-layout.js +1 -1
  62. package/lib/module/shared/adapters/with-screen-transitions/stack-layout.js.map +1 -1
  63. package/lib/module/shared/components/boundary/portal/components/boundary-content-portal/hooks/use-boundary-content-portal-attachment.js +7 -4
  64. package/lib/module/shared/components/boundary/portal/components/boundary-content-portal/hooks/use-boundary-content-portal-attachment.js.map +1 -1
  65. package/lib/module/shared/components/overlay/helpers/create-overlay-interpolator-frame.js +25 -0
  66. package/lib/module/shared/components/overlay/helpers/create-overlay-interpolator-frame.js.map +1 -0
  67. package/lib/module/shared/components/overlay/helpers/get-active-overlay.js +37 -21
  68. package/lib/module/shared/components/overlay/helpers/get-active-overlay.js.map +1 -1
  69. package/lib/module/shared/components/overlay/helpers/retain-ready-overlay-resources.js +17 -0
  70. package/lib/module/shared/components/overlay/helpers/retain-ready-overlay-resources.js.map +1 -0
  71. package/lib/module/shared/components/overlay/helpers/run-overlay-slot-interpolator.js +36 -0
  72. package/lib/module/shared/components/overlay/helpers/run-overlay-slot-interpolator.js.map +1 -0
  73. package/lib/module/shared/components/overlay/hooks/use-overlay-slot.js +80 -0
  74. package/lib/module/shared/components/overlay/hooks/use-overlay-slot.js.map +1 -0
  75. package/lib/module/shared/components/overlay/variations/float-overlay.js +15 -66
  76. package/lib/module/shared/components/overlay/variations/float-overlay.js.map +1 -1
  77. package/lib/module/shared/components/overlay/variations/overlay-host.js +90 -18
  78. package/lib/module/shared/components/overlay/variations/overlay-host.js.map +1 -1
  79. package/lib/module/shared/components/screen-lifecycle/hooks/use-close-transition-intent.js +4 -1
  80. package/lib/module/shared/components/screen-lifecycle/hooks/use-close-transition-intent.js.map +1 -1
  81. package/lib/module/shared/providers/screen/animation/animation.provider.js +10 -7
  82. package/lib/module/shared/providers/screen/animation/animation.provider.js.map +1 -1
  83. package/lib/module/shared/providers/screen/animation/helpers/accessors/use-build-transition-accessor.js +6 -8
  84. package/lib/module/shared/providers/screen/animation/helpers/accessors/use-build-transition-accessor.js.map +1 -1
  85. package/lib/module/shared/providers/screen/animation/use-screen-animation.js +8 -2
  86. package/lib/module/shared/providers/screen/animation/use-screen-animation.js.map +1 -1
  87. package/lib/module/shared/providers/screen/gestures/gestures.provider.js +10 -6
  88. package/lib/module/shared/providers/screen/gestures/gestures.provider.js.map +1 -1
  89. package/lib/module/shared/providers/screen/gestures/hooks/use-screen-gesture-config.js +1 -3
  90. package/lib/module/shared/providers/screen/gestures/hooks/use-screen-gesture-config.js.map +1 -1
  91. package/lib/module/shared/providers/screen/gestures/ownership/{use-walk-up-and-register-shadowing-claims.js → gesture-ownership-bridge.js} +35 -49
  92. package/lib/module/shared/providers/screen/gestures/ownership/gesture-ownership-bridge.js.map +1 -0
  93. package/lib/module/shared/providers/screen/styles/constants.js +1 -0
  94. package/lib/module/shared/providers/screen/styles/constants.js.map +1 -1
  95. package/lib/module/shared/providers/screen/styles/helpers/transition-visual-state.js +18 -0
  96. package/lib/module/shared/providers/screen/styles/helpers/transition-visual-state.js.map +1 -1
  97. package/lib/module/shared/providers/screen/styles/hooks/slot-resolvers.js +14 -15
  98. package/lib/module/shared/providers/screen/styles/hooks/slot-resolvers.js.map +1 -1
  99. package/lib/module/shared/providers/screen/styles/hooks/use-interpolated-style-maps.js +35 -12
  100. package/lib/module/shared/providers/screen/styles/hooks/use-interpolated-style-maps.js.map +1 -1
  101. package/lib/module/shared/providers/screen/styles/slot.provider.js +19 -30
  102. package/lib/module/shared/providers/screen/styles/slot.provider.js.map +1 -1
  103. package/lib/module/shared/providers/stack/blank-stack-state/helpers/resolve-presented-index.js +14 -0
  104. package/lib/module/shared/providers/stack/blank-stack-state/helpers/resolve-presented-index.js.map +1 -0
  105. package/lib/module/shared/providers/stack/blank-stack.provider.js +2 -1
  106. package/lib/module/shared/providers/stack/blank-stack.provider.js.map +1 -1
  107. package/lib/module/shared/types/animation.types.js.map +1 -1
  108. package/lib/module/shared/utils/create-provider.js +119 -10
  109. package/lib/module/shared/utils/create-provider.js.map +1 -1
  110. package/lib/typescript/blank-stack/components/stack-view.d.ts.map +1 -1
  111. package/lib/typescript/blank-stack/types.d.ts +1 -1
  112. package/lib/typescript/blank-stack/types.d.ts.map +1 -1
  113. package/lib/typescript/component-stack/components/stack-view.d.ts.map +1 -1
  114. package/lib/typescript/component-stack/types.d.ts +1 -1
  115. package/lib/typescript/component-stack/types.d.ts.map +1 -1
  116. package/lib/typescript/native-stack/types.d.ts +1 -1
  117. package/lib/typescript/native-stack/types.d.ts.map +1 -1
  118. package/lib/typescript/native-stack/views/NativeStackView.native.d.ts.map +1 -1
  119. package/lib/typescript/shared/components/boundary/portal/components/boundary-content-portal/hooks/use-boundary-content-portal-attachment.d.ts.map +1 -1
  120. package/lib/typescript/shared/components/overlay/helpers/create-overlay-interpolator-frame.d.ts +7 -0
  121. package/lib/typescript/shared/components/overlay/helpers/create-overlay-interpolator-frame.d.ts.map +1 -0
  122. package/lib/typescript/shared/components/overlay/helpers/get-active-overlay.d.ts +17 -7
  123. package/lib/typescript/shared/components/overlay/helpers/get-active-overlay.d.ts.map +1 -1
  124. package/lib/typescript/shared/components/overlay/helpers/retain-ready-overlay-resources.d.ts +11 -0
  125. package/lib/typescript/shared/components/overlay/helpers/retain-ready-overlay-resources.d.ts.map +1 -0
  126. package/lib/typescript/shared/components/overlay/helpers/run-overlay-slot-interpolator.d.ts +8 -0
  127. package/lib/typescript/shared/components/overlay/helpers/run-overlay-slot-interpolator.d.ts.map +1 -0
  128. package/lib/typescript/shared/components/overlay/hooks/use-overlay-slot.d.ts +15 -0
  129. package/lib/typescript/shared/components/overlay/hooks/use-overlay-slot.d.ts.map +1 -0
  130. package/lib/typescript/shared/components/overlay/variations/float-overlay.d.ts +1 -1
  131. package/lib/typescript/shared/components/overlay/variations/float-overlay.d.ts.map +1 -1
  132. package/lib/typescript/shared/components/overlay/variations/overlay-host.d.ts +7 -6
  133. package/lib/typescript/shared/components/overlay/variations/overlay-host.d.ts.map +1 -1
  134. package/lib/typescript/shared/components/screen-lifecycle/hooks/use-close-transition-intent.d.ts.map +1 -1
  135. package/lib/typescript/shared/index.d.ts +12 -12
  136. package/lib/typescript/shared/index.d.ts.map +1 -1
  137. package/lib/typescript/shared/providers/screen/animation/animation.provider.d.ts +4 -0
  138. package/lib/typescript/shared/providers/screen/animation/animation.provider.d.ts.map +1 -1
  139. package/lib/typescript/shared/providers/screen/animation/helpers/accessors/use-build-transition-accessor.d.ts +4 -1
  140. package/lib/typescript/shared/providers/screen/animation/helpers/accessors/use-build-transition-accessor.d.ts.map +1 -1
  141. package/lib/typescript/shared/providers/screen/animation/use-screen-animation.d.ts.map +1 -1
  142. package/lib/typescript/shared/providers/screen/gestures/gestures.provider.d.ts.map +1 -1
  143. package/lib/typescript/shared/providers/screen/gestures/hooks/use-screen-gesture-config.d.ts +2 -2
  144. package/lib/typescript/shared/providers/screen/gestures/hooks/use-screen-gesture-config.d.ts.map +1 -1
  145. package/lib/typescript/shared/providers/screen/gestures/ownership/gesture-ownership-bridge.d.ts +3 -0
  146. package/lib/typescript/shared/providers/screen/gestures/ownership/gesture-ownership-bridge.d.ts.map +1 -0
  147. package/lib/typescript/shared/providers/screen/styles/constants.d.ts.map +1 -1
  148. package/lib/typescript/shared/providers/screen/styles/helpers/transition-visual-state.d.ts +7 -0
  149. package/lib/typescript/shared/providers/screen/styles/helpers/transition-visual-state.d.ts.map +1 -1
  150. package/lib/typescript/shared/providers/screen/styles/hooks/slot-resolvers.d.ts.map +1 -1
  151. package/lib/typescript/shared/providers/screen/styles/hooks/use-interpolated-style-maps.d.ts +1 -1
  152. package/lib/typescript/shared/providers/screen/styles/hooks/use-interpolated-style-maps.d.ts.map +1 -1
  153. package/lib/typescript/shared/providers/screen/styles/slot.provider.d.ts +5 -5
  154. package/lib/typescript/shared/providers/screen/styles/slot.provider.d.ts.map +1 -1
  155. package/lib/typescript/shared/providers/stack/blank-stack-state/helpers/resolve-presented-index.d.ts +3 -0
  156. package/lib/typescript/shared/providers/stack/blank-stack-state/helpers/resolve-presented-index.d.ts.map +1 -0
  157. package/lib/typescript/shared/providers/stack/blank-stack.provider.d.ts.map +1 -1
  158. package/lib/typescript/shared/types/animation.types.d.ts +8 -0
  159. package/lib/typescript/shared/types/animation.types.d.ts.map +1 -1
  160. package/lib/typescript/shared/types/index.d.ts +1 -1
  161. package/lib/typescript/shared/types/index.d.ts.map +1 -1
  162. package/lib/typescript/shared/types/overlay.types.d.ts +26 -11
  163. package/lib/typescript/shared/types/overlay.types.d.ts.map +1 -1
  164. package/lib/typescript/shared/types/screen.types.d.ts +2 -2
  165. package/lib/typescript/shared/types/screen.types.d.ts.map +1 -1
  166. package/lib/typescript/shared/utils/create-provider.d.ts +21 -6
  167. package/lib/typescript/shared/utils/create-provider.d.ts.map +1 -1
  168. package/package.json +1 -1
  169. package/src/blank-stack/components/stack-view.tsx +1 -4
  170. package/src/blank-stack/types.ts +8 -2
  171. package/src/component-stack/components/stack-view.tsx +1 -4
  172. package/src/component-stack/types.ts +8 -2
  173. package/src/native-stack/types.ts +8 -2
  174. package/src/native-stack/views/NativeStackView.native.tsx +3 -9
  175. package/src/shared/adapters/with-screen-transitions/stack-layout.tsx +1 -1
  176. package/src/shared/components/boundary/portal/components/boundary-content-portal/hooks/use-boundary-content-portal-attachment.ts +9 -4
  177. package/src/shared/components/overlay/helpers/create-overlay-interpolator-frame.ts +29 -0
  178. package/src/shared/components/overlay/helpers/get-active-overlay.ts +62 -20
  179. package/src/shared/components/overlay/helpers/retain-ready-overlay-resources.ts +38 -0
  180. package/src/shared/components/overlay/helpers/run-overlay-slot-interpolator.ts +48 -0
  181. package/src/shared/components/overlay/hooks/use-overlay-slot.ts +103 -0
  182. package/src/shared/components/overlay/variations/float-overlay.tsx +22 -64
  183. package/src/shared/components/overlay/variations/overlay-host.tsx +135 -28
  184. package/src/shared/components/screen-lifecycle/hooks/use-close-transition-intent.ts +5 -1
  185. package/src/shared/index.ts +1 -0
  186. package/src/shared/providers/screen/animation/animation.provider.tsx +24 -11
  187. package/src/shared/providers/screen/animation/helpers/accessors/use-build-transition-accessor.ts +15 -9
  188. package/src/shared/providers/screen/animation/use-screen-animation.tsx +12 -2
  189. package/src/shared/providers/screen/gestures/gestures.provider.tsx +18 -7
  190. package/src/shared/providers/screen/gestures/hooks/use-screen-gesture-config.ts +4 -4
  191. package/src/shared/providers/screen/gestures/ownership/{use-walk-up-and-register-shadowing-claims.ts → gesture-ownership-bridge.tsx} +44 -54
  192. package/src/shared/providers/screen/styles/constants.ts +1 -0
  193. package/src/shared/providers/screen/styles/helpers/transition-visual-state.ts +26 -0
  194. package/src/shared/providers/screen/styles/hooks/slot-resolvers.tsx +17 -5
  195. package/src/shared/providers/screen/styles/hooks/use-interpolated-style-maps.tsx +51 -12
  196. package/src/shared/providers/screen/styles/slot.provider.tsx +46 -70
  197. package/src/shared/providers/stack/blank-stack-state/helpers/resolve-presented-index.ts +22 -0
  198. package/src/shared/providers/stack/blank-stack.provider.tsx +6 -1
  199. package/src/shared/types/animation.types.ts +8 -0
  200. package/src/shared/types/index.ts +1 -1
  201. package/src/shared/types/overlay.types.ts +41 -14
  202. package/src/shared/types/screen.types.ts +2 -2
  203. package/src/shared/utils/create-provider.tsx +221 -19
  204. package/lib/commonjs/shared/providers/screen/gestures/ownership/use-walk-up-and-register-shadowing-claims.js.map +0 -1
  205. package/lib/commonjs/shared/providers/screen/styles/components/floating-overlay-layer.js +0 -28
  206. package/lib/commonjs/shared/providers/screen/styles/components/floating-overlay-layer.js.map +0 -1
  207. package/lib/commonjs/shared/providers/screen/styles/stores/slot-references.store.js +0 -53
  208. package/lib/commonjs/shared/providers/screen/styles/stores/slot-references.store.js.map +0 -1
  209. package/lib/module/shared/providers/screen/gestures/ownership/use-walk-up-and-register-shadowing-claims.js.map +0 -1
  210. package/lib/module/shared/providers/screen/styles/components/floating-overlay-layer.js +0 -24
  211. package/lib/module/shared/providers/screen/styles/components/floating-overlay-layer.js.map +0 -1
  212. package/lib/module/shared/providers/screen/styles/stores/slot-references.store.js +0 -47
  213. package/lib/module/shared/providers/screen/styles/stores/slot-references.store.js.map +0 -1
  214. package/lib/typescript/shared/providers/screen/gestures/ownership/use-walk-up-and-register-shadowing-claims.d.ts +0 -14
  215. package/lib/typescript/shared/providers/screen/gestures/ownership/use-walk-up-and-register-shadowing-claims.d.ts.map +0 -1
  216. package/lib/typescript/shared/providers/screen/styles/components/floating-overlay-layer.d.ts +0 -7
  217. package/lib/typescript/shared/providers/screen/styles/components/floating-overlay-layer.d.ts.map +0 -1
  218. package/lib/typescript/shared/providers/screen/styles/stores/slot-references.store.d.ts +0 -6
  219. package/lib/typescript/shared/providers/screen/styles/stores/slot-references.store.d.ts.map +0 -1
  220. package/src/shared/providers/screen/styles/components/floating-overlay-layer.tsx +0 -29
  221. package/src/shared/providers/screen/styles/stores/slot-references.store.ts +0 -72
@@ -2,53 +2,160 @@ import {
2
2
  NavigationContext,
3
3
  NavigationRouteContext,
4
4
  } from "@react-navigation/native";
5
- import { memo, useMemo } from "react";
6
- import { Animated, StyleSheet, View } from "react-native";
7
- import { useDerivedValue } from "react-native-reanimated";
8
- import type { StackScene } from "../../../hooks/navigation/use-stack";
9
- import { useScreenAnimation } from "../../../providers/screen/animation";
10
- import type { BaseDescriptor } from "../../../providers/screen/descriptors";
5
+ import { memo, useMemo, useRef } from "react";
6
+ import { StyleSheet, View } from "react-native";
7
+ import Animated, { useDerivedValue } from "react-native-reanimated";
8
+ import { snapDescriptorToIndex } from "../../../animation/snap-to";
9
+ import { useStack } from "../../../hooks/navigation/use-stack";
10
+ import { useScreenAnimationStore } from "../../../providers/screen/animation";
11
+ import type { ScreenAnimationContextValue } from "../../../providers/screen/animation/animation.provider";
12
+ import {
13
+ type ScreenSlotContextValue,
14
+ useScreenSlots,
15
+ } from "../../../providers/screen/styles/slot.provider";
16
+ import type { OverlayProps } from "../../../types/overlay.types";
11
17
  import type {
12
- OverlayProps,
13
- OverlayScreenState,
14
- } from "../../../types/overlay.types";
18
+ FloatOverlayActivity,
19
+ FloatOverlayEntry,
20
+ } from "../helpers/get-active-overlay";
21
+ import {
22
+ type ReadyOverlayResources,
23
+ retainReadyOverlayResources,
24
+ } from "../helpers/retain-ready-overlay-resources";
25
+ import { useOverlaySlot } from "../hooks/use-overlay-slot";
15
26
 
16
27
  type OverlayHostProps = {
17
- scene: StackScene;
18
- overlayScreenState: OverlayScreenState<BaseDescriptor["navigation"]>;
28
+ scene: FloatOverlayEntry["scene"];
29
+ driverScene: FloatOverlayEntry["scene"];
30
+ previousOverlayScene?: FloatOverlayEntry["scene"];
31
+ activity: FloatOverlayActivity;
32
+ layerIndex: number;
19
33
  };
20
34
 
21
35
  export const OverlayHost = memo(function OverlayHost({
22
36
  scene,
23
- overlayScreenState,
37
+ driverScene,
38
+ previousOverlayScene,
39
+ activity,
40
+ layerIndex,
24
41
  }: OverlayHostProps) {
25
- const OverlayComponent = scene.descriptor.options.overlay;
42
+ const overlayAnimationStore = useScreenAnimationStore(scene.route.key);
43
+ const driverAnimationStore = useScreenAnimationStore(driverScene.route.key);
44
+ const previousOverlayAnimationStore = useScreenAnimationStore(
45
+ previousOverlayScene?.route.key ?? scene.route.key,
46
+ );
47
+ const driverSlots = useScreenSlots(driverScene.route.key);
48
+ const overlayComponentRef = useRef(scene.descriptor.options.overlay);
49
+ const OverlayComponent = overlayComponentRef.current;
50
+ const readyResourcesRef = useRef<ReadyOverlayResources | null>(null);
51
+ readyResourcesRef.current = retainReadyOverlayResources(
52
+ readyResourcesRef.current,
53
+ overlayAnimationStore,
54
+ driverScene,
55
+ driverAnimationStore,
56
+ driverSlots,
57
+ );
58
+ const readyResources = readyResourcesRef.current;
59
+
60
+ if (!OverlayComponent || !readyResources) {
61
+ return null;
62
+ }
63
+
64
+ return (
65
+ <ReadyOverlayHost
66
+ scene={scene}
67
+ driverScene={readyResources.driverScene}
68
+ activity={activity}
69
+ layerIndex={layerIndex}
70
+ overlayAnimationStore={readyResources.overlayAnimationStore}
71
+ driverAnimationStore={readyResources.driverAnimationStore}
72
+ previousOverlayAnimationStore={
73
+ previousOverlayScene ? previousOverlayAnimationStore : undefined
74
+ }
75
+ driverSlots={readyResources.driverSlots}
76
+ OverlayComponent={OverlayComponent}
77
+ />
78
+ );
79
+ });
80
+
81
+ type ReadyOverlayHostProps = OverlayHostProps & {
82
+ overlayAnimationStore: ScreenAnimationContextValue;
83
+ driverAnimationStore: ScreenAnimationContextValue;
84
+ previousOverlayAnimationStore?: ScreenAnimationContextValue | null;
85
+ driverSlots: ScreenSlotContextValue;
86
+ OverlayComponent: NonNullable<
87
+ FloatOverlayEntry["scene"]["descriptor"]["options"]["overlay"]
88
+ >;
89
+ };
26
90
 
27
- const screenAnimation = useScreenAnimation();
91
+ function ReadyOverlayHost({
92
+ scene,
93
+ driverScene,
94
+ activity,
95
+ layerIndex,
96
+ overlayAnimationStore,
97
+ driverAnimationStore,
98
+ previousOverlayAnimationStore,
99
+ driverSlots,
100
+ OverlayComponent,
101
+ }: ReadyOverlayHostProps) {
102
+ const { scenes, focusedIndex, routeKeys, routes } = useStack();
103
+ const descriptor = scene.descriptor;
104
+ const focusedScene = scenes[focusedIndex] ?? scenes[scenes.length - 1];
105
+ const focusedDescriptor = focusedScene?.descriptor;
106
+ const { animatedProps, animatedStyle } = useOverlaySlot({
107
+ overlayAnimationStore,
108
+ driverAnimationStore,
109
+ previousOverlayAnimationStore: previousOverlayAnimationStore ?? undefined,
110
+ driverInterpolator: driverScene.descriptor.options.screenStyleInterpolator,
111
+ interpolatorReady: driverSlots.interpolatorReady,
112
+ isIncoming: scene.route.key === driverScene.route.key,
113
+ });
28
114
  const relativeProgress = useDerivedValue(() => {
29
115
  "worklet";
30
- return screenAnimation.get().stackProgress;
116
+ overlayAnimationStore.screenInterpolatorPropsRevision.get();
117
+ return overlayAnimationStore.screenInterpolatorProps.get().stackProgress;
31
118
  });
32
119
 
33
- const overlayProps: OverlayProps<BaseDescriptor["navigation"]> = useMemo(
120
+ const overlayProps: OverlayProps = useMemo(
34
121
  () => ({
35
- ...overlayScreenState,
122
+ route: scene.route,
123
+ index: routeKeys.indexOf(scene.route.key),
124
+ options: focusedDescriptor?.options ?? {},
125
+ routes,
126
+ focusedRoute: focusedScene?.route ?? scene.route,
127
+ focusedIndex,
128
+ meta: focusedDescriptor?.options?.meta,
129
+ navigation: scene.descriptor.navigation,
130
+ snapTo: (index: number) => {
131
+ snapDescriptorToIndex(scene.descriptor, index);
132
+ },
36
133
  progress: relativeProgress,
37
134
  }),
38
- [relativeProgress, overlayScreenState],
135
+ [
136
+ scene,
137
+ focusedDescriptor?.options,
138
+ focusedIndex,
139
+ focusedScene?.route,
140
+ relativeProgress,
141
+ routeKeys,
142
+ routes,
143
+ ],
39
144
  );
40
-
41
- if (!OverlayComponent) {
42
- return null;
43
- }
44
-
45
145
  return (
46
146
  <Animated.View
47
- pointerEvents="box-none"
48
- style={[styles.container, styles.floating, StyleSheet.absoluteFill]}
147
+ animatedProps={animatedProps}
148
+ pointerEvents={activity === "active" ? "box-none" : "none"}
149
+ style={[
150
+ styles.container,
151
+ styles.floating,
152
+ StyleSheet.absoluteFill,
153
+ { zIndex: 1000 + layerIndex },
154
+ animatedStyle,
155
+ ]}
49
156
  >
50
- <NavigationContext.Provider value={scene.descriptor.navigation as any}>
51
- <NavigationRouteContext.Provider value={scene.route}>
157
+ <NavigationContext.Provider value={descriptor.navigation as any}>
158
+ <NavigationRouteContext.Provider value={descriptor.route}>
52
159
  <View
53
160
  pointerEvents="box-none"
54
161
  style={[StyleSheet.absoluteFill, styles.overlay]}
@@ -59,7 +166,7 @@ export const OverlayHost = memo(function OverlayHost({
59
166
  </NavigationContext.Provider>
60
167
  </Animated.View>
61
168
  );
62
- });
169
+ }
63
170
 
64
171
  const styles = StyleSheet.create({
65
172
  overlay: {
@@ -105,8 +105,12 @@ export function useCloseTransitionIntent(current: BaseDescriptor): {
105
105
 
106
106
  // biome-ignore lint/correctness/useExhaustiveDependencies: navigation listener should only rebind when the navigator instance changes
107
107
  useLayoutEffect(() => {
108
+ if (stackType !== StackType.NATIVE) {
109
+ return;
110
+ }
111
+
108
112
  return current.navigation.addListener?.("beforeRemove", handleBeforeRemove);
109
- }, [current.navigation]);
113
+ }, [current.navigation, stackType]);
110
114
 
111
115
  return { completeClose };
112
116
  }
@@ -71,6 +71,7 @@ export type {
71
71
  BoundsNavigationZoomStyle,
72
72
  GestureHandoffValues,
73
73
  InactiveBehavior,
74
+ OverlayComponent,
74
75
  OverlayProps,
75
76
  RawGestureValues,
76
77
  ScreenBackdropComponent,
@@ -2,6 +2,7 @@ import { type ReactNode, useCallback, useLayoutEffect, useMemo } from "react";
2
2
  import { useSharedValue } from "react-native-reanimated";
3
3
  import { createBoundsAccessor } from "../../../utils/bounds";
4
4
  import createProvider from "../../../utils/create-provider";
5
+ import { useDescriptorsStore } from "../descriptors";
5
6
  import { useScreenAnimationPipeline } from "./helpers/pipeline";
6
7
  import type {
7
8
  RegisterScreenAnimationDescendant,
@@ -25,25 +26,36 @@ export type ScreenAnimationContextValue = ReturnType<
25
26
  };
26
27
 
27
28
  export type ScreenAnimationContextResult = {
29
+ key: string;
28
30
  value: ScreenAnimationContextValue;
29
31
  };
30
32
 
31
33
  export const { ScreenAnimationProvider, useScreenAnimationStore } =
32
34
  createProvider("ScreenAnimation", {
33
35
  guarded: true,
36
+ global: true,
34
37
  })<Props, ScreenAnimationContextValue>(
35
38
  (_props, { useParentStore }): ScreenAnimationContextResult => {
36
- const parentContext = useParentStore();
37
- const parentScreenInterpolatorProps =
38
- parentContext?.screenInterpolatorProps;
39
- const parentScreenInterpolatorPropsRevision =
40
- parentContext?.screenInterpolatorPropsRevision;
41
- const parentAncestorScreenAnimationSources =
42
- parentContext?.ancestorScreenAnimationSources;
43
- const parentRegisterDescendantScreenAnimationSource =
44
- parentContext?.registerDescendantScreenAnimationSource;
45
- const parentAncestorDescendantScreenAnimationRegistrars =
46
- parentContext?.ancestorDescendantScreenAnimationRegistrars;
39
+ const currentScreenKey = useDescriptorsStore(
40
+ (store) => store.derivations.currentScreenKey,
41
+ );
42
+ const parentScreenInterpolatorProps = useParentStore(
43
+ (parentContext) => parentContext?.screenInterpolatorProps,
44
+ );
45
+ const parentScreenInterpolatorPropsRevision = useParentStore(
46
+ (parentContext) => parentContext?.screenInterpolatorPropsRevision,
47
+ );
48
+ const parentAncestorScreenAnimationSources = useParentStore(
49
+ (parentContext) => parentContext?.ancestorScreenAnimationSources,
50
+ );
51
+ const parentRegisterDescendantScreenAnimationSource = useParentStore(
52
+ (parentContext) =>
53
+ parentContext?.registerDescendantScreenAnimationSource,
54
+ );
55
+ const parentAncestorDescendantScreenAnimationRegistrars = useParentStore(
56
+ (parentContext) =>
57
+ parentContext?.ancestorDescendantScreenAnimationRegistrars,
58
+ );
47
59
 
48
60
  const {
49
61
  screenInterpolatorProps,
@@ -192,6 +204,7 @@ export const { ScreenAnimationProvider, useScreenAnimationStore } =
192
204
  ]);
193
205
 
194
206
  return {
207
+ key: currentScreenKey,
195
208
  value: {
196
209
  screenInterpolatorProps,
197
210
  screenInterpolatorPropsRevision,
@@ -4,7 +4,7 @@ import type {
4
4
  ScreenTransitionTarget,
5
5
  } from "../../../../../types/animation.types";
6
6
  import { createBoundsAccessor } from "../../../../../utils/bounds";
7
- import { useScreenAnimationStore } from "../../animation.provider";
7
+ import type { ScreenAnimationContextValue } from "../../animation.provider";
8
8
  import type {
9
9
  ScreenAnimationDescendantSources,
10
10
  ScreenAnimationSource,
@@ -15,6 +15,14 @@ type TransitionSourceIndex = number;
15
15
 
16
16
  export type TransitionAccessorSource = ScreenAnimationTransitionSource;
17
17
 
18
+ type TransitionAccessorStore = Pick<
19
+ ScreenAnimationContextValue,
20
+ | "screenInterpolatorProps"
21
+ | "screenInterpolatorPropsRevision"
22
+ | "ancestorScreenAnimationSources"
23
+ | "descendantScreenAnimationSources"
24
+ >;
25
+
18
26
  const resolveTargetIndex = (
19
27
  target: ScreenTransitionTarget | undefined,
20
28
  currentIndex: TransitionSourceIndex,
@@ -118,14 +126,12 @@ const buildSourceBoundsAccessor = (source: ScreenAnimationSource) => {
118
126
  });
119
127
  };
120
128
 
121
- export const useBuildTransitionAccessor = () => {
122
- const {
123
- screenInterpolatorProps,
124
- screenInterpolatorPropsRevision,
125
- ancestorScreenAnimationSources,
126
- descendantScreenAnimationSources,
127
- } = useScreenAnimationStore();
128
-
129
+ export const useBuildTransitionAccessor = ({
130
+ screenInterpolatorProps,
131
+ screenInterpolatorPropsRevision,
132
+ ancestorScreenAnimationSources,
133
+ descendantScreenAnimationSources,
134
+ }: TransitionAccessorStore) => {
129
135
  return useMemo(() => {
130
136
  const selfSource = {
131
137
  screenInterpolatorProps,
@@ -1,3 +1,4 @@
1
+ import { useRoute } from "@react-navigation/native";
1
2
  import { type DerivedValue, useDerivedValue } from "react-native-reanimated";
2
3
  import type {
3
4
  ScreenInterpolationProps,
@@ -33,12 +34,21 @@ export function useScreenAnimation(
33
34
  ):
34
35
  | DerivedValue<ScreenInterpolationProps>
35
36
  | DerivedValue<ScreenInterpolationProps | null> {
37
+ const route = useRoute();
38
+ const screenAnimationStore = useScreenAnimationStore(route.key);
39
+
40
+ if (!screenAnimationStore) {
41
+ throw new Error(
42
+ `ScreenAnimation store for route "${route.key}" was not found`,
43
+ );
44
+ }
45
+
36
46
  const {
37
47
  screenInterpolatorPropsRevision,
38
48
  ancestorScreenAnimationSources,
39
49
  descendantScreenAnimationSources,
40
- } = useScreenAnimationStore();
41
- const transition = useBuildTransitionAccessor();
50
+ } = screenAnimationStore;
51
+ const transition = useBuildTransitionAccessor(screenAnimationStore);
42
52
  const transitionTarget = normalizeScreenAnimationTarget(
43
53
  target,
44
54
  ancestorScreenAnimationSources.length,
@@ -1,11 +1,11 @@
1
- import { useMemo } from "react";
1
+ import { Fragment, useMemo } from "react";
2
2
  import { Gesture } from "react-native-gesture-handler";
3
3
  import { useSharedValue } from "react-native-reanimated";
4
4
  import { ScrollStore } from "../../../stores/scroll.store";
5
5
  import createProvider from "../../../utils/create-provider";
6
6
  import { useDescriptorsStore } from "../descriptors";
7
7
  import { useScreenGestureConfig } from "./hooks/use-screen-gesture-config";
8
- import { useWalkUpAndRegisterShadowingClaims } from "./ownership/use-walk-up-and-register-shadowing-claims";
8
+ import { GestureOwnershipBridge } from "./ownership/gesture-ownership-bridge";
9
9
  import { useBuildPanGesture } from "./pan/use-build-pan-gesture";
10
10
  import { useBuildPinchGesture } from "./pinch/use-build-pinch-gesture";
11
11
  import {
@@ -28,11 +28,16 @@ export const { ScreenGestureProvider, useScreenGestureStore: useGestureStore } =
28
28
  { children },
29
29
  { useParentStore },
30
30
  ): { value: GestureContextType; children: React.ReactNode } => {
31
- const gestureContext = useParentStore();
32
- const gestureConfig = useScreenGestureConfig();
33
31
  const currentScreenKey = useDescriptorsStore(
34
32
  (store) => store.derivations.currentScreenKey,
35
33
  );
34
+ const isTopMostScreen = useDescriptorsStore(
35
+ (store) => store.derivations.isTopMostScreen,
36
+ );
37
+ const gestureContext = useParentStore((parentContext) =>
38
+ isTopMostScreen ? parentContext : null,
39
+ );
40
+ const gestureConfig = useScreenGestureConfig(gestureContext);
36
41
 
37
42
  const scrollState = ScrollStore.getValue(
38
43
  currentScreenKey,
@@ -89,13 +94,19 @@ export const { ScreenGestureProvider, useScreenGestureStore: useGestureStore } =
89
94
  ],
90
95
  );
91
96
 
92
- useWalkUpAndRegisterShadowingClaims(
93
- gestureConfig.participation.claimedDirections,
97
+ const content = useMemo(
98
+ () => (
99
+ <Fragment>
100
+ <GestureOwnershipBridge />
101
+ {children}
102
+ </Fragment>
103
+ ),
104
+ [children],
94
105
  );
95
106
 
96
107
  return {
97
108
  value,
98
- children,
109
+ children: content,
99
110
  };
100
111
  },
101
112
  );
@@ -1,12 +1,12 @@
1
1
  import { usePreventRemoveContext } from "@react-navigation/native";
2
2
  import { useMemo } from "react";
3
3
  import { useDescriptorsStore } from "../../descriptors";
4
- import { useGestureStore } from "../gestures.provider";
5
4
  import { resolveScreenGestureConfig } from "../shared/policy";
6
- import type { ScreenGestureConfig } from "../types";
5
+ import type { GestureContextType, ScreenGestureConfig } from "../types";
7
6
 
8
- export function useScreenGestureConfig(): ScreenGestureConfig {
9
- const gestureContext = useGestureStore();
7
+ export function useScreenGestureConfig(
8
+ gestureContext: GestureContextType | null,
9
+ ): ScreenGestureConfig {
10
10
  const options = useDescriptorsStore((store) => store.options);
11
11
  const isFirstKey = useDescriptorsStore(
12
12
  (store) => store.derivations.isFirstKey,
@@ -30,9 +30,9 @@ const findShadowedDirections = (
30
30
  ) => {
31
31
  const shadowedDirections: Direction[] = [];
32
32
 
33
- for (const dir of DIRECTIONS) {
34
- if (claimedDirections[dir] && ancestorDirections[dir]) {
35
- shadowedDirections.push(dir);
33
+ for (const direction of DIRECTIONS) {
34
+ if (claimedDirections[direction] && ancestorDirections[direction]) {
35
+ shadowedDirections.push(direction);
36
36
  }
37
37
  }
38
38
 
@@ -70,8 +70,8 @@ const registerShadowingClaims = (
70
70
 
71
71
  for (const { ancestor, directions } of shadowedAncestors) {
72
72
  const newClaims = { ...ancestor.childDirectionClaims.get() };
73
- for (const dir of directions) {
74
- newClaims[dir] = { routeKey: currentScreenKey, isDismissing };
73
+ for (const direction of directions) {
74
+ newClaims[direction] = { routeKey: currentScreenKey, isDismissing };
75
75
  }
76
76
  ancestor.childDirectionClaims.set(newClaims);
77
77
  }
@@ -86,10 +86,9 @@ const clearShadowingClaims = (
86
86
  const newClaims = { ...currentClaims };
87
87
  let needsUpdate = false;
88
88
 
89
- for (const dir of directions) {
90
- // Only remove claims written by this screen; a newer descendant may own it now.
91
- if (currentClaims[dir]?.routeKey === currentScreenKey) {
92
- newClaims[dir] = null;
89
+ for (const direction of directions) {
90
+ if (currentClaims[direction]?.routeKey === currentScreenKey) {
91
+ newClaims[direction] = null;
93
92
  needsUpdate = true;
94
93
  }
95
94
  }
@@ -121,51 +120,32 @@ const getDescriptorClaimedDirections = (
121
120
  }).participation.claimedDirections;
122
121
  };
123
122
 
124
- /**
125
- * Registers this screen with ancestors that claim the same direction.
126
- *
127
- * Example, when C is top-most:
128
- * A claims vertical
129
- * └─ B claims horizontal
130
- * └─ C claims vertical
131
- *
132
- * C walks up the tree and writes itself into A.childDirectionClaims.vertical.
133
- * B is skipped because it does not claim vertical.
134
- */
135
- export function useWalkUpAndRegisterShadowingClaims(
136
- claimedDirections: ClaimedDirections,
137
- ): void {
138
- const parentContext = useGestureStore();
123
+ const requireGestureContext = (
124
+ gestureContext: GestureContextType | null,
125
+ ): GestureContextType => {
126
+ if (!gestureContext) {
127
+ throw new Error(
128
+ "GestureOwnershipBridge must be rendered within a ScreenGestureProvider",
129
+ );
130
+ }
131
+
132
+ return gestureContext;
133
+ };
134
+
135
+ function ActiveGestureOwnershipBridge() {
136
+ const gestureContext = requireGestureContext(useGestureStore());
139
137
  const previous = useDescriptorsStore((store) => store.previous);
140
- const isTopMostScreen = useDescriptorsStore(
141
- (store) => store.derivations.isTopMostScreen,
142
- );
143
- const currentScreenKey = useDescriptorsStore(
144
- (store) => store.derivations.currentScreenKey,
145
- );
146
138
  const isCurrentScreenClosing = useBlankStackStore(
147
- (store) => store?.scenesByKey[currentScreenKey]?.activity === "closing",
139
+ (store) =>
140
+ store?.scenesByKey[gestureContext.routeKey]?.activity === "closing",
148
141
  );
149
-
150
- /*
151
- * We want to calculate effective claimed directions as claimedDirections is not enough for us.
152
- * What this solves is lingering claimed directions when a screen is closing.
153
- *
154
- * Overlay claims horizontal
155
- * └─ A has no local horizontal claim
156
- * └─ B claims horizontal (closing)
157
- * └─ C claims horizontal (closing)
158
- *
159
- * Closing screens are still mounted, so they can still block parent gestures.
160
- * But they cannot receive touches anymore.
161
- *
162
- * So when B/C are closing and the user is really touching A, B/C should not
163
- * keep blocking the parent with their own gesture config.
164
- *
165
- * A closing screen should act like the visible screen underneath it:
166
- * - if the screen underneath claims the gesture, keep blocking the parent
167
- * - if the screen underneath does not claim it, let the parent handle it
168
- */
142
+ const {
143
+ claimedDirections,
144
+ gestureContext: parentContext,
145
+ routeKey: currentScreenKey,
146
+ } = gestureContext;
147
+ // A retained closing screen cannot receive touches, so its ownership must
148
+ // mirror the visible screen underneath instead of blocking an ancestor.
169
149
  const effectiveClaimedDirections = useMemo(
170
150
  () =>
171
151
  resolveShadowingClaimDirections({
@@ -178,14 +158,13 @@ export function useWalkUpAndRegisterShadowingClaims(
178
158
  }),
179
159
  [isCurrentScreenClosing, claimedDirections, previous, parentContext],
180
160
  );
181
-
182
161
  const shadowedAncestors = useMemo(
183
162
  () => findShadowedAncestors(parentContext, effectiveClaimedDirections),
184
163
  [parentContext, effectiveClaimedDirections],
185
164
  );
186
165
 
187
166
  useLayoutEffect(() => {
188
- if (!isTopMostScreen || !shadowedAncestors.length) {
167
+ if (!shadowedAncestors.length) {
189
168
  return;
190
169
  }
191
170
 
@@ -194,5 +173,16 @@ export function useWalkUpAndRegisterShadowingClaims(
194
173
  return () => {
195
174
  clearShadowingClaims(shadowedAncestors, currentScreenKey);
196
175
  };
197
- }, [shadowedAncestors, currentScreenKey, isTopMostScreen]);
176
+ }, [shadowedAncestors, currentScreenKey]);
177
+
178
+ return null;
179
+ }
180
+
181
+ /** Keeps gesture ownership subscriptions attached only to participating screens. */
182
+ export function GestureOwnershipBridge() {
183
+ const isTopMostScreen = useDescriptorsStore(
184
+ (store) => store.derivations.isTopMostScreen,
185
+ );
186
+
187
+ return isTopMostScreen ? <ActiveGestureOwnershipBridge /> : null;
198
188
  }
@@ -65,6 +65,7 @@ export const PROP_RESET_VALUES: Record<string, unknown> = {
65
65
  };
66
66
 
67
67
  const RESERVED_STYLE_SLOT_IDS = {
68
+ overlay: true,
68
69
  content: true,
69
70
  backdrop: true,
70
71
  surface: true,
@@ -42,3 +42,29 @@ export const hasCloseTransitionFinished = ({
42
42
  "worklet";
43
43
  return !!closing && animationProgress === 0;
44
44
  };
45
+
46
+ export const isScreenInterpolatorReady = ({
47
+ hasInterpolator,
48
+ opening,
49
+ closing,
50
+ pendingLifecycleStartBlockCount,
51
+ animationProgress,
52
+ }: {
53
+ hasInterpolator: boolean;
54
+ opening: boolean;
55
+ closing: number;
56
+ pendingLifecycleStartBlockCount: number;
57
+ animationProgress: number;
58
+ }) => {
59
+ "worklet";
60
+
61
+ return (
62
+ hasInterpolator &&
63
+ !isOpenTransitionBlocked({
64
+ opening,
65
+ pendingLifecycleStartBlockCount,
66
+ animationProgress,
67
+ }) &&
68
+ !hasCloseTransitionFinished({ closing, animationProgress })
69
+ );
70
+ };