react-native-screen-transitions 3.4.0-alpha.6 → 3.4.0-alpha.7

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 (205) hide show
  1. package/README.md +136 -46
  2. package/lib/commonjs/blank-stack/navigators/create-blank-stack-navigator.js +27 -45
  3. package/lib/commonjs/blank-stack/navigators/create-blank-stack-navigator.js.map +1 -1
  4. package/lib/commonjs/component-stack/navigators/create-component-stack-navigator.js +1 -1
  5. package/lib/commonjs/shared/components/create-boundary-component/components/boundary-target.js +39 -0
  6. package/lib/commonjs/shared/components/create-boundary-component/components/boundary-target.js.map +1 -0
  7. package/lib/commonjs/shared/components/create-boundary-component/create-boundary-component.js +232 -0
  8. package/lib/commonjs/shared/components/create-boundary-component/create-boundary-component.js.map +1 -0
  9. package/lib/commonjs/shared/components/create-boundary-component/hooks/helpers/measurement-rules.js +2 -4
  10. package/lib/commonjs/shared/components/create-boundary-component/hooks/helpers/measurement-rules.js.map +1 -1
  11. package/lib/commonjs/shared/components/create-boundary-component/hooks/use-boundary-measure-and-store.js +4 -3
  12. package/lib/commonjs/shared/components/create-boundary-component/hooks/use-boundary-measure-and-store.js.map +1 -1
  13. package/lib/commonjs/shared/components/create-boundary-component/hooks/use-pending-destination-retry-measurement.js +2 -1
  14. package/lib/commonjs/shared/components/create-boundary-component/hooks/use-pending-destination-retry-measurement.js.map +1 -1
  15. package/lib/commonjs/shared/components/create-boundary-component/index.js +20 -214
  16. package/lib/commonjs/shared/components/create-boundary-component/index.js.map +1 -1
  17. package/lib/commonjs/shared/components/create-boundary-component/providers/boundary-owner.provider.js +63 -0
  18. package/lib/commonjs/shared/components/create-boundary-component/providers/boundary-owner.provider.js.map +1 -0
  19. package/lib/commonjs/shared/components/create-transition-aware-component.js +29 -7
  20. package/lib/commonjs/shared/components/create-transition-aware-component.js.map +1 -1
  21. package/lib/commonjs/shared/components/overlay/variations/float-overlay.js +1 -1
  22. package/lib/commonjs/shared/components/screen-container/index.js +8 -12
  23. package/lib/commonjs/shared/components/screen-container/index.js.map +1 -1
  24. package/lib/commonjs/shared/components/screen-container/layers/backdrop.js +4 -4
  25. package/lib/commonjs/shared/components/screen-container/layers/backdrop.js.map +1 -1
  26. package/lib/commonjs/shared/components/screen-container/layers/content.js +4 -4
  27. package/lib/commonjs/shared/components/screen-container/layers/content.js.map +1 -1
  28. package/lib/commonjs/shared/components/screen-container/layers/maybe-masked-navigation-container.js +4 -4
  29. package/lib/commonjs/shared/components/screen-container/layers/maybe-masked-navigation-container.js.map +1 -1
  30. package/lib/commonjs/shared/components/screen-container/layers/surface-container.js +4 -4
  31. package/lib/commonjs/shared/components/screen-container/layers/surface-container.js.map +1 -1
  32. package/lib/commonjs/shared/constants.js +2 -1
  33. package/lib/commonjs/shared/constants.js.map +1 -1
  34. package/lib/commonjs/shared/providers/screen/screen-composer.js +1 -1
  35. package/lib/commonjs/shared/providers/screen/screen-composer.js.map +1 -1
  36. package/lib/commonjs/shared/providers/screen/styles/helpers/build-resolved-style-map.js +144 -0
  37. package/lib/commonjs/shared/providers/screen/styles/helpers/build-resolved-style-map.js.map +1 -0
  38. package/lib/commonjs/shared/providers/screen/styles/helpers/resolve-interpolated-style-output.js +28 -0
  39. package/lib/commonjs/shared/providers/screen/styles/helpers/resolve-interpolated-style-output.js.map +1 -0
  40. package/lib/commonjs/shared/providers/screen/styles/helpers/split-normalized-style-maps.js +39 -0
  41. package/lib/commonjs/shared/providers/screen/styles/helpers/split-normalized-style-maps.js.map +1 -0
  42. package/lib/commonjs/shared/providers/screen/styles/index.js +25 -0
  43. package/lib/commonjs/shared/providers/screen/styles/index.js.map +1 -0
  44. package/lib/commonjs/shared/providers/screen/{styles.provider.js → styles/styles.provider.js} +47 -39
  45. package/lib/commonjs/shared/providers/screen/styles/styles.provider.js.map +1 -0
  46. package/lib/commonjs/shared/utils/bounds/helpers/compute-bounds-styles.js +1 -1
  47. package/lib/commonjs/shared/utils/bounds/helpers/compute-bounds-styles.js.map +1 -1
  48. package/lib/commonjs/shared/utils/bounds/helpers/style-composers.js +21 -10
  49. package/lib/commonjs/shared/utils/bounds/helpers/style-composers.js.map +1 -1
  50. package/lib/commonjs/shared/utils/bounds/zoom/build.js +56 -30
  51. package/lib/commonjs/shared/utils/bounds/zoom/build.js.map +1 -1
  52. package/lib/module/blank-stack/navigators/create-blank-stack-navigator.js +27 -45
  53. package/lib/module/blank-stack/navigators/create-blank-stack-navigator.js.map +1 -1
  54. package/lib/module/component-stack/navigators/create-component-stack-navigator.js +1 -1
  55. package/lib/module/shared/components/create-boundary-component/components/boundary-target.js +34 -0
  56. package/lib/module/shared/components/create-boundary-component/components/boundary-target.js.map +1 -0
  57. package/lib/module/shared/components/create-boundary-component/create-boundary-component.js +227 -0
  58. package/lib/module/shared/components/create-boundary-component/create-boundary-component.js.map +1 -0
  59. package/lib/module/shared/components/create-boundary-component/hooks/helpers/measurement-rules.js +2 -4
  60. package/lib/module/shared/components/create-boundary-component/hooks/helpers/measurement-rules.js.map +1 -1
  61. package/lib/module/shared/components/create-boundary-component/hooks/use-boundary-measure-and-store.js +4 -3
  62. package/lib/module/shared/components/create-boundary-component/hooks/use-boundary-measure-and-store.js.map +1 -1
  63. package/lib/module/shared/components/create-boundary-component/hooks/use-pending-destination-retry-measurement.js +2 -1
  64. package/lib/module/shared/components/create-boundary-component/hooks/use-pending-destination-retry-measurement.js.map +1 -1
  65. package/lib/module/shared/components/create-boundary-component/index.js +16 -213
  66. package/lib/module/shared/components/create-boundary-component/index.js.map +1 -1
  67. package/lib/module/shared/components/create-boundary-component/providers/boundary-owner.provider.js +56 -0
  68. package/lib/module/shared/components/create-boundary-component/providers/boundary-owner.provider.js.map +1 -0
  69. package/lib/module/shared/components/create-transition-aware-component.js +30 -8
  70. package/lib/module/shared/components/create-transition-aware-component.js.map +1 -1
  71. package/lib/module/shared/components/overlay/variations/float-overlay.js +1 -1
  72. package/lib/module/shared/components/overlay/variations/float-overlay.js.map +1 -1
  73. package/lib/module/shared/components/screen-container/index.js +8 -12
  74. package/lib/module/shared/components/screen-container/index.js.map +1 -1
  75. package/lib/module/shared/components/screen-container/layers/backdrop.js +4 -4
  76. package/lib/module/shared/components/screen-container/layers/backdrop.js.map +1 -1
  77. package/lib/module/shared/components/screen-container/layers/content.js +4 -4
  78. package/lib/module/shared/components/screen-container/layers/content.js.map +1 -1
  79. package/lib/module/shared/components/screen-container/layers/maybe-masked-navigation-container.js +4 -4
  80. package/lib/module/shared/components/screen-container/layers/maybe-masked-navigation-container.js.map +1 -1
  81. package/lib/module/shared/components/screen-container/layers/surface-container.js +4 -4
  82. package/lib/module/shared/components/screen-container/layers/surface-container.js.map +1 -1
  83. package/lib/module/shared/constants.js +2 -1
  84. package/lib/module/shared/constants.js.map +1 -1
  85. package/lib/module/shared/providers/screen/screen-composer.js +1 -1
  86. package/lib/module/shared/providers/screen/screen-composer.js.map +1 -1
  87. package/lib/module/shared/providers/screen/styles/helpers/build-resolved-style-map.js +139 -0
  88. package/lib/module/shared/providers/screen/styles/helpers/build-resolved-style-map.js.map +1 -0
  89. package/lib/module/shared/providers/screen/styles/helpers/resolve-interpolated-style-output.js +23 -0
  90. package/lib/module/shared/providers/screen/styles/helpers/resolve-interpolated-style-output.js.map +1 -0
  91. package/lib/module/shared/providers/screen/styles/helpers/split-normalized-style-maps.js +34 -0
  92. package/lib/module/shared/providers/screen/styles/helpers/split-normalized-style-maps.js.map +1 -0
  93. package/lib/module/shared/providers/screen/styles/index.js +4 -0
  94. package/lib/module/shared/providers/screen/styles/index.js.map +1 -0
  95. package/lib/module/shared/providers/screen/{styles.provider.js → styles/styles.provider.js} +48 -40
  96. package/lib/module/shared/providers/screen/styles/styles.provider.js.map +1 -0
  97. package/lib/module/shared/utils/bounds/helpers/compute-bounds-styles.js +2 -2
  98. package/lib/module/shared/utils/bounds/helpers/compute-bounds-styles.js.map +1 -1
  99. package/lib/module/shared/utils/bounds/helpers/style-composers.js +21 -10
  100. package/lib/module/shared/utils/bounds/helpers/style-composers.js.map +1 -1
  101. package/lib/module/shared/utils/bounds/zoom/build.js +55 -28
  102. package/lib/module/shared/utils/bounds/zoom/build.js.map +1 -1
  103. package/lib/typescript/blank-stack/navigators/create-blank-stack-navigator.d.ts +9 -15
  104. package/lib/typescript/blank-stack/navigators/create-blank-stack-navigator.d.ts.map +1 -1
  105. package/lib/typescript/blank-stack/types.d.ts +6 -4
  106. package/lib/typescript/blank-stack/types.d.ts.map +1 -1
  107. package/lib/typescript/component-stack/navigators/create-component-stack-navigator.d.ts +1 -1
  108. package/lib/typescript/shared/components/create-boundary-component/components/boundary-target.d.ts +209 -0
  109. package/lib/typescript/shared/components/create-boundary-component/components/boundary-target.d.ts.map +1 -0
  110. package/lib/typescript/shared/components/create-boundary-component/create-boundary-component.d.ts +8 -0
  111. package/lib/typescript/shared/components/create-boundary-component/create-boundary-component.d.ts.map +1 -0
  112. package/lib/typescript/shared/components/create-boundary-component/hooks/helpers/measurement-rules.d.ts.map +1 -1
  113. package/lib/typescript/shared/components/create-boundary-component/hooks/use-boundary-measure-and-store.d.ts +2 -8
  114. package/lib/typescript/shared/components/create-boundary-component/hooks/use-boundary-measure-and-store.d.ts.map +1 -1
  115. package/lib/typescript/shared/components/create-boundary-component/hooks/use-pending-destination-retry-measurement.d.ts +0 -1
  116. package/lib/typescript/shared/components/create-boundary-component/hooks/use-pending-destination-retry-measurement.d.ts.map +1 -1
  117. package/lib/typescript/shared/components/create-boundary-component/index.d.ts +216 -12
  118. package/lib/typescript/shared/components/create-boundary-component/index.d.ts.map +1 -1
  119. package/lib/typescript/shared/components/create-boundary-component/providers/boundary-owner.provider.d.ts +35 -0
  120. package/lib/typescript/shared/components/create-boundary-component/providers/boundary-owner.provider.d.ts.map +1 -0
  121. package/lib/typescript/shared/components/create-transition-aware-component.d.ts.map +1 -1
  122. package/lib/typescript/shared/components/screen-container/index.d.ts.map +1 -1
  123. package/lib/typescript/shared/components/screen-container/layers/maybe-masked-navigation-container.d.ts.map +1 -1
  124. package/lib/typescript/shared/constants.d.ts +1 -0
  125. package/lib/typescript/shared/constants.d.ts.map +1 -1
  126. package/lib/typescript/shared/index.d.ts +209 -2
  127. package/lib/typescript/shared/index.d.ts.map +1 -1
  128. package/lib/typescript/shared/providers/screen/styles/helpers/build-resolved-style-map.d.ts +11 -0
  129. package/lib/typescript/shared/providers/screen/styles/helpers/build-resolved-style-map.d.ts.map +1 -0
  130. package/lib/typescript/shared/providers/screen/styles/helpers/resolve-interpolated-style-output.d.ts +7 -0
  131. package/lib/typescript/shared/providers/screen/styles/helpers/resolve-interpolated-style-output.d.ts.map +1 -0
  132. package/lib/typescript/shared/providers/screen/styles/helpers/split-normalized-style-maps.d.ts +6 -0
  133. package/lib/typescript/shared/providers/screen/styles/helpers/split-normalized-style-maps.d.ts.map +1 -0
  134. package/lib/typescript/shared/providers/screen/styles/index.d.ts +2 -0
  135. package/lib/typescript/shared/providers/screen/styles/index.d.ts.map +1 -0
  136. package/lib/typescript/shared/providers/screen/{styles.provider.d.ts → styles/styles.provider.d.ts} +3 -5
  137. package/lib/typescript/shared/providers/screen/styles/styles.provider.d.ts.map +1 -0
  138. package/lib/typescript/shared/types/animation.types.d.ts +3 -9
  139. package/lib/typescript/shared/types/animation.types.d.ts.map +1 -1
  140. package/lib/typescript/shared/types/index.d.ts +1 -1
  141. package/lib/typescript/shared/types/index.d.ts.map +1 -1
  142. package/lib/typescript/shared/types/screen.types.d.ts +2 -4
  143. package/lib/typescript/shared/types/screen.types.d.ts.map +1 -1
  144. package/lib/typescript/shared/utils/bounds/helpers/compute-bounds-styles.d.ts +1 -11
  145. package/lib/typescript/shared/utils/bounds/helpers/compute-bounds-styles.d.ts.map +1 -1
  146. package/lib/typescript/shared/utils/bounds/helpers/style-composers.d.ts.map +1 -1
  147. package/lib/typescript/shared/utils/bounds/zoom/build.d.ts +1 -1
  148. package/lib/typescript/shared/utils/bounds/zoom/build.d.ts.map +1 -1
  149. package/package.json +1 -1
  150. package/src/blank-stack/navigators/create-blank-stack-navigator.tsx +37 -80
  151. package/src/blank-stack/types.ts +7 -4
  152. package/src/component-stack/navigators/create-component-stack-navigator.tsx +1 -1
  153. package/src/shared/components/create-boundary-component/components/boundary-target.tsx +45 -0
  154. package/src/shared/components/create-boundary-component/create-boundary-component.tsx +282 -0
  155. package/src/shared/components/create-boundary-component/hooks/helpers/measurement-rules.ts +2 -7
  156. package/src/shared/components/create-boundary-component/hooks/use-boundary-measure-and-store.ts +6 -10
  157. package/src/shared/components/create-boundary-component/hooks/use-pending-destination-retry-measurement.ts +3 -2
  158. package/src/shared/components/create-boundary-component/index.tsx +16 -252
  159. package/src/shared/components/create-boundary-component/providers/boundary-owner.provider.tsx +109 -0
  160. package/src/shared/components/create-transition-aware-component.tsx +33 -5
  161. package/src/shared/components/overlay/variations/float-overlay.tsx +1 -1
  162. package/src/shared/components/screen-container/index.tsx +10 -13
  163. package/src/shared/components/screen-container/layers/backdrop.tsx +4 -4
  164. package/src/shared/components/screen-container/layers/content.tsx +4 -4
  165. package/src/shared/components/screen-container/layers/maybe-masked-navigation-container.tsx +6 -4
  166. package/src/shared/components/screen-container/layers/surface-container.tsx +4 -4
  167. package/src/shared/constants.ts +1 -0
  168. package/src/shared/index.ts +0 -1
  169. package/src/shared/providers/screen/screen-composer.tsx +1 -1
  170. package/src/shared/providers/screen/styles/helpers/build-resolved-style-map.ts +185 -0
  171. package/src/shared/providers/screen/styles/helpers/resolve-interpolated-style-output.ts +31 -0
  172. package/src/shared/providers/screen/styles/helpers/split-normalized-style-maps.ts +44 -0
  173. package/src/shared/providers/screen/styles/index.tsx +5 -0
  174. package/src/shared/providers/screen/styles/styles.provider.tsx +173 -0
  175. package/src/shared/types/animation.types.ts +3 -10
  176. package/src/shared/types/index.ts +0 -1
  177. package/src/shared/types/screen.types.ts +2 -4
  178. package/src/shared/utils/bounds/helpers/compute-bounds-styles.ts +2 -1
  179. package/src/shared/utils/bounds/helpers/style-composers.ts +11 -0
  180. package/src/shared/utils/bounds/zoom/build.ts +85 -70
  181. package/lib/commonjs/shared/components/screen-container/deferred-visibility-host.js +0 -45
  182. package/lib/commonjs/shared/components/screen-container/deferred-visibility-host.js.map +0 -1
  183. package/lib/commonjs/shared/hooks/animation/use-associated-style.js +0 -234
  184. package/lib/commonjs/shared/hooks/animation/use-associated-style.js.map +0 -1
  185. package/lib/commonjs/shared/providers/screen/helpers/resolve-interpolated-style-output.js +0 -50
  186. package/lib/commonjs/shared/providers/screen/helpers/resolve-interpolated-style-output.js.map +0 -1
  187. package/lib/commonjs/shared/providers/screen/styles.provider.js.map +0 -1
  188. package/lib/module/shared/components/screen-container/deferred-visibility-host.js +0 -40
  189. package/lib/module/shared/components/screen-container/deferred-visibility-host.js.map +0 -1
  190. package/lib/module/shared/hooks/animation/use-associated-style.js +0 -229
  191. package/lib/module/shared/hooks/animation/use-associated-style.js.map +0 -1
  192. package/lib/module/shared/providers/screen/helpers/resolve-interpolated-style-output.js +0 -44
  193. package/lib/module/shared/providers/screen/helpers/resolve-interpolated-style-output.js.map +0 -1
  194. package/lib/module/shared/providers/screen/styles.provider.js.map +0 -1
  195. package/lib/typescript/shared/components/screen-container/deferred-visibility-host.d.ts +0 -14
  196. package/lib/typescript/shared/components/screen-container/deferred-visibility-host.d.ts.map +0 -1
  197. package/lib/typescript/shared/hooks/animation/use-associated-style.d.ts +0 -32
  198. package/lib/typescript/shared/hooks/animation/use-associated-style.d.ts.map +0 -1
  199. package/lib/typescript/shared/providers/screen/helpers/resolve-interpolated-style-output.d.ts +0 -14
  200. package/lib/typescript/shared/providers/screen/helpers/resolve-interpolated-style-output.d.ts.map +0 -1
  201. package/lib/typescript/shared/providers/screen/styles.provider.d.ts.map +0 -1
  202. package/src/shared/components/screen-container/deferred-visibility-host.tsx +0 -44
  203. package/src/shared/hooks/animation/use-associated-style.ts +0 -297
  204. package/src/shared/providers/screen/helpers/resolve-interpolated-style-output.ts +0 -61
  205. package/src/shared/providers/screen/styles.provider.tsx +0 -164
