react-native-screen-transitions 4.0.0-alpha.9 → 4.0.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 (225) hide show
  1. package/README.md +5 -10
  2. package/lib/commonjs/components/boundary/portal/components/boundary-content-portal/helpers/active-handoff-receiver.js +53 -1
  3. package/lib/commonjs/components/boundary/portal/components/boundary-content-portal/helpers/active-handoff-receiver.js.map +1 -1
  4. package/lib/commonjs/components/boundary/portal/components/boundary-content-portal/hooks/use-boundary-content-portal-attachment.js +43 -8
  5. package/lib/commonjs/components/boundary/portal/components/boundary-content-portal/hooks/use-boundary-content-portal-attachment.js.map +1 -1
  6. package/lib/commonjs/components/boundary/portal/components/boundary-portal/hooks/use-boundary-portal-attachment.js +2 -3
  7. package/lib/commonjs/components/boundary/portal/components/boundary-portal/hooks/use-boundary-portal-attachment.js.map +1 -1
  8. package/lib/commonjs/components/boundary/utils/source-signals.js +6 -4
  9. package/lib/commonjs/components/boundary/utils/source-signals.js.map +1 -1
  10. package/lib/commonjs/components/overlay/helpers/get-active-overlay.js +3 -24
  11. package/lib/commonjs/components/overlay/helpers/get-active-overlay.js.map +1 -1
  12. package/lib/commonjs/components/overlay/helpers/retain-ready-overlay-resources.js +4 -3
  13. package/lib/commonjs/components/overlay/helpers/retain-ready-overlay-resources.js.map +1 -1
  14. package/lib/commonjs/components/overlay/hooks/use-overlay-slot.js +1 -2
  15. package/lib/commonjs/components/overlay/hooks/use-overlay-slot.js.map +1 -1
  16. package/lib/commonjs/components/overlay/variations/float-overlay.js +0 -2
  17. package/lib/commonjs/components/overlay/variations/float-overlay.js.map +1 -1
  18. package/lib/commonjs/components/overlay/variations/overlay-host.js +18 -15
  19. package/lib/commonjs/components/overlay/variations/overlay-host.js.map +1 -1
  20. package/lib/commonjs/components/screen-container/layers/content.js +10 -5
  21. package/lib/commonjs/components/screen-container/layers/content.js.map +1 -1
  22. package/lib/commonjs/components/screen-container/layers/surface.js +50 -0
  23. package/lib/commonjs/components/screen-container/layers/surface.js.map +1 -0
  24. package/lib/commonjs/components/stack-view.js +7 -29
  25. package/lib/commonjs/components/stack-view.js.map +1 -1
  26. package/lib/commonjs/configs/index.js +1 -4
  27. package/lib/commonjs/configs/index.js.map +1 -1
  28. package/lib/commonjs/configs/presets.js +1 -384
  29. package/lib/commonjs/configs/presets.js.map +1 -1
  30. package/lib/commonjs/navigators/create-blank-stack-navigator.js +7 -67
  31. package/lib/commonjs/navigators/create-blank-stack-navigator.js.map +1 -1
  32. package/lib/commonjs/navigators/expo-router/index.js +1 -18
  33. package/lib/commonjs/navigators/expo-router/index.js.map +1 -1
  34. package/lib/commonjs/navigators/react-navigation/index.js +1 -3
  35. package/lib/commonjs/navigators/react-navigation/index.js.map +1 -1
  36. package/lib/commonjs/providers/screen/animation/animation.provider.js +6 -1
  37. package/lib/commonjs/providers/screen/animation/animation.provider.js.map +1 -1
  38. package/lib/commonjs/providers/screen/animation/use-screen-animation.js +1 -8
  39. package/lib/commonjs/providers/screen/animation/use-screen-animation.js.map +1 -1
  40. package/lib/commonjs/providers/screen/styles/constants.js +4 -0
  41. package/lib/commonjs/providers/screen/styles/constants.js.map +1 -1
  42. package/lib/commonjs/providers/screen/styles/hooks/slot-resolvers.js +1 -9
  43. package/lib/commonjs/providers/screen/styles/hooks/slot-resolvers.js.map +1 -1
  44. package/lib/commonjs/providers/screen/styles/slot.provider.js +3 -1
  45. package/lib/commonjs/providers/screen/styles/slot.provider.js.map +1 -1
  46. package/lib/commonjs/providers/stack/blank-stack-state/helpers/build-blank-stack-state.js +10 -4
  47. package/lib/commonjs/providers/stack/blank-stack-state/helpers/build-blank-stack-state.js.map +1 -1
  48. package/lib/commonjs/providers/stack/blank-stack-state/helpers/derive-blank-stack-state.js +4 -3
  49. package/lib/commonjs/providers/stack/blank-stack-state/helpers/derive-blank-stack-state.js.map +1 -1
  50. package/lib/commonjs/providers/stack/blank-stack-state/helpers/reconcile-blank-stack-routes.js.map +1 -1
  51. package/lib/commonjs/providers/stack/blank-stack-state/helpers/state-equality.js +9 -2
  52. package/lib/commonjs/providers/stack/blank-stack-state/helpers/state-equality.js.map +1 -1
  53. package/lib/commonjs/utils/create-provider.js +14 -3
  54. package/lib/commonjs/utils/create-provider.js.map +1 -1
  55. package/lib/module/components/boundary/portal/components/boundary-content-portal/helpers/active-handoff-receiver.js +50 -0
  56. package/lib/module/components/boundary/portal/components/boundary-content-portal/helpers/active-handoff-receiver.js.map +1 -1
  57. package/lib/module/components/boundary/portal/components/boundary-content-portal/hooks/use-boundary-content-portal-attachment.js +44 -9
  58. package/lib/module/components/boundary/portal/components/boundary-content-portal/hooks/use-boundary-content-portal-attachment.js.map +1 -1
  59. package/lib/module/components/boundary/portal/components/boundary-portal/hooks/use-boundary-portal-attachment.js +2 -3
  60. package/lib/module/components/boundary/portal/components/boundary-portal/hooks/use-boundary-portal-attachment.js.map +1 -1
  61. package/lib/module/components/boundary/utils/source-signals.js +6 -4
  62. package/lib/module/components/boundary/utils/source-signals.js.map +1 -1
  63. package/lib/module/components/overlay/helpers/get-active-overlay.js +3 -24
  64. package/lib/module/components/overlay/helpers/get-active-overlay.js.map +1 -1
  65. package/lib/module/components/overlay/helpers/retain-ready-overlay-resources.js +4 -3
  66. package/lib/module/components/overlay/helpers/retain-ready-overlay-resources.js.map +1 -1
  67. package/lib/module/components/overlay/hooks/use-overlay-slot.js +1 -2
  68. package/lib/module/components/overlay/hooks/use-overlay-slot.js.map +1 -1
  69. package/lib/module/components/overlay/variations/float-overlay.js +0 -2
  70. package/lib/module/components/overlay/variations/float-overlay.js.map +1 -1
  71. package/lib/module/components/overlay/variations/overlay-host.js +19 -16
  72. package/lib/module/components/overlay/variations/overlay-host.js.map +1 -1
  73. package/lib/module/components/screen-container/layers/content.js +10 -5
  74. package/lib/module/components/screen-container/layers/content.js.map +1 -1
  75. package/lib/module/components/screen-container/layers/surface.js +45 -0
  76. package/lib/module/components/screen-container/layers/surface.js.map +1 -0
  77. package/lib/module/components/stack-view.js +7 -29
  78. package/lib/module/components/stack-view.js.map +1 -1
  79. package/lib/module/configs/index.js +2 -5
  80. package/lib/module/configs/index.js.map +1 -1
  81. package/lib/module/configs/presets.js +0 -380
  82. package/lib/module/configs/presets.js.map +1 -1
  83. package/lib/module/navigators/create-blank-stack-navigator.js +7 -66
  84. package/lib/module/navigators/create-blank-stack-navigator.js.map +1 -1
  85. package/lib/module/navigators/expo-router/index.js +1 -18
  86. package/lib/module/navigators/expo-router/index.js.map +1 -1
  87. package/lib/module/navigators/react-navigation/index.js +1 -3
  88. package/lib/module/navigators/react-navigation/index.js.map +1 -1
  89. package/lib/module/providers/screen/animation/animation.provider.js +4 -0
  90. package/lib/module/providers/screen/animation/animation.provider.js.map +1 -1
  91. package/lib/module/providers/screen/animation/use-screen-animation.js +2 -9
  92. package/lib/module/providers/screen/animation/use-screen-animation.js.map +1 -1
  93. package/lib/module/providers/screen/styles/constants.js +4 -0
  94. package/lib/module/providers/screen/styles/constants.js.map +1 -1
  95. package/lib/module/providers/screen/styles/hooks/slot-resolvers.js +2 -10
  96. package/lib/module/providers/screen/styles/hooks/slot-resolvers.js.map +1 -1
  97. package/lib/module/providers/screen/styles/slot.provider.js +1 -0
  98. package/lib/module/providers/screen/styles/slot.provider.js.map +1 -1
  99. package/lib/module/providers/stack/blank-stack-state/helpers/build-blank-stack-state.js +11 -5
  100. package/lib/module/providers/stack/blank-stack-state/helpers/build-blank-stack-state.js.map +1 -1
  101. package/lib/module/providers/stack/blank-stack-state/helpers/derive-blank-stack-state.js +5 -4
  102. package/lib/module/providers/stack/blank-stack-state/helpers/derive-blank-stack-state.js.map +1 -1
  103. package/lib/module/providers/stack/blank-stack-state/helpers/reconcile-blank-stack-routes.js.map +1 -1
  104. package/lib/module/providers/stack/blank-stack-state/helpers/state-equality.js +7 -1
  105. package/lib/module/providers/stack/blank-stack-state/helpers/state-equality.js.map +1 -1
  106. package/lib/module/types/animation.types.js +10 -0
  107. package/lib/module/types/animation.types.js.map +1 -1
  108. package/lib/module/utils/create-provider.js +14 -3
  109. package/lib/module/utils/create-provider.js.map +1 -1
  110. package/lib/typescript/components/boundary/portal/components/boundary-content-portal/helpers/active-handoff-receiver.d.ts +20 -1
  111. package/lib/typescript/components/boundary/portal/components/boundary-content-portal/helpers/active-handoff-receiver.d.ts.map +1 -1
  112. package/lib/typescript/components/boundary/portal/components/boundary-content-portal/hooks/use-boundary-content-portal-attachment.d.ts.map +1 -1
  113. package/lib/typescript/components/boundary/portal/components/boundary-portal/hooks/use-boundary-portal-attachment.d.ts.map +1 -1
  114. package/lib/typescript/components/boundary/utils/source-signals.d.ts.map +1 -1
  115. package/lib/typescript/components/overlay/helpers/get-active-overlay.d.ts +2 -8
  116. package/lib/typescript/components/overlay/helpers/get-active-overlay.d.ts.map +1 -1
  117. package/lib/typescript/components/overlay/helpers/retain-ready-overlay-resources.d.ts +2 -1
  118. package/lib/typescript/components/overlay/helpers/retain-ready-overlay-resources.d.ts.map +1 -1
  119. package/lib/typescript/components/overlay/hooks/use-overlay-slot.d.ts.map +1 -1
  120. package/lib/typescript/components/overlay/variations/float-overlay.d.ts.map +1 -1
  121. package/lib/typescript/components/overlay/variations/overlay-host.d.ts +2 -3
  122. package/lib/typescript/components/overlay/variations/overlay-host.d.ts.map +1 -1
  123. package/lib/typescript/components/screen-container/layers/content.d.ts.map +1 -1
  124. package/lib/typescript/components/screen-container/layers/surface.d.ts +7 -0
  125. package/lib/typescript/components/screen-container/layers/surface.d.ts.map +1 -0
  126. package/lib/typescript/components/stack-view.d.ts +1 -1
  127. package/lib/typescript/components/stack-view.d.ts.map +1 -1
  128. package/lib/typescript/configs/index.d.ts +0 -9
  129. package/lib/typescript/configs/index.d.ts.map +1 -1
  130. package/lib/typescript/configs/presets.d.ts +0 -9
  131. package/lib/typescript/configs/presets.d.ts.map +1 -1
  132. package/lib/typescript/index.d.ts +1 -10
  133. package/lib/typescript/index.d.ts.map +1 -1
  134. package/lib/typescript/navigators/create-blank-stack-navigator.d.ts +2 -4
  135. package/lib/typescript/navigators/create-blank-stack-navigator.d.ts.map +1 -1
  136. package/lib/typescript/navigators/expo-router/index.d.ts +3 -3
  137. package/lib/typescript/navigators/expo-router/index.d.ts.map +1 -1
  138. package/lib/typescript/navigators/react-navigation/index.d.ts +1 -1
  139. package/lib/typescript/navigators/react-navigation/index.d.ts.map +1 -1
  140. package/lib/typescript/providers/screen/animation/animation.provider.d.ts +10 -1
  141. package/lib/typescript/providers/screen/animation/animation.provider.d.ts.map +1 -1
  142. package/lib/typescript/providers/screen/animation/use-screen-animation.d.ts.map +1 -1
  143. package/lib/typescript/providers/screen/styles/constants.d.ts.map +1 -1
  144. package/lib/typescript/providers/screen/styles/hooks/slot-resolvers.d.ts.map +1 -1
  145. package/lib/typescript/providers/screen/styles/slot.provider.d.ts +11 -2
  146. package/lib/typescript/providers/screen/styles/slot.provider.d.ts.map +1 -1
  147. package/lib/typescript/providers/stack/blank-stack-state/helpers/build-blank-stack-state.d.ts +3 -3
  148. package/lib/typescript/providers/stack/blank-stack-state/helpers/build-blank-stack-state.d.ts.map +1 -1
  149. package/lib/typescript/providers/stack/blank-stack-state/helpers/derive-blank-stack-state.d.ts.map +1 -1
  150. package/lib/typescript/providers/stack/blank-stack-state/helpers/reconcile-blank-stack-routes.d.ts +3 -2
  151. package/lib/typescript/providers/stack/blank-stack-state/helpers/reconcile-blank-stack-routes.d.ts.map +1 -1
  152. package/lib/typescript/providers/stack/blank-stack-state/helpers/state-equality.d.ts +4 -4
  153. package/lib/typescript/providers/stack/blank-stack-state/helpers/state-equality.d.ts.map +1 -1
  154. package/lib/typescript/providers/stack/blank-stack-state/helpers/types.d.ts +6 -5
  155. package/lib/typescript/providers/stack/blank-stack-state/helpers/types.d.ts.map +1 -1
  156. package/lib/typescript/providers/stack/blank-stack.provider.d.ts +3 -1
  157. package/lib/typescript/providers/stack/blank-stack.provider.d.ts.map +1 -1
  158. package/lib/typescript/types/animation.types.d.ts +15 -7
  159. package/lib/typescript/types/animation.types.d.ts.map +1 -1
  160. package/lib/typescript/types/blank-stack.types.d.ts +2 -23
  161. package/lib/typescript/types/blank-stack.types.d.ts.map +1 -1
  162. package/lib/typescript/types/index.d.ts +2 -2
  163. package/lib/typescript/types/index.d.ts.map +1 -1
  164. package/lib/typescript/types/providers/blank-stack-provider.types.d.ts +8 -6
  165. package/lib/typescript/types/providers/blank-stack-provider.types.d.ts.map +1 -1
  166. package/lib/typescript/types/screen.types.d.ts +31 -0
  167. package/lib/typescript/types/screen.types.d.ts.map +1 -1
  168. package/lib/typescript/utils/create-provider.d.ts +4 -1
  169. package/lib/typescript/utils/create-provider.d.ts.map +1 -1
  170. package/package.json +3 -8
  171. package/src/components/boundary/portal/components/boundary-content-portal/helpers/active-handoff-receiver.ts +89 -0
  172. package/src/components/boundary/portal/components/boundary-content-portal/hooks/use-boundary-content-portal-attachment.ts +97 -14
  173. package/src/components/boundary/portal/components/boundary-portal/hooks/use-boundary-portal-attachment.ts +2 -6
  174. package/src/components/boundary/utils/source-signals.ts +6 -4
  175. package/src/components/overlay/helpers/get-active-overlay.ts +4 -36
  176. package/src/components/overlay/helpers/retain-ready-overlay-resources.ts +10 -1
  177. package/src/components/overlay/hooks/use-overlay-slot.ts +1 -5
  178. package/src/components/overlay/variations/float-overlay.tsx +9 -12
  179. package/src/components/overlay/variations/overlay-host.tsx +24 -22
  180. package/src/components/screen-container/layers/content.tsx +12 -7
  181. package/src/components/screen-container/layers/surface.tsx +65 -0
  182. package/src/components/stack-view.tsx +8 -39
  183. package/src/configs/index.ts +0 -6
  184. package/src/configs/presets.ts +0 -447
  185. package/src/index.ts +3 -1
  186. package/src/navigators/create-blank-stack-navigator.tsx +16 -124
  187. package/src/navigators/expo-router/index.tsx +0 -23
  188. package/src/navigators/react-navigation/index.tsx +0 -3
  189. package/src/providers/screen/animation/animation.provider.tsx +60 -54
  190. package/src/providers/screen/animation/use-screen-animation.tsx +2 -14
  191. package/src/providers/screen/styles/constants.ts +2 -0
  192. package/src/providers/screen/styles/hooks/slot-resolvers.tsx +2 -17
  193. package/src/providers/screen/styles/slot.provider.tsx +2 -0
  194. package/src/providers/stack/blank-stack-state/helpers/build-blank-stack-state.ts +30 -12
  195. package/src/providers/stack/blank-stack-state/helpers/derive-blank-stack-state.ts +11 -3
  196. package/src/providers/stack/blank-stack-state/helpers/reconcile-blank-stack-routes.ts +2 -2
  197. package/src/providers/stack/blank-stack-state/helpers/state-equality.ts +27 -16
  198. package/src/providers/stack/blank-stack-state/helpers/types.ts +9 -4
  199. package/src/types/animation.types.ts +15 -9
  200. package/src/types/blank-stack.types.ts +1 -29
  201. package/src/types/index.ts +3 -1
  202. package/src/types/providers/blank-stack-provider.types.ts +14 -11
  203. package/src/types/screen.types.ts +36 -0
  204. package/src/utils/create-provider.tsx +22 -4
  205. package/lib/commonjs/components/boundary/portal/utils/teleport-control.js +0 -16
  206. package/lib/commonjs/components/boundary/portal/utils/teleport-control.js.map +0 -1
  207. package/lib/commonjs/providers/navigation/navigation-host.provider.js +0 -56
  208. package/lib/commonjs/providers/navigation/navigation-host.provider.js.map +0 -1
  209. package/lib/commonjs/providers/navigation/react-navigation-host.js +0 -23
  210. package/lib/commonjs/providers/navigation/react-navigation-host.js.map +0 -1
  211. package/lib/module/components/boundary/portal/utils/teleport-control.js +0 -11
  212. package/lib/module/components/boundary/portal/utils/teleport-control.js.map +0 -1
  213. package/lib/module/providers/navigation/navigation-host.provider.js +0 -50
  214. package/lib/module/providers/navigation/navigation-host.provider.js.map +0 -1
  215. package/lib/module/providers/navigation/react-navigation-host.js +0 -19
  216. package/lib/module/providers/navigation/react-navigation-host.js.map +0 -1
  217. package/lib/typescript/components/boundary/portal/utils/teleport-control.d.ts +0 -3
  218. package/lib/typescript/components/boundary/portal/utils/teleport-control.d.ts.map +0 -1
  219. package/lib/typescript/providers/navigation/navigation-host.provider.d.ts +0 -21
  220. package/lib/typescript/providers/navigation/navigation-host.provider.d.ts.map +0 -1
  221. package/lib/typescript/providers/navigation/react-navigation-host.d.ts +0 -3
  222. package/lib/typescript/providers/navigation/react-navigation-host.d.ts.map +0 -1
  223. package/src/components/boundary/portal/utils/teleport-control.ts +0 -13
  224. package/src/providers/navigation/navigation-host.provider.tsx +0 -75
  225. package/src/providers/navigation/react-navigation-host.tsx +0 -24