@@ -1,254 +1,15 @@
1
- import {
2
- type ComponentType,
3
- forwardRef,
4
- memo,
5
- useCallback,
6
- useMemo,
7
- } from "react";
8
- import { Pressable, View as RNView, type View } from "react-native";
9
- import Animated, { runOnUI, useAnimatedRef } from "react-native-reanimated";
10
- import { useAssociatedStyles } from "../../hooks/animation/use-associated-style";
11
- import { useLayoutAnchorContext } from "../../providers/layout-anchor.provider";
12
- import { useDescriptorDerivations } from "../../providers/screen/descriptors";
13
- import { AnimationStore } from "../../stores/animation.store";
14
- import { BoundStore } from "../../stores/bounds";
15
- import { prepareStyleForBounds } from "../../utils/bounds/helpers/styles";
16
- import { useAutoSourceMeasurement } from "./hooks/use-auto-source-measurement";
17
- import { useBoundaryMeasureAndStore } from "./hooks/use-boundary-measure-and-store";
18
- import { useBoundaryPresence } from "./hooks/use-boundary-presence";
19
- import { useGroupActiveMeasurement } from "./hooks/use-group-active-measurement";
20
- import { useGroupActiveSourceMeasurement } from "./hooks/use-group-active-source-measurement";
21
- import { useInitialLayoutHandler } from "./hooks/use-initial-layout-handler";
22
- import { usePendingDestinationMeasurement } from "./hooks/use-pending-destination-measurement";
23
- import { usePendingDestinationRetryMeasurement } from "./hooks/use-pending-destination-retry-measurement";
24
- import { useScrollSettledMeasurement } from "./hooks/use-scroll-settled-measurement";
25
- import type { BoundaryComponentProps, BoundaryConfigProps } from "./types";
26
- import { buildBoundaryMatchKey } from "./utils/build-boundary-match-key";
1
+ import { View } from "react-native";
2
+ import { Pressable } from "react-native-gesture-handler";
3
+ import { BoundaryTarget } from "./components/boundary-target";
4
+ import { createBoundaryComponent } from "./create-boundary-component";
27
5
 
28
- const setGroupSelectionOnUI = (group: string, id: string) => {
29
- "worklet";
30
- BoundStore.setGroupActiveId(group, id);
31
- };
32
-
33
- interface CreateBoundaryComponentOptions {
34
- alreadyAnimated?: boolean;
35
- }
36
-
37
- export function createBoundaryComponent<P extends object>(
38
- Wrapped: ComponentType<P>,
39
- options: CreateBoundaryComponentOptions = {},
40
- ) {
41
- const { alreadyAnimated = false } = options;
42
- const AnimatedComponent = alreadyAnimated
43
- ? Wrapped
44
- : Animated.createAnimatedComponent(Wrapped);
45
-
46
- const Inner = forwardRef<
47
- React.ComponentRef<typeof AnimatedComponent>,
48
- BoundaryComponentProps<P>
49
- >((props, _ref) => {
50
- const {
51
- enabled = true,
52
- group,
53
- id,
54
- anchor,
55
- scaleMode,
56
- target,
57
- method,
58
- style,
59
- onPress,
60
- ...rest
61
- } = props as any;
62
-
63
- const sharedBoundTag = buildBoundaryMatchKey({ group, id });
64
- const animatedRef = useAnimatedRef<View>();
65
-
66
- const {
67
- previousScreenKey: preferredSourceScreenKey,
68
- currentScreenKey,
69
- nextScreenKey,
70
- ancestorKeys,
71
- navigatorKey,
72
- ancestorNavigatorKeys,
73
- hasConfiguredInterpolator,
74
- } = useDescriptorDerivations();
75
- const runtimeEnabled = enabled && hasConfiguredInterpolator;
76
- const hasNextScreen = !!nextScreenKey;
77
- const shouldUpdateDestination = !hasNextScreen;
78
- const layoutAnchor = useLayoutAnchorContext();
79
- const boundaryConfig = useMemo<BoundaryConfigProps | undefined>(() => {
80
- if (
81
- anchor === undefined &&
82
- scaleMode === undefined &&
83
- target === undefined &&
84
- method === undefined
85
- ) {
86
- return undefined;
87
- }
88
-
89
- return {
90
- anchor,
91
- scaleMode,
92
- target,
93
- method,
94
- };
95
- }, [anchor, scaleMode, target, method]);
96
-
97
- const isAnimating = AnimationStore.getValue(currentScreenKey, "animating");
98
- const progress = AnimationStore.getValue(currentScreenKey, "progress");
99
-
100
- const preparedStyles = useMemo(() => prepareStyleForBounds(style), [style]);
101
-
102
- const { associatedStyles } = useAssociatedStyles({
103
- id: sharedBoundTag,
104
- resetTransformOnUnset: true,
105
- });
106
-
107
- const maybeMeasureAndStore = useBoundaryMeasureAndStore({
108
- enabled,
109
- sharedBoundTag,
110
- preferredSourceScreenKey,
111
- currentScreenKey,
112
- ancestorKeys,
113
- navigatorKey,
114
- ancestorNavigatorKeys,
115
- isAnimating,
116
- preparedStyles,
117
- animatedRef,
118
- layoutAnchor,
119
- });
120
-
121
- const shouldRunDestinationEffects = runtimeEnabled && !hasNextScreen;
122
-
123
- // Register/unregister this boundary in the presence map so source/destination
124
- // matching can resolve across screens (including ancestor relationships).
125
- useBoundaryPresence({
126
- enabled: runtimeEnabled,
127
- sharedBoundTag,
128
- currentScreenKey,
129
- ancestorKeys,
130
- navigatorKey,
131
- ancestorNavigatorKeys,
132
- boundaryConfig,
133
- });
6
+ export { createBoundaryComponent };
134
7
 
135
- // On the source screen, capture source bounds when a matching destination
136
- // appears on the next screen.
137
- useAutoSourceMeasurement({
138
- enabled: runtimeEnabled,
139
- sharedBoundTag,
140
- nextScreenKey,
141
- maybeMeasureAndStore,
142
- });
143
-
144
- // Primary destination capture: once a pending source link exists for this tag,
145
- // measure destination bounds and complete the pair.
146
- usePendingDestinationMeasurement({
147
- sharedBoundTag,
148
- enabled: shouldRunDestinationEffects,
149
- expectedSourceScreenKey: preferredSourceScreenKey,
150
- maybeMeasureAndStore,
151
- });
152
-
153
- // Reliability fallback: retry destination capture during transition progress
154
- // when the initial pending-destination attempt happens before layout is ready.
155
- usePendingDestinationRetryMeasurement({
156
- sharedBoundTag,
157
- enabled: shouldRunDestinationEffects,
158
- currentScreenKey,
159
- expectedSourceScreenKey: preferredSourceScreenKey,
160
- progress,
161
- animating: isAnimating,
162
- maybeMeasureAndStore,
163
- });
164
-
165
- // Grouped boundaries (e.g. paged/detail UIs): re-measure when this boundary
166
- // becomes the active member so destination bounds stay accurate.
167
- useGroupActiveMeasurement({
168
- enabled: runtimeEnabled,
169
- group,
170
- id,
171
- currentScreenKey,
172
- shouldUpdateDestination,
173
- maybeMeasureAndStore,
174
- });
175
-
176
- // Source-side grouped retargeting: when an unfocused/source boundary
177
- // becomes the active member, refresh its snapshot and source link so
178
- // close transitions do not use stale pre-scroll geometry.
179
- useGroupActiveSourceMeasurement({
180
- enabled: runtimeEnabled,
181
- group,
182
- id,
183
- hasNextScreen,
184
- isAnimating,
185
- maybeMeasureAndStore,
186
- });
187
-
188
- // While idle on source screens, re-measure after scroll settles so a later
189
- // close transition starts from up-to-date source geometry.
190
- useScrollSettledMeasurement({
191
- enabled: runtimeEnabled,
192
- group,
193
- hasNextScreen,
194
- isAnimating,
195
- maybeMeasureAndStore,
196
- });
197
-
198
- // Destination mount-time capture path: onLayout schedules a one-time UI-thread
199
- // initial measurement when transitions are active.
200
- useInitialLayoutHandler({
201
- enabled: runtimeEnabled,
202
- sharedBoundTag,
203
- currentScreenKey,
204
- ancestorKeys,
205
- expectedSourceScreenKey: preferredSourceScreenKey,
206
- maybeMeasureAndStore,
207
- });
208
-
209
- const handlePress = useCallback(
210
- (...args: unknown[]) => {
211
- // Press path has priority: capture source before user onPress/navigation.
212
- if (group) {
213
- runOnUI(setGroupSelectionOnUI)(group, String(id));
214
- }
215
- runOnUI(maybeMeasureAndStore)({ intent: "capture-source" });
216
-
217
- if (typeof onPress === "function") {
218
- onPress(...args);
219
- }
220
- },
221
- [group, id, maybeMeasureAndStore, onPress],
222
- );
223
-
224
- const resolvedOnPress =
225
- typeof onPress === "function" ? handlePress : undefined;
226
-
227
- return (
228
- <AnimatedComponent
229
- {...(rest as any)}
230
- ref={animatedRef}
231
- style={[style, enabled ? associatedStyles : undefined]}
232
- onPress={resolvedOnPress}
233
- collapsable={false}
234
- />
235
- );
236
- });
237
-
238
- return memo(Inner) as unknown as React.MemoExoticComponent<
239
- React.ForwardRefExoticComponent<
240
- BoundaryComponentProps<P> &
241
- React.RefAttributes<React.ComponentRef<typeof Wrapped>>
242
- >
243
- >;
244
- }
245
-
246
- // Pre-built boundary component variants
247
- const BoundaryView = createBoundaryComponent(RNView);
8
+ const BoundaryView = createBoundaryComponent(View);
9
+ const BoundaryTrigger = createBoundaryComponent(Pressable);
248
10
  BoundaryView.displayName = "Transition.Boundary.View";