@@ -9,14 +9,23 @@ import { useBlankStackStore } from "../../../../../../providers/stack/blank-stac
9
9
  import { AnimationStore } from "../../../../../../stores/animation.store";
10
10
  import { getLinkKeyFromTag } from "../../../../../../stores/bounds/helpers/link-pairs.helpers";
11
11
  import { getEntry } from "../../../../../../stores/bounds/internals/entries";
12
+ import {
13
+ getPairKeyForDestination,
14
+ getPairKeyForSource,
15
+ } from "../../../../../../stores/bounds/internals/links";
12
16
  import { pairs } from "../../../../../../stores/bounds/internals/state";
17
+ import type {
18
+ LinkPairState,
19
+ TagLink,
20
+ } from "../../../../../../stores/bounds/types";
13
21
  import { SystemStore } from "../../../../../../stores/system.store";
14
22
  import { PORTAL_HOST_NAME_RESET_VALUE } from "../../../utils/naming";
15
- import { isTeleportEnabled } from "../../../utils/teleport-control";
16
23
  import {
17
24
  resolveActiveHandoffReceiver,
18
25
  resolveHandoffAttachmentCandidate,
19
26
  resolvePreviousHandoffReceiver,
27
+ resolveRequestedHandoffPairKey,
28
+ resolveRequestedHandoffReceiver,
20
29
  } from "../helpers/active-handoff-receiver";