249
-
250
- const BoundaryPressable = createBoundaryComponent(Pressable);
251
- BoundaryPressable.displayName = "Transition.Boundary.Pressable";
11
+ BoundaryTrigger.displayName = "Transition.Boundary.Trigger";
12
+ BoundaryTarget.displayName = "Transition.Boundary.Target";
252
13
 
253
14
  /**
254
15
  * Shared-boundary components.
@@ -258,18 +19,21 @@ BoundaryPressable.displayName = "Transition.Boundary.Pressable";
258
19
  * 2. Destination screen captures bounds for the same tag.
259
20
  * 3. The link is updated as layout changes (group-active + scroll-settled paths).
260
21
  *
261
- * Press behavior:
262
- * - When a boundary has `onPress` (typically `Boundary.Pressable`), source
22
+ * Trigger behavior:
23
+ * - When a boundary has `onPress` (typically `Boundary.Trigger`), source
263
24
  * measurement runs before the user callback. This gives navigation transitions
264
25
  * fresh source geometry on the first frame.
265
26
  *
266
27
  * Use:
267
28
  * - `Boundary.View` for passive/shared elements.
268
- * - `Boundary.Pressable` for tappable elements that start navigation.
29
+ * - `Boundary.Trigger` for tappable elements that start navigation.
30
+ * - `Boundary.Target` to measure a nested descendant instead of the owner.
269
31
  */
270
32
  export const Boundary = {
271
33
  /** Passive boundary wrapper (no built-in press semantics). */
272
34
  View: BoundaryView,
273
35
  /** Pressable boundary wrapper with press-priority source capture. */
274
- Pressable: BoundaryPressable,
36
+ Trigger: BoundaryTrigger,
37
+ /** Optional nested measurement override inside a boundary owner. */
38
+ Target: BoundaryTarget,
275
39
  };
@@ -0,0 +1,109 @@
1
+ import type React from "react";
2
+ import {
3
+ createContext,
4
+ type ReactNode,
5
+ useCallback,
6
+ useContext,
7
+ useMemo,
8
+ useRef,
9
+ useState,
10
+ } from "react";
11
+ import type { View } from "react-native";
12
+ import type Animated from "react-native-reanimated";
13
+ import type { AnimatedRef } from "react-native-reanimated";
14
+
15
+ type BoundaryAssociatedStyle = React.ComponentProps<
16
+ typeof Animated.View
17
+ >["style"];
18
+
19
+ interface BoundaryOwnerContextValue {
20
+ ownerRef: AnimatedRef<View>;
21
+ registerTargetRef: (targetRef: AnimatedRef<View>) => void;
22
+ unregisterTargetRef: (targetRef: AnimatedRef<View>) => void;
23
+ activeTargetRef: AnimatedRef<View> | null;
24
+ associatedTargetStyles?: BoundaryAssociatedStyle;
25
+ }
26
+
27
+ const BoundaryOwnerContext = createContext<BoundaryOwnerContextValue | null>(
28
+ null,
29
+ );
30
+
31
+ const MULTIPLE_TARGETS_WARNING =
32
+ "[react-native-screen-transitions] Multiple Boundary.Target elements were rendered under the same boundary owner. The first registered target will be measured.";
33
+
34
+ export const TARGET_OUTSIDE_OWNER_WARNING =
35
+ "[react-native-screen-transitions] Boundary.Target must be rendered inside a Boundary owner (Boundary.View, Boundary.Trigger, or a component created by createBoundaryComponent).";
36
+
37
+ export const BoundaryOwnerProvider = (props: {
38
+ value: BoundaryOwnerContextValue;
39
+ children: ReactNode;
40
+ }) => {
41
+ const { value, children } = props;
42
+
43
+ return (
44
+ <BoundaryOwnerContext.Provider value={value}>
45
+ {children}
46
+ </BoundaryOwnerContext.Provider>
47
+ );
48
+ };
49
+
50
+ export const useBoundaryOwnerContext = () => {
51
+ return useContext(BoundaryOwnerContext);
52
+ };
53
+
54
+ export const useBoundaryOwner = (params: {
55
+ ownerRef: AnimatedRef<View>;
56
+ associatedTargetStyles?: BoundaryAssociatedStyle;
57
+ }) => {
58
+ const { ownerRef, associatedTargetStyles } = params;
59
+ const warnedAboutMultipleTargetsRef = useRef(false);
60
+ const [targetRefs, setTargetRefs] = useState<AnimatedRef<View>[]>([]);
61
+
62
+ const registerTargetRef = useCallback((targetRef: AnimatedRef<View>) => {
63
+ setTargetRefs((prev) => {
64
+ if (prev.includes(targetRef)) {
65
+ return prev;
66
+ }
67
+
68
+ if (
69
+ __DEV__ &&
70
+ prev.length > 0 &&
71
+ !warnedAboutMultipleTargetsRef.current
72
+ ) {
73
+ warnedAboutMultipleTargetsRef.current = true;
74
+ console.warn(MULTIPLE_TARGETS_WARNING);
75
+ }
76
+
77
+ return [...prev, targetRef];
78
+ });
79
+ }, []);
80
+
81
+ const unregisterTargetRef = useCallback((targetRef: AnimatedRef<View>) => {
82
+ setTargetRefs((prev) =>
83
+ prev.filter((existingRef) => existingRef !== targetRef),
84
+ );
85
+ }, []);
86
+
87
+ const contextValue = useMemo(
88
+ () => ({
89
+ ownerRef,
90
+ registerTargetRef,
91
+ unregisterTargetRef,
92
+ activeTargetRef: targetRefs[0] ?? null,
93
+ associatedTargetStyles,
94
+ }),
95
+ [
96
+ ownerRef,
97
+ registerTargetRef,
98
+ unregisterTargetRef,
99
+ targetRefs,
100
+ associatedTargetStyles,
101
+ ],
102
+ );
103
+
104
+ return {
105
+ contextValue,
106
+ hasActiveTarget: targetRefs.length > 0,
107
+ measuredRef: targetRefs[0] ?? ownerRef,
108
+ };
109
+ };
@@ -5,13 +5,16 @@ import type { View } from "react-native";
5
5
  import { GestureDetector } from "react-native-gesture-handler";