21
30
  import { createBoundaryContentPortalHostName } from "../helpers/host-name";
22
31
 
@@ -24,6 +33,19 @@ interface UseBoundaryContentPortalAttachmentParams {
24
33
  boundaryId: string;
25
34
  }
26
35
 
36
+ const isCompleteActiveLink = (
37
+ pair: LinkPairState | null | undefined,
38
+ link: TagLink | undefined,
39
+ boundaryLinkKey: string,
40
+ ) => {
41
+ "worklet";
42
+
43
+ return (
44
+ link?.status === "complete" &&
45
+ (!link.group || pair?.groups[link.group]?.activeId === boundaryLinkKey)
46
+ );
47
+ };
48
+
27
49
  export const useBoundaryContentPortalAttachment = ({
28
50
  boundaryId,
29
51
  }: UseBoundaryContentPortalAttachmentParams) => {
@@ -34,6 +56,9 @@ export const useBoundaryContentPortalAttachment = ({
34
56
  );
35
57
  const nextScreenKey = useDescriptorsStore((s) => s.derivations.nextScreenKey);
36
58
  const sourcePairKey = useDescriptorsStore((s) => s.derivations.sourcePairKey);
59
+ const destinationPairKey = useDescriptorsStore(
60
+ (s) => s.derivations.destinationPairKey,
61
+ );
37
62
  const destinationSlots = useOptionalScreenSlotStore(
38
63
  nextScreenKey ?? currentScreenKey,
39
64
  );
@@ -67,11 +92,9 @@ export const useBoundaryContentPortalAttachment = ({
67
92
  const slot = slotsMap.get()[boundaryId];
68
93
  const {
69
94
  pointerEvents: _pointerEvents,
70
- teleport,
95
+ handoffTarget,
71
96
  ...slotProps
72
97
  } = slot?.props ?? {};
73
-
74
- const shouldTeleport = isTeleportEnabled(teleport);
75
98
  const closing = activeReceiverClosing.get();
76
99
  const animationProgress = activeReceiverAnimationProgress.get();
77
100
 
@@ -89,20 +112,65 @@ export const useBoundaryContentPortalAttachment = ({
89
112
  animationProgress,
90
113
  });
91
114
 
92
- const pair = sourcePairKey ? pairs.get()[sourcePairKey] : null;
93
- const link = pair?.links[getLinkKeyFromTag(boundaryId)];
115
+ const automaticPair = sourcePairKey ? pairs.get()[sourcePairKey] : null;
116
+ const boundaryLinkKey = getLinkKeyFromTag(boundaryId);
117
+ const automaticLink = automaticPair?.links[boundaryLinkKey];
118
+ const requestedSourcePairKey =
119
+ getPairKeyForSource(boundaryId, currentScreenKey) ?? sourcePairKey;
120
+ const requestedSourcePair = requestedSourcePairKey
121
+ ? pairs.get()[requestedSourcePairKey]
122
+ : null;
123
+ const requestedSourceLink = requestedSourcePair?.links[boundaryLinkKey];
94
124
 
95
125
  const pairDestination =
96
- link?.status === "complete" &&
97
- (!link.group ||
98
- pair?.groups[link.group]?.activeId === getLinkKeyFromTag(boundaryId))
99
- ? link.destination.screenKey
126
+ automaticLink?.status === "complete" &&
127
+ (!automaticLink.group ||
128
+ automaticPair?.groups[automaticLink.group]?.activeId ===
129
+ boundaryLinkKey)
130
+ ? automaticLink.destination.screenKey
100
131
  : null;
132
+ const requestedDestinationPairKey =
133
+ getPairKeyForDestination(boundaryId, currentScreenKey) ??
134
+ destinationPairKey;
135
+ const destinationPair = requestedDestinationPairKey
136
+ ? pairs.get()[requestedDestinationPairKey]
137
+ : null;
138
+ const destinationLink = destinationPair?.links[boundaryLinkKey];
139
+ const retainedSourcePairKey = sourcePairBeforeClose.get() ?? undefined;
140
+ const retainedSourcePair = retainedSourcePairKey
141
+ ? pairs.get()[retainedSourcePairKey]
142
+ : null;
143
+ const retainedSourceLink = retainedSourcePair?.links[boundaryLinkKey];
144
+ const requestedPairKey = resolveRequestedHandoffPairKey({
145
+ destinationPairHasCompleteLink: isCompleteActiveLink(
146
+ destinationPair,
147
+ destinationLink,
148
+ boundaryLinkKey,
149
+ ),
150
+ destinationPairKey: requestedDestinationPairKey,
151
+ handoffTarget,
152
+ retainedSourcePairHasCompleteLink: isCompleteActiveLink(
153
+ retainedSourcePair,
154
+ retainedSourceLink,
155
+ boundaryLinkKey,
156
+ ),
157
+ retainedSourcePairKey,
158
+ sourcePairHasCompleteLink: isCompleteActiveLink(
159
+ requestedSourcePair,
160
+ requestedSourceLink,
161
+ boundaryLinkKey,
162
+ ),
163
+ sourcePairKey: requestedSourcePairKey,
164
+ });
165
+ const requestedPair = requestedPairKey
166
+ ? pairs.get()[requestedPairKey]
167
+ : null;
168
+ const requestedLink = requestedPair?.links[boundaryLinkKey];
101
169
 
102
170
  const isInterpolatorReady = interpolatorReady.get();
103
171
  const attachedScreenKey = attachedReceiverScreenKey.get();
104
172
 
105
- const nextReceiverScreenKey = resolveHandoffAttachmentCandidate({
173
+ const automaticReceiverScreenKey = resolveHandoffAttachmentCandidate({
106
174
  activeReceiverClosing: !!closing,
107
175
  activeReceiverScreenKey,
108
176
  attachedReceiverScreenKey: attachedScreenKey,
@@ -110,8 +178,25 @@ export const useBoundaryContentPortalAttachment = ({
110
178
  interpolatorReady: !!isInterpolatorReady,
111
179
  pairChangedDuringClose,
112
180
  pairDestinationScreenKey: pairDestination,
181
+ pairHasBoundaryLink: automaticLink !== undefined,
113
182
  previousReceiverScreenKey,
114
183
  });
184
+ const requestedDestinationScreenKey =
185
+ requestedLink?.status === "complete"
186
+ ? requestedLink.destination.screenKey
187
+ : null;
188
+ const nextReceiverScreenKey = resolveRequestedHandoffReceiver({
189
+ automaticScreenKey: automaticReceiverScreenKey,
190
+ destinationReady:
191
+ requestedDestinationScreenKey === activeReceiverScreenKey ||
192
+ !!isInterpolatorReady,
193
+ destinationScreenKey: requestedDestinationScreenKey,
194
+ handoffTarget,
195
+ sourceScreenKey:
196
+ requestedLink?.status === "complete"
197
+ ? requestedLink.source.screenKey
198
+ : null,
199
+ });
115
200
 
116
201
  const receiverEntry = nextReceiverScreenKey
117
202
  ? getEntry(boundaryId, nextReceiverScreenKey)
@@ -136,9 +221,7 @@ export const useBoundaryContentPortalAttachment = ({
136
221
  attachedReceiverScreenKey.set(nextReceiverScreenKey);
137
222
  }
138
223
 
139
- const targetScreenKey = shouldTeleport
140
- ? attachedReceiverScreenKey.get()
141
- : null;
224
+ const targetScreenKey = attachedReceiverScreenKey.get();
142
225
 
143
226
  const targetHostName = targetScreenKey
144
227
  ? createBoundaryContentPortalHostName(targetScreenKey, boundaryId)
@@ -3,7 +3,6 @@ import { useDescriptorsStore } from "../../../../../../providers/screen/descript
3
3
  import { useScreenSlotStore } from "../../../../../../providers/screen/styles";
4
4
  import { useBoundaryRootStore } from "../../../../providers/boundary-root.provider";
5
5
  import { PORTAL_HOST_NAME_RESET_VALUE } from "../../../utils/naming";
6
- import { isTeleportEnabled } from "../../../utils/teleport-control";
7
6
  import { useActiveHostKey } from "../stores/host-registry.store";
8
7
  import { useActivePortalBoundaryHost } from "./use-active-portal-boundary-host";
9
8
 
@@ -45,14 +44,11 @@ export const useBoundaryPortalAttachment = ({
45
44
  const slot = slotsMap.get()[boundaryId];
46
45
  const {
47
46
  pointerEvents: _pointerEvents,
48
- teleport,
47
+ handoffTarget: _handoffTarget,
49
48
  ...slotProps
50
49
  } = slot?.props ?? {};
51
50
 
52
- const shouldAttach =
53
- slot !== undefined &&
54
- isTeleportEnabled(teleport) &&
55
- portalHostReady.get();
51
+ const shouldAttach = slot !== undefined && portalHostReady.get();
56
52
 
57
53
  const hostName = shouldAttach
58
54
  ? portalHostName.get()
@@ -1,3 +1,4 @@
1
+ import { getLinkKeyFromTag } from "../../../stores/bounds/helpers/link-pairs.helpers";
1
2
  import type {
2
3
  LinkPairsState,
3
4
  ScreenPairKey,
@@ -25,8 +26,9 @@ export const getInitialSourceCaptureSignal = (params: {
25
26
  }
26
27
 
27
28
  const pair = linkState?.[sourcePairKey];
28
- const link = pair?.links?.[linkId];
29
- const hasSourceRequest = pair?.sourceRequests?.[linkId];
29
+ const linkKey = getLinkKeyFromTag(linkId);
30
+ const link = pair?.links?.[linkKey];
31
+ const hasSourceRequest = pair?.sourceRequests?.[linkKey];
30
32
 
31
33
  if ((!link?.destination && !hasSourceRequest) || link?.source) {
32
34
  return null;
@@ -37,12 +39,12 @@ export const getInitialSourceCaptureSignal = (params: {
37
39
 
38
40
  // Passive grouped sources should not measure every mounted item. Once a
39
41
  // group has an active id, only that concrete member can auto-capture.
40
- if (activeId && activeId !== linkId) {
42
+ if (activeId && activeId !== linkKey) {
41
43
  return null;
42
44
  }
43
45
  }
44
46
 
45
- const signalParts = group ? [group, linkId] : [linkId];
47
+ const signalParts = group ? [group, linkKey] : [linkKey];
46
48
 
47
49
  return {
48
50
  pairKey: sourcePairKey,
@@ -4,52 +4,24 @@ type StackScene = BaseStackScene;
4
4
 
5
5
  import { isOverlayVisible } from "../../../utils/overlay/visibility";
6
6
 
7
- export type FloatOverlayActivity = "active" | "inert" | "inactive" | "closing";
8
-
9
7
  export type FloatOverlayEntry = {
10
8
  scene: StackScene;
11
9
  overlayIndex: number;
12
- activity: FloatOverlayActivity;
13
10
  };
14
11
 
15
12
  export type FloatOverlayTransitionEntry = FloatOverlayEntry & {
16
13
  driverScene: StackScene;
17
14
  };
18
15
 
19
- type OverlayCandidate = Omit<FloatOverlayEntry, "activity">;
20
-
21
- const resolveOverlayActivity = (
22
- scene: StackScene,
23
- distanceFromTop: number,
24
- ): FloatOverlayActivity => {
25
- if (distanceFromTop === 0 && scene.activity === "closing") {
26
- return "closing";
27
- }
28
-
29
- if (distanceFromTop === 0) {
30
- return "active";
31
- }
32
-
33
- if (distanceFromTop === 1) {
34
- return "inert";
35
- }
36
-
37
- return "inactive";
38
- };
39
-
40
16
  /**
41
- * Finds every visible floating-overlay checkpoint in stack order.
42
- *
43
- * The newest checkpoint owns the active overlay. Its immediate predecessor
44
- * remains visible and inert; all older checkpoints are retained but inactive.
45
- * This mirrors the screen activity window without making plain screens create
46
- * a new overlay checkpoint.
17
+ * Overlay ordering and transition coordination are library-owned. Visibility,
18
+ * interaction, and presentation are user-owned.
47
19
  */
48
20
  export function getFloatOverlayStack(
49
21
  scenes: StackScene[],
50
22
  transitionsAlwaysOn: boolean,
51
23
  ): FloatOverlayEntry[] {
52
- const candidates: OverlayCandidate[] = [];
24
+ const candidates: FloatOverlayEntry[] = [];
53
25
 
54
26
  for (let index = 0; index < scenes.length; index += 1) {
55
27
  const scene = scenes[index];
@@ -64,11 +36,7 @@ export function getFloatOverlayStack(
64
36
  }
65
37
  }
66
38
 
67
- const topIndex = candidates.length - 1;
68
- return candidates.map((candidate, index) => ({
69
- ...candidate,
70
- activity: resolveOverlayActivity(candidate.scene, topIndex - index),
71
- }));
39
+ return candidates;
72
40
  }
73
41
 
74
42
  export function getFloatOverlayTransitions(
@@ -4,6 +4,7 @@ import type { FloatOverlayEntry } from "./get-active-overlay";
4
4
 
5
5
  export type ReadyOverlayResources = {
6
6
  overlayAnimationStore: ScreenAnimationContextValue;
7
+ overlaySlots: ScreenSlotContextValue;
7
8
  driverScene: FloatOverlayEntry["scene"];
8
9
  driverAnimationStore: ScreenAnimationContextValue;
9
10
  driverSlots: ScreenSlotContextValue;
@@ -12,16 +13,23 @@ export type ReadyOverlayResources = {
12
13
  export function retainReadyOverlayResources(
13
14
  previous: ReadyOverlayResources | null,
14
15
  overlayAnimationStore: ScreenAnimationContextValue | null,
16
+ overlaySlots: ScreenSlotContextValue | null,
15
17
  driverScene: FloatOverlayEntry["scene"],
16
18
  driverAnimationStore: ScreenAnimationContextValue | null,
17
19
  driverSlots: ScreenSlotContextValue | null,
18
20
  ): ReadyOverlayResources | null {
19
- if (!overlayAnimationStore || !driverAnimationStore || !driverSlots) {
21
+ if (
22
+ !overlayAnimationStore ||
23
+ !overlaySlots ||
24
+ !driverAnimationStore ||
25
+ !driverSlots
26
+ ) {
20
27
  return previous;
21
28
  }
22
29
 
23
30
  if (
24
31
  previous?.overlayAnimationStore === overlayAnimationStore &&
32
+ previous.overlaySlots === overlaySlots &&
25
33
  previous.driverScene === driverScene &&
26
34
  previous.driverAnimationStore === driverAnimationStore &&
27
35
  previous.driverSlots === driverSlots
@@ -31,6 +39,7 @@ export function retainReadyOverlayResources(
31
39
 
32
40
  return {
33
41
  overlayAnimationStore,
42
+ overlaySlots,
34
43
  driverScene,
35
44
  driverAnimationStore,
36
45
  driverSlots,
@@ -108,11 +108,7 @@ export const useOverlaySlot = ({
108
108
  return NO_PROPS;
109
109
  }
110
110
 
111
- const {
112
- pointerEvents: _pointerEvents,
113
- teleport: _teleport,
114
- ...props
115
- } = slotProps;
111
+ const { handoffTarget: _handoffTarget, ...props } = slotProps;
116
112
 
117
113
  return props;
118
114
  });
@@ -24,16 +24,13 @@ export function FloatOverlay() {
24
24
 
25
25
  const overlayTransitions = getFloatOverlayTransitions(overlayStack, scenes);
26
26
 
27
- return overlayTransitions.map(
28
- ({ scene, activity, driverScene }, layerIndex) => (
29
- <OverlayHost
30
- key={scene.route.key}
31
- scene={scene}
32
- driverScene={driverScene}
33
- previousOverlayScene={overlayTransitions[layerIndex - 1]?.scene}
34
- activity={activity}
35
- layerIndex={layerIndex}
36
- />
37
- ),
38
- );
27
+ return overlayTransitions.map(({ scene, driverScene }, layerIndex) => (
28
+ <OverlayHost
29
+ key={scene.route.key}
30
+ scene={scene}
31
+ driverScene={driverScene}
32
+ previousOverlayScene={overlayTransitions[layerIndex - 1]?.scene}
33
+ layerIndex={layerIndex}
34
+ />
35
+ ));
39
36
  }
@@ -2,19 +2,19 @@ import { memo, useMemo, useRef } from "react";
2
2
  import { StyleSheet, View } from "react-native";
3
3
  import Animated, { useDerivedValue } from "react-native-reanimated";
4
4
  import { snapDescriptorToIndex } from "../../../animation/snap-to";
5
- import { NavigationScreenProvider } from "../../../providers/navigation/navigation-host.provider";
6
5
  import { useOptionalScreenAnimationStore } from "../../../providers/screen/animation";
7
- import type { ScreenAnimationContextValue } from "../../../providers/screen/animation/animation.provider";
6
+ import {
7
+ type ScreenAnimationContextValue,
8
+ ScreenAnimationStoreProvider,
9
+ } from "../../../providers/screen/animation/animation.provider";
8
10
  import {
9
11
  type ScreenSlotContextValue,
12
+ ScreenSlotStoreProvider,
10
13
  useOptionalScreenSlotStore,
11
14
  } from "../../../providers/screen/styles/slot.provider";
12
15
  import { useBlankStackStore } from "../../../providers/stack/blank-stack.provider";
13
16
  import type { OverlayProps } from "../../../types/overlay.types";
14
- import type {
15
- FloatOverlayActivity,
16
- FloatOverlayEntry,
17
- } from "../helpers/get-active-overlay";
17
+ import type { FloatOverlayEntry } from "../helpers/get-active-overlay";
18
18
  import {
19
19
  type ReadyOverlayResources,
20
20
  retainReadyOverlayResources,
@@ -25,7 +25,6 @@ type OverlayHostProps = {
25
25
  scene: FloatOverlayEntry["scene"];
26
26
  driverScene: FloatOverlayEntry["scene"];
27
27
  previousOverlayScene?: FloatOverlayEntry["scene"];
28
- activity: FloatOverlayActivity;
29
28
  layerIndex: number;
30
29
  };
31
30
 
@@ -33,7 +32,6 @@ export const OverlayHost = memo(function OverlayHost({
33
32
  scene,
34
33
  driverScene,
35
34
  previousOverlayScene,
36
- activity,
37
35
  layerIndex,
38
36
  }: OverlayHostProps) {
39
37
  const overlayAnimationStore = useOptionalScreenAnimationStore(
@@ -45,6 +43,7 @@ export const OverlayHost = memo(function OverlayHost({
45
43
  const previousOverlayAnimationStore = useOptionalScreenAnimationStore(
46
44
  previousOverlayScene?.route.key ?? scene.route.key,
47
45
  );
46
+ const overlaySlots = useOptionalScreenSlotStore(scene.route.key);
48
47
  const driverSlots = useOptionalScreenSlotStore(driverScene.route.key);
49
48
  const overlayComponentRef = useRef(scene.descriptor.options.overlay);
50
49
  const OverlayComponent = overlayComponentRef.current;
@@ -52,6 +51,7 @@ export const OverlayHost = memo(function OverlayHost({
52
51
  readyResourcesRef.current = retainReadyOverlayResources(
53
52
  readyResourcesRef.current,
54
53
  overlayAnimationStore,
54
+ overlaySlots,
55
55
  driverScene,
56
56
  driverAnimationStore,
57
57
  driverSlots,
@@ -66,9 +66,9 @@ export const OverlayHost = memo(function OverlayHost({
66
66
  <ReadyOverlayHost
67
67
  scene={scene}
68
68
  driverScene={readyResources.driverScene}
69
- activity={activity}
70
69
  layerIndex={layerIndex}
71
70
  overlayAnimationStore={readyResources.overlayAnimationStore}
71
+ overlaySlots={readyResources.overlaySlots}
72
72
  driverAnimationStore={readyResources.driverAnimationStore}
73
73
  previousOverlayAnimationStore={
74
74
  previousOverlayScene ? previousOverlayAnimationStore : undefined
@@ -81,6 +81,7 @@ export const OverlayHost = memo(function OverlayHost({
81
81
 
82
82
  type ReadyOverlayHostProps = OverlayHostProps & {
83
83
  overlayAnimationStore: ScreenAnimationContextValue;
84
+ overlaySlots: ScreenSlotContextValue;
84
85
  driverAnimationStore: ScreenAnimationContextValue;
85
86
  previousOverlayAnimationStore?: ScreenAnimationContextValue | null;
86
87
  driverSlots: ScreenSlotContextValue;
@@ -92,16 +93,15 @@ type ReadyOverlayHostProps = OverlayHostProps & {
92
93
  function ReadyOverlayHost({
93
94
  scene,
94
95
  driverScene,
95
- activity,
96
96
  layerIndex,
97
97
  overlayAnimationStore,
98
+ overlaySlots,
98
99
  driverAnimationStore,
99
100
  previousOverlayAnimationStore,
100
101
  driverSlots,
101
102
  OverlayComponent,
102
103
  }: ReadyOverlayHostProps) {
103
104
  const { scenes, focusedIndex, routeKeys, routes } = useBlankStackStore();
104
- const descriptor = scene.descriptor;
105
105
  const focusedScene = scenes[focusedIndex] ?? scenes[scenes.length - 1];
106
106
  const focusedDescriptor = focusedScene?.descriptor;
107
107
  const { animatedProps, animatedStyle } = useOverlaySlot({
@@ -147,7 +147,7 @@ function ReadyOverlayHost({
147
147
  return (
148
148
  <Animated.View
149
149
  animatedProps={animatedProps}
150
- pointerEvents={activity === "active" ? "box-none" : "none"}
150
+ pointerEvents="box-none"
151
151
  style={[
152
152
  styles.container,
153
153
  styles.floating,
@@ -156,17 +156,19 @@ function ReadyOverlayHost({
156
156
  animatedStyle,
157
157
  ]}
158
158
  >
159
- <NavigationScreenProvider
160
- navigation={descriptor.navigation}
161
- route={descriptor.route}
159
+ <ScreenAnimationStoreProvider
160
+ registerGlobally={false}
161
+ value={overlayAnimationStore}
162
162
  >
163
- <View
164
- pointerEvents="box-none"
165
- style={[StyleSheet.absoluteFill, styles.overlay]}
166
- >
167
- <OverlayComponent {...overlayProps} />
168
- </View>
169
- </NavigationScreenProvider>
163
+ <ScreenSlotStoreProvider registerGlobally={false} value={overlaySlots}>
164
+ <View
165
+ pointerEvents="box-none"
166
+ style={[StyleSheet.absoluteFill, styles.overlay]}
167
+ >
168
+ <OverlayComponent {...overlayProps} />
169
+ </View>
170
+ </ScreenSlotStoreProvider>
171
+ </ScreenAnimationStoreProvider>
170
172
  </Animated.View>
171
173
  );
172
174
  }
@@ -10,6 +10,7 @@ import { ScreenFallbackHost } from "../../boundary/portal/components/boundary-po
10
10
  import { useContentLayout } from "../hooks/use-content-layout";
11
11
  import { MaybeMaskedNavigationContainer } from "./maybe-masked-navigation-container";
12
12
  import { usesLayerRenderProps } from "./render-component";
13
+ import { SurfaceLayer } from "./surface";
13
14
 
14
15
  type Props = {
15
16
  children: React.ReactNode;
@@ -50,18 +51,22 @@ export const ContentLayer = memo(
50
51
  const contentProps =
51
52
  animatedContentProps as ScreenContentComponentProps["props"];
52
53
 
54
+ const screenChildren = hasAutoSnapPoint ? (
55
+ <View collapsable={false} onLayout={handleContentLayout}>
56
+ {children}
57
+ </View>
58
+ ) : (
59
+ children
60
+ );
61
+
53
62
  const contentChildren = (
54
63
  <MaybeMaskedNavigationContainer
55
64
  pointerEvents={contentPointerEvents}
56
65
  enabled={isNavigationMaskEnabled}
57
66
  >
58
- {hasAutoSnapPoint ? (
59
- <View collapsable={false} onLayout={handleContentLayout}>
60
- {children}
61
- </View>
62
- ) : (
63
- children
64
- )}
67
+ <SurfaceLayer pointerEvents={contentPointerEvents}>
68
+ {screenChildren}
69
+ </SurfaceLayer>
65
70
  <ScreenFallbackHost />
66
71
  </MaybeMaskedNavigationContainer>
67
72
  );
@@ -0,0 +1,65 @@
1
+ import { type ComponentType, memo, useMemo } from "react";
2
+ import { StyleSheet } from "react-native";
3
+ import Animated from "react-native-reanimated";
4
+ import { useDescriptorsStore } from "../../../providers/screen/descriptors";
5
+ import { useSlotProps, useSlotStyles } from "../../../providers/screen/styles";
6
+ import type { ScreenSurfaceComponentProps } from "../../../types";
7
+ import { usesLayerRenderProps } from "./render-component";
8
+
9
+ type Props = {
10
+ children: React.ReactNode;
11
+ pointerEvents: "box-none" | undefined;
12
+ };
13
+
14
+ export const SurfaceLayer = memo(({ children, pointerEvents }: Props) => {
15
+ const SurfaceComponent = useDescriptorsStore(
16
+ (store) => store.options.surfaceComponent,
17
+ );
18
+
19
+ const AnimatedSurfaceComponent = useMemo(() => {
20
+ return SurfaceComponent && !usesLayerRenderProps(SurfaceComponent)
21
+ ? Animated.createAnimatedComponent(SurfaceComponent as ComponentType<any>)
22
+ : null;
23
+ }, [SurfaceComponent]);
24
+
25
+ const animatedSurfaceStyle = useSlotStyles("surface");
26
+ const animatedSurfaceProps = useSlotProps("surface");
27
+ const surfaceStyles = [
28
+ styles.surface,
29
+ animatedSurfaceStyle,
30
+ ] as ScreenSurfaceComponentProps["styles"];
31
+ const surfaceProps =
32
+ animatedSurfaceProps as ScreenSurfaceComponentProps["props"];
33
+
34
+ if (!SurfaceComponent) {
35
+ return children;
36
+ }
37
+
38
+ if (AnimatedSurfaceComponent) {
39
+ return (
40
+ <AnimatedSurfaceComponent
41
+ style={surfaceStyles}
42
+ animatedProps={animatedSurfaceProps}
43
+ pointerEvents={pointerEvents}
44
+ >
45
+ {children}
46
+ </AnimatedSurfaceComponent>
47
+ );
48
+ }
49
+
50
+ return (
51
+ <SurfaceComponent
52
+ styles={surfaceStyles}
53
+ props={surfaceProps}
54
+ pointerEvents={pointerEvents}
55
+ >
56
+ {children}
57
+ </SurfaceComponent>
58
+ );
59
+ });
60
+
61
+ const styles = StyleSheet.create({
62
+ surface: {
63
+ flex: 1,
64
+ },
65
+ });