6
6
  import Animated, {
7
7
  runOnUI,
8
+ useAnimatedProps,
8
9
  useAnimatedRef,
10
+ useAnimatedStyle,
9
11
  useComposedEventHandler,
10
12
  useSharedValue,
11
13
  } from "react-native-reanimated";
12
- import { useAssociatedStyles } from "../hooks/animation/use-associated-style";
14
+ import { NO_PROPS, NO_STYLES } from "../constants";
13
15
  import { useScrollRegistry } from "../hooks/gestures/use-scroll-registry";
14
16
  import { RegisterBoundsProvider } from "../providers/register-bounds.provider";
17
+ import { useScreenStyles } from "../providers/screen/styles";
15
18
  import { ScrollSettleProvider } from "../providers/scroll-settle.provider";
16
19
  import type { TransitionAwareProps } from "../types/screen.types";
17
20
 
@@ -135,11 +138,36 @@ export function createTransitionAwareComponent<P extends object>(
135
138
  } = props as any;
136
139
 
137
140
  const animatedRef = useAnimatedRef<View>();
141
+ const { elementStylesMap } = useScreenStyles();
142
+ const associatedId = sharedBoundTag || styleId;
138
143
 
139
- const { associatedStyles, associatedProps } = useAssociatedStyles({
140
- id: sharedBoundTag || styleId,
141
- style,
142
- resetTransformOnUnset: !!sharedBoundTag,
144
+ const associatedStyles = useAnimatedStyle(() => {
145
+ "worklet";
146
+
147
+ if (!associatedId) {
148
+ return { opacity: 1 };
149
+ }
150
+
151
+ const baseStyle =
152
+ (elementStylesMap.value[associatedId]?.style as
153
+ | Record<string, any>
154
+ | undefined) ?? (NO_STYLES as Record<string, any>);
155
+
156
+ if ("opacity" in baseStyle) {
157
+ return baseStyle;
158
+ }
159
+
160
+ return { ...baseStyle, opacity: 1 };
161
+ });
162
+
163
+ const associatedProps = useAnimatedProps(() => {
164
+ "worklet";
165
+
166
+ if (!associatedId) {
167
+ return NO_PROPS;
168
+ }
169
+
170
+ return elementStylesMap.value[associatedId]?.props ?? NO_PROPS;
143
171
  });
144
172
 
145
173
  return (
@@ -5,7 +5,7 @@ import { useStack } from "../../../hooks/navigation/use-stack";
5
5
  import { ScreenAnimationProvider } from "../../../providers/screen/animation";
6
6
  import type { BaseDescriptor } from "../../../providers/screen/descriptors";
7
7
  import { DescriptorsProvider } from "../../../providers/screen/descriptors";
8
- import { ScreenStylesProvider } from "../../../providers/screen/styles.provider";
8
+ import { ScreenStylesProvider } from "../../../providers/screen/styles";
9
9
  import type { OverlayScreenState } from "../../../types/overlay.types";
10
10
 
11
11
  import { getActiveFloatOverlay } from "../helpers/get-active-overlay";
@@ -1,6 +1,5 @@
1
1
  import { memo } from "react";
2
2
  import { StyleSheet, View } from "react-native";
3
- import { DeferredVisibilityHost } from "./deferred-visibility-host";
4
3
  import { useBackdropPointerEvents } from "./hooks/use-backdrop-pointer-events";
5
4
  import { BackdropLayer } from "./layers/backdrop";
6
5
  import { ContentLayer } from "./layers/content";
@@ -15,18 +14,16 @@ export const ScreenContainer = memo(({ children }: Props) => {
15
14
 
16
15
  return (
17
16
  <View style={styles.container} pointerEvents={pointerEvents}>
18
- <DeferredVisibilityHost pointerEvents={pointerEvents}>
19
- <BackdropLayer
20
- isBackdropActive={isBackdropActive}
21
- backdropBehavior={backdropBehavior}
22
- />
23
- <ContentLayer
24
- pointerEvents={pointerEvents}
25
- isBackdropActive={isBackdropActive}
26
- >
27
- {children}
28
- </ContentLayer>
29
- </DeferredVisibilityHost>
17
+ <BackdropLayer
18
+ isBackdropActive={isBackdropActive}
19
+ backdropBehavior={backdropBehavior}
20
+ />
21
+ <ContentLayer
22
+ pointerEvents={pointerEvents}
23
+ isBackdropActive={isBackdropActive}
24
+ >
25
+ {children}
26
+ </ContentLayer>
30
27
  </View>
31
28
  );
32
29
  });
@@ -9,7 +9,7 @@ import { DefaultSnapSpec } from "../../../configs/specs";
9
9
  import { NO_PROPS, NO_STYLES } from "../../../constants";
10
10
  import { useNavigationHelpers } from "../../../hooks/navigation/use-navigation-helpers";
11
11
  import { useDescriptors } from "../../../providers/screen/descriptors";
12
- import { useScreenStyles } from "../../../providers/screen/styles.provider";
12
+ import { useScreenStyles } from "../../../providers/screen/styles";
13
13
  import { AnimationStore } from "../../../stores/animation.store";
14
14
  import { GestureStore } from "../../../stores/gesture.store";
15
15
  import { SystemStore } from "../../../stores/system.store";
@@ -24,7 +24,7 @@ export const BackdropLayer = memo(function BackdropLayer({
24
24
  backdropBehavior: BackdropBehavior;
25
25
  isBackdropActive: boolean;
26
26
  }) {
27
- const { stylesMap } = useScreenStyles();
27
+ const { layerStylesMap } = useScreenStyles();
28
28
  const { current } = useDescriptors();
29
29
  const { dismissScreen } = useNavigationHelpers();
30
30
 
@@ -111,12 +111,12 @@ export const BackdropLayer = memo(function BackdropLayer({
111
111
 
112
112
  const animatedBackdropStyle = useAnimatedStyle(() => {
113
113
  "worklet";
114
- return stylesMap.value.backdrop?.style ?? NO_STYLES;
114
+ return layerStylesMap.value.backdrop?.style ?? NO_STYLES;
115
115
  });
116
116
 
117
117
  const animatedBackdropProps = useAnimatedProps(() => {
118
118
  "worklet";
119
- return stylesMap.value.backdrop?.props ?? NO_PROPS;
119
+ return layerStylesMap.value.backdrop?.props ?? NO_PROPS;
120
120
  });
121
121
 
122
122
  return (
@@ -9,7 +9,7 @@ import Animated, {
9
9
  import { NO_PROPS, NO_STYLES } from "../../../constants";
10
10
  import { useGestureContext } from "../../../providers/gestures";
11
11
  import { useDescriptors } from "../../../providers/screen/descriptors";
12
- import { useScreenStyles } from "../../../providers/screen/styles.provider";
12
+ import { useScreenStyles } from "../../../providers/screen/styles";
13
13
  import { resolveNavigationMaskEnabled } from "../../../utils/resolve-screen-transition-options";
14
14
  import { useContentLayout } from "../hooks/use-content-layout";
15
15
  import { MaybeMaskedNavigationContainer } from "./maybe-masked-navigation-container";
@@ -23,7 +23,7 @@ type Props = {
23
23
 
24
24
  export const ContentLayer = memo(
25
25
  ({ children, pointerEvents, isBackdropActive }: Props) => {
26
- const { stylesMap } = useScreenStyles();
26
+ const { layerStylesMap } = useScreenStyles();
27
27
  const { current } = useDescriptors();
28
28
 
29
29
  const gestureContext = useGestureContext();
@@ -39,12 +39,12 @@ export const ContentLayer = memo(
39
39
 
40
40
  const animatedContentStyle = useAnimatedStyle(() => {
41
41
  "worklet";
42
- return stylesMap.value.content?.style || NO_STYLES;
42
+ return layerStylesMap.value.content?.style || NO_STYLES;
43
43
  });
44
44
 
45
45
  const animatedContentProps = useAnimatedProps(() => {
46
46
  "worklet";
47
- return stylesMap.value.content?.props ?? NO_PROPS;
47
+ return layerStylesMap.value.content?.props ?? NO_PROPS;
48
48
  });
49
49
 
50
50
  return (
@@ -6,7 +6,7 @@ import {
6
6
  NAVIGATION_MASK_ELEMENT_STYLE_ID,
7
7
  NO_STYLES,
8
8
  } from "../../../constants";
9
- import { useScreenStyles } from "../../../providers/screen/styles.provider";
9
+ import { useScreenStyles } from "../../../providers/screen/styles";
10
10
  import { logger } from "../../../utils/logger";
11
11
 
12
12
  type Props = {
@@ -27,19 +27,21 @@ let hasWarnedMissingMaskedView = false;
27
27
 
28
28
  export const MaybeMaskedNavigationContainer = memo(
29
29
  ({ enabled, children, pointerEvents }: Props) => {
30
- const { stylesMap } = useScreenStyles();
30
+ const { layerStylesMap } = useScreenStyles();
31
31
 
32
32
  const animatedNavigationMaskStyle = useAnimatedStyle(() => {
33
33
  "worklet";
34
34
  return (
35
- stylesMap.value[NAVIGATION_MASK_ELEMENT_STYLE_ID]?.style || NO_STYLES
35
+ layerStylesMap.value[NAVIGATION_MASK_ELEMENT_STYLE_ID]?.style ||
36
+ NO_STYLES
36
37
  );
37
38
  });
38
39
 
39
40
  const animatedNavigationMaskContainerStyle = useAnimatedStyle(() => {
40
41
  "worklet";
41
42
  return (
42
- stylesMap.value[NAVIGATION_MASK_CONTAINER_STYLE_ID]?.style || NO_STYLES
43
+ layerStylesMap.value[NAVIGATION_MASK_CONTAINER_STYLE_ID]?.style ||
44
+ NO_STYLES
43
45
  );
44
46
  });
45
47
 
@@ -6,7 +6,7 @@ import Animated, {
6
6
  } from "react-native-reanimated";
7
7
  import { NO_PROPS, NO_STYLES } from "../../../constants";
8
8
  import { useDescriptors } from "../../../providers/screen/descriptors";
9
- import { useScreenStyles } from "../../../providers/screen/styles.provider";
9
+ import { useScreenStyles } from "../../../providers/screen/styles";
10
10
 
11
11
  type Props = {
12
12
  children: React.ReactNode;
@@ -14,7 +14,7 @@ type Props = {
14
14
  };
15
15
 
16
16
  export const SurfaceContainer = memo(({ children, pointerEvents }: Props) => {
17
- const { stylesMap } = useScreenStyles();
17
+ const { layerStylesMap } = useScreenStyles();
18
18
  const { current } = useDescriptors();
19
19
 
20
20
  const SurfaceComponent = current.options.surfaceComponent;
@@ -27,12 +27,12 @@ export const SurfaceContainer = memo(({ children, pointerEvents }: Props) => {
27
27
 
28
28
  const animatedSurfaceStyle = useAnimatedStyle(() => {
29
29
  "worklet";
30
- return stylesMap.value.surface?.style ?? NO_STYLES;
30
+ return layerStylesMap.value.surface?.style ?? NO_STYLES;
31
31
  });
32
32
 
33
33
  const animatedSurfaceProps = useAnimatedProps(() => {
34
34
  "worklet";
35
- return stylesMap.value.surface?.props ?? NO_PROPS;
35
+ return layerStylesMap.value.surface?.props ?? NO_PROPS;
36
36
  });
37
37
 
38
38
  if (!AnimatedSurfaceComponent) return children;
@@ -105,6 +105,7 @@ export const EMPTY_BOUND_HELPER_RESULT_RAW = Object.freeze({
105
105
  translateY: 0,
106
106
  width: 0,
107
107
  height: 0,
108
+ ...HIDDEN_STYLE,
108
109
  });
109
110
  export const ENTER_RANGE = [0, 1] as const;
110
111
  export const EXIT_RANGE = [1, 2] as const;
@@ -49,7 +49,6 @@ export type {
49
49
  BoundsNavigationAccessor,
50
50
  BoundsNavigationZoomOptions,
51
51
  BoundsNavigationZoomStyle,
52
- DeferredScreenStyleSignal,
53
52
  OverlayProps,
54
53
  ScreenInterpolationProps,
55
54
  ScreenStyleInterpolator,
@@ -4,7 +4,7 @@ import { ScreenLifecycle } from "../../components/screen-lifecycle";
4
4
  import { ScreenGestureProvider } from "../gestures";
5
5
  import { ScreenAnimationProvider } from "./animation";
6
6
  import { type BaseDescriptor, DescriptorsProvider } from "./descriptors";
7
- import { ScreenStylesProvider } from "./styles.provider";
7
+ import { ScreenStylesProvider } from "./styles";
8
8
 
9
9
  type Props<TDescriptor extends BaseDescriptor> = {
10
10
  previous?: TDescriptor;