react-native-screen-transitions 3.7.0-alpha.0 → 3.7.0-beta.1

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 (102) hide show
  1. package/lib/commonjs/shared/adapters/with-screen-transitions/index.js +0 -6
  2. package/lib/commonjs/shared/adapters/with-screen-transitions/index.js.map +1 -1
  3. package/lib/commonjs/shared/adapters/with-screen-transitions/options.js +22 -68
  4. package/lib/commonjs/shared/adapters/with-screen-transitions/options.js.map +1 -1
  5. package/lib/commonjs/shared/adapters/with-screen-transitions/stack-layout.js +1 -1
  6. package/lib/commonjs/shared/adapters/with-screen-transitions/stack-layout.js.map +1 -1
  7. package/lib/commonjs/shared/components/activity/helpers.js +1 -1
  8. package/lib/commonjs/shared/components/activity/helpers.js.map +1 -1
  9. package/lib/commonjs/shared/components/activity/variants/activity-screen.js +4 -3
  10. package/lib/commonjs/shared/components/activity/variants/activity-screen.js.map +1 -1
  11. package/lib/commonjs/shared/index.js.map +1 -1
  12. package/lib/commonjs/shared/providers/screen/styles/helpers/resolve-slot-styles/index.js +7 -28
  13. package/lib/commonjs/shared/providers/screen/styles/helpers/resolve-slot-styles/index.js.map +1 -1
  14. package/lib/commonjs/shared/providers/screen/styles/hooks/use-resolved-slot-style-map.js +2 -14
  15. package/lib/commonjs/shared/providers/screen/styles/hooks/use-resolved-slot-style-map.js.map +1 -1
  16. package/lib/commonjs/shared/providers/stack/helpers/managed-stack-state/helpers/build-managed-stack-state.js +5 -7
  17. package/lib/commonjs/shared/providers/stack/helpers/managed-stack-state/helpers/build-managed-stack-state.js.map +1 -1
  18. package/lib/commonjs/shared/providers/stack/helpers/managed-stack-state/helpers/derive-managed-stack-state.js +1 -5
  19. package/lib/commonjs/shared/providers/stack/helpers/managed-stack-state/helpers/derive-managed-stack-state.js.map +1 -1
  20. package/lib/commonjs/shared/providers/stack/helpers/managed-stack-state/helpers/helpers.js +12 -1
  21. package/lib/commonjs/shared/providers/stack/helpers/managed-stack-state/helpers/helpers.js.map +1 -1
  22. package/lib/commonjs/shared/providers/stack/helpers/managed-stack-state/helpers/reconcile-managed-routes.js +2 -7
  23. package/lib/commonjs/shared/providers/stack/helpers/managed-stack-state/helpers/reconcile-managed-routes.js.map +1 -1
  24. package/lib/commonjs/shared/providers/stack/helpers/managed-stack-state/managed-stack-controller.js +4 -4
  25. package/lib/commonjs/shared/providers/stack/helpers/managed-stack-state/managed-stack-controller.js.map +1 -1
  26. package/lib/commonjs/shared/utils/bounds/navigation/reveal/build.js +4 -4
  27. package/lib/commonjs/shared/utils/bounds/navigation/reveal/build.js.map +1 -1
  28. package/lib/commonjs/shared/utils/bounds/navigation/reveal/config.js +2 -1
  29. package/lib/commonjs/shared/utils/bounds/navigation/reveal/config.js.map +1 -1
  30. package/lib/module/shared/adapters/with-screen-transitions/index.js +0 -1
  31. package/lib/module/shared/adapters/with-screen-transitions/index.js.map +1 -1
  32. package/lib/module/shared/adapters/with-screen-transitions/options.js +21 -67
  33. package/lib/module/shared/adapters/with-screen-transitions/options.js.map +1 -1
  34. package/lib/module/shared/adapters/with-screen-transitions/stack-layout.js +2 -2
  35. package/lib/module/shared/adapters/with-screen-transitions/stack-layout.js.map +1 -1
  36. package/lib/module/shared/components/activity/helpers.js +1 -1
  37. package/lib/module/shared/components/activity/helpers.js.map +1 -1
  38. package/lib/module/shared/components/activity/variants/activity-screen.js +4 -3
  39. package/lib/module/shared/components/activity/variants/activity-screen.js.map +1 -1
  40. package/lib/module/shared/index.js.map +1 -1
  41. package/lib/module/shared/providers/screen/styles/helpers/resolve-slot-styles/index.js +7 -28
  42. package/lib/module/shared/providers/screen/styles/helpers/resolve-slot-styles/index.js.map +1 -1
  43. package/lib/module/shared/providers/screen/styles/hooks/use-resolved-slot-style-map.js +3 -15
  44. package/lib/module/shared/providers/screen/styles/hooks/use-resolved-slot-style-map.js.map +1 -1
  45. package/lib/module/shared/providers/stack/helpers/managed-stack-state/helpers/build-managed-stack-state.js +6 -8
  46. package/lib/module/shared/providers/stack/helpers/managed-stack-state/helpers/build-managed-stack-state.js.map +1 -1
  47. package/lib/module/shared/providers/stack/helpers/managed-stack-state/helpers/derive-managed-stack-state.js +2 -6
  48. package/lib/module/shared/providers/stack/helpers/managed-stack-state/helpers/derive-managed-stack-state.js.map +1 -1
  49. package/lib/module/shared/providers/stack/helpers/managed-stack-state/helpers/helpers.js +9 -0
  50. package/lib/module/shared/providers/stack/helpers/managed-stack-state/helpers/helpers.js.map +1 -1
  51. package/lib/module/shared/providers/stack/helpers/managed-stack-state/helpers/reconcile-managed-routes.js +2 -7
  52. package/lib/module/shared/providers/stack/helpers/managed-stack-state/helpers/reconcile-managed-routes.js.map +1 -1
  53. package/lib/module/shared/providers/stack/helpers/managed-stack-state/managed-stack-controller.js +4 -4
  54. package/lib/module/shared/providers/stack/helpers/managed-stack-state/managed-stack-controller.js.map +1 -1
  55. package/lib/module/shared/utils/bounds/navigation/reveal/build.js +5 -5
  56. package/lib/module/shared/utils/bounds/navigation/reveal/build.js.map +1 -1
  57. package/lib/module/shared/utils/bounds/navigation/reveal/config.js +1 -0
  58. package/lib/module/shared/utils/bounds/navigation/reveal/config.js.map +1 -1
  59. package/lib/typescript/blank-stack/types.d.ts +10 -9
  60. package/lib/typescript/blank-stack/types.d.ts.map +1 -1
  61. package/lib/typescript/shared/adapters/with-screen-transitions/index.d.ts +1 -2
  62. package/lib/typescript/shared/adapters/with-screen-transitions/index.d.ts.map +1 -1
  63. package/lib/typescript/shared/adapters/with-screen-transitions/options.d.ts +3 -10
  64. package/lib/typescript/shared/adapters/with-screen-transitions/options.d.ts.map +1 -1
  65. package/lib/typescript/shared/components/activity/helpers.d.ts.map +1 -1
  66. package/lib/typescript/shared/components/activity/variants/activity-screen.d.ts.map +1 -1
  67. package/lib/typescript/shared/index.d.ts +1 -1
  68. package/lib/typescript/shared/index.d.ts.map +1 -1
  69. package/lib/typescript/shared/providers/screen/styles/helpers/resolve-slot-styles/index.d.ts +1 -2
  70. package/lib/typescript/shared/providers/screen/styles/helpers/resolve-slot-styles/index.d.ts.map +1 -1
  71. package/lib/typescript/shared/providers/screen/styles/hooks/use-resolved-slot-style-map.d.ts.map +1 -1
  72. package/lib/typescript/shared/providers/stack/helpers/managed-stack-state/helpers/build-managed-stack-state.d.ts.map +1 -1
  73. package/lib/typescript/shared/providers/stack/helpers/managed-stack-state/helpers/derive-managed-stack-state.d.ts.map +1 -1
  74. package/lib/typescript/shared/providers/stack/helpers/managed-stack-state/helpers/helpers.d.ts +2 -0
  75. package/lib/typescript/shared/providers/stack/helpers/managed-stack-state/helpers/helpers.d.ts.map +1 -1
  76. package/lib/typescript/shared/providers/stack/helpers/managed-stack-state/helpers/reconcile-managed-routes.d.ts.map +1 -1
  77. package/lib/typescript/shared/types/bounds.types.d.ts +19 -0
  78. package/lib/typescript/shared/types/bounds.types.d.ts.map +1 -1
  79. package/lib/typescript/shared/types/screen.types.d.ts +15 -14
  80. package/lib/typescript/shared/types/screen.types.d.ts.map +1 -1
  81. package/lib/typescript/shared/utils/bounds/navigation/reveal/build.d.ts.map +1 -1
  82. package/lib/typescript/shared/utils/bounds/navigation/reveal/config.d.ts +1 -0
  83. package/lib/typescript/shared/utils/bounds/navigation/reveal/config.d.ts.map +1 -1
  84. package/package.json +1 -1
  85. package/src/blank-stack/types.ts +10 -9
  86. package/src/shared/adapters/with-screen-transitions/index.tsx +1 -6
  87. package/src/shared/adapters/with-screen-transitions/options.ts +38 -109
  88. package/src/shared/adapters/with-screen-transitions/stack-layout.tsx +5 -5
  89. package/src/shared/components/activity/helpers.ts +1 -1
  90. package/src/shared/components/activity/variants/activity-screen.tsx +4 -3
  91. package/src/shared/index.ts +1 -5
  92. package/src/shared/providers/screen/styles/helpers/resolve-slot-styles/index.ts +12 -53
  93. package/src/shared/providers/screen/styles/hooks/use-resolved-slot-style-map.tsx +3 -16
  94. package/src/shared/providers/stack/helpers/managed-stack-state/helpers/build-managed-stack-state.ts +9 -12
  95. package/src/shared/providers/stack/helpers/managed-stack-state/helpers/derive-managed-stack-state.ts +2 -10
  96. package/src/shared/providers/stack/helpers/managed-stack-state/helpers/helpers.ts +19 -0
  97. package/src/shared/providers/stack/helpers/managed-stack-state/helpers/reconcile-managed-routes.ts +2 -12
  98. package/src/shared/providers/stack/helpers/managed-stack-state/managed-stack-controller.ts +4 -4
  99. package/src/shared/types/bounds.types.ts +19 -0
  100. package/src/shared/types/screen.types.ts +15 -14
  101. package/src/shared/utils/bounds/navigation/reveal/build.ts +10 -6
  102. package/src/shared/utils/bounds/navigation/reveal/config.ts +1 -0
@@ -1,4 +1,3 @@
1
- import type { ScreenProps } from "react-native-screens";
2
1
  import type { ScreenTransitionConfig } from "../../types";
3
2
 
4
3
  type NativeStackTransitionResetOptions = {
@@ -8,26 +7,14 @@ type NativeStackTransitionResetOptions = {
8
7
  gestureEnabled: false;
9
8
  };
10
9
 
11
- export type NativeStackNativeGestureOptions = {
12
- nativeGestureEnabled?: boolean;
13
- nativeGestureDirection?: ScreenProps["swipeDirection"];
14
- nativeGestureResponseDistance?: ScreenProps["gestureResponseDistance"];
15
- };
16
-
17
- export type ScreenTransitionDescriptorOptions = ScreenTransitionConfig & {
10
+ export type AdapterDescriptorOptions = ScreenTransitionConfig & {
18
11
  enableTransitions?: boolean;
19
- screenTransition?: ScreenTransitionConfig | null | false;
20
12
  };
21
13
 
22
14
  export type NativeStackAdapterOptions<
23
15
  TNativeOptions extends object = Record<string, unknown>,
24
- > = Omit<
25
- TNativeOptions,
26
- | keyof ScreenTransitionDescriptorOptions
27
- | keyof NativeStackNativeGestureOptions
28
- > &
29
- ScreenTransitionDescriptorOptions &
30
- NativeStackNativeGestureOptions;
16
+ > = Omit<TNativeOptions, keyof AdapterDescriptorOptions> &
17
+ AdapterDescriptorOptions;
31
18
 
32
19
  const NATIVE_STACK_TRANSITION_RESET_OPTIONS: NativeStackTransitionResetOptions =
33
20
  {
@@ -37,14 +24,15 @@ const NATIVE_STACK_TRANSITION_RESET_OPTIONS: NativeStackTransitionResetOptions =
37
24
  gestureEnabled: false,
38
25
  };
39
26
 
40
- const COLLIDING_TRANSITION_OPTION_KEYS = [
41
- "gestureEnabled",
42
- "gestureDirection",
43
- "gestureResponseDistance",
44
- ] as const satisfies readonly (keyof ScreenTransitionConfig)[];
27
+ type GestureEnabledRestore = {
28
+ gestureEnabled: ScreenTransitionConfig["gestureEnabled"];
29
+ hasGestureEnabled: boolean;
30
+ };
45
31
 
46
- type CollidingTransitionOptionKey =
47
- (typeof COLLIDING_TRANSITION_OPTION_KEYS)[number];
32
+ const gestureEnabledRestoreByAdaptedOptions = new WeakMap<
33
+ Record<string, unknown>,
34
+ GestureEnabledRestore
35
+ >();
48
36
 
49
37
  export type NativeStackAdapterOptionInput =
50
38
  | Record<string, unknown>
@@ -54,63 +42,6 @@ function isPlainOptions(value: unknown): value is Record<string, unknown> {
54
42
  return typeof value === "object" && value !== null;
55
43
  }
56
44
 
57
- function extractCollidingTransitionOptions(
58
- options: Record<string, unknown>,
59
- ): ScreenTransitionConfig | undefined {
60
- let screenTransition: ScreenTransitionConfig | undefined;
61
-
62
- for (const key of COLLIDING_TRANSITION_OPTION_KEYS) {
63
- if (!(key in options)) {
64
- continue;
65
- }
66
-
67
- screenTransition ??= {};
68
- screenTransition[key] = options[key] as never;
69
- }
70
-
71
- return screenTransition;
72
- }
73
-
74
- function removeCollidingTransitionOptions<
75
- TOptions extends Record<string, unknown>,
76
- >(options: TOptions): Omit<TOptions, CollidingTransitionOptionKey> {
77
- const nativeOptions = { ...options };
78
-
79
- for (const key of COLLIDING_TRANSITION_OPTION_KEYS) {
80
- delete nativeOptions[key];
81
- }
82
-
83
- return nativeOptions;
84
- }
85
-
86
- function applyNativeGestureAliases<TOptions extends Record<string, unknown>>(
87
- options: TOptions,
88
- ): TOptions {
89
- const nativeOptions: Record<string, unknown> = { ...options };
90
- const {
91
- nativeGestureEnabled,
92
- nativeGestureDirection,
93
- nativeGestureResponseDistance,
94
- } = options;
95
- delete nativeOptions.nativeGestureEnabled;
96
- delete nativeOptions.nativeGestureDirection;
97
- delete nativeOptions.nativeGestureResponseDistance;
98
-
99
- if (nativeGestureEnabled !== undefined) {
100
- nativeOptions.gestureEnabled = nativeGestureEnabled;
101
- }
102
-
103
- if (nativeGestureDirection !== undefined) {
104
- nativeOptions.gestureDirection = nativeGestureDirection;
105
- }
106
-
107
- if (nativeGestureResponseDistance !== undefined) {
108
- nativeOptions.gestureResponseDistance = nativeGestureResponseDistance;
109
- }
110
-
111
- return nativeOptions as TOptions;
112
- }
113
-
114
45
  export function adaptNativeStackTransitionOptions<
115
46
  TOptions extends NativeStackAdapterOptionInput | undefined,
116
47
  >(options: TOptions): TOptions {
@@ -123,50 +54,48 @@ export function adaptNativeStackTransitionOptions<
123
54
  return options;
124
55
  }
125
56
 
126
- const inlineScreenTransition = extractCollidingTransitionOptions(options);
127
- const explicitScreenTransition = options.screenTransition;
128
- const hasTransitionsEnabled =
129
- options.enableTransitions === true || !!explicitScreenTransition;
57
+ const hasTransitionsEnabled = options.enableTransitions === true;
130
58
 
131
59
  if (!hasTransitionsEnabled) {
132
- return applyNativeGestureAliases(options) as TOptions;
60
+ return options;
133
61
  }
134
62
 
135
- const nativeOptions = applyNativeGestureAliases(
136
- removeCollidingTransitionOptions(options),
137
- );
138
- const nativeGestureEnabled = nativeOptions.gestureEnabled;
139
- const screenTransition =
140
- explicitScreenTransition && isPlainOptions(explicitScreenTransition)
141
- ? {
142
- ...inlineScreenTransition,
143
- ...explicitScreenTransition,
144
- }
145
- : inlineScreenTransition;
146
-
147
- return {
63
+ const nativeOptions = options as Record<string, unknown>;
64
+ const adaptedOptions: Record<string, unknown> = {
148
65
  ...nativeOptions,
149
66
  ...NATIVE_STACK_TRANSITION_RESET_OPTIONS,
150
- ...(nativeGestureEnabled !== undefined
151
- ? { gestureEnabled: nativeGestureEnabled }
152
- : null),
153
67
  enableTransitions: true,
154
- ...(screenTransition ? { screenTransition } : null),
155
- } as TOptions;
68
+ };
69
+ gestureEnabledRestoreByAdaptedOptions.set(adaptedOptions, {
70
+ gestureEnabled:
71
+ nativeOptions.gestureEnabled as ScreenTransitionConfig["gestureEnabled"],
72
+ hasGestureEnabled: "gestureEnabled" in nativeOptions,
73
+ });
74
+
75
+ return adaptedOptions as TOptions;
156
76
  }
157
77
 
158
- export function resolveScreenTransitionOptions<
159
- TOptions extends ScreenTransitionDescriptorOptions,
78
+ export function resolveAdapterTransitionOptions<
79
+ TOptions extends AdapterDescriptorOptions,
160
80
  >(options: TOptions): TOptions & ScreenTransitionConfig {
161
- const screenTransition = options.screenTransition;
81
+ const gestureEnabledRestore = gestureEnabledRestoreByAdaptedOptions.get(
82
+ options as Record<string, unknown>,
83
+ );
162
84
 
163
- if (!screenTransition) {
85
+ if (!gestureEnabledRestore) {
164
86
  return options;
165
87
  }
166
88
 
167
- return {
89
+ const resolvedOptions = {
168
90
  ...options,
169
- ...screenTransition,
170
91
  enableTransitions: true,
171
92
  };
93
+
94
+ if (gestureEnabledRestore.hasGestureEnabled) {
95
+ resolvedOptions.gestureEnabled = gestureEnabledRestore.gestureEnabled;
96
+ } else {
97
+ delete resolvedOptions.gestureEnabled;
98
+ }
99
+
100
+ return resolvedOptions;
172
101
  }
@@ -24,8 +24,8 @@ import {
24
24
  useScreenTransitionsAdapterContext,
25
25
  } from "./context";
26
26
  import {
27
- resolveScreenTransitionOptions,
28
- type ScreenTransitionDescriptorOptions,
27
+ type AdapterDescriptorOptions,
28
+ resolveAdapterTransitionOptions,
29
29
  } from "./options";
30
30
  import type {
31
31
  NavigatorLayout,
@@ -63,8 +63,8 @@ function normalizeDescriptor(
63
63
  ): BaseStackDescriptor {
64
64
  return {
65
65
  ...descriptor,
66
- options: resolveScreenTransitionOptions(
67
- descriptor.options as ScreenTransitionDescriptorOptions,
66
+ options: resolveAdapterTransitionOptions(
67
+ descriptor.options as AdapterDescriptorOptions,
68
68
  ),
69
69
  };
70
70
  }
@@ -119,7 +119,7 @@ function buildTransitionStackState({
119
119
 
120
120
  if (
121
121
  !shouldShowFloatOverlay &&
122
- (normalizedDescriptor.options as ScreenTransitionDescriptorOptions)
122
+ (normalizedDescriptor.options as AdapterDescriptorOptions)
123
123
  .enableTransitions &&
124
124
  isOverlayVisible(normalizedDescriptor.options)
125
125
  ) {
@@ -5,4 +5,4 @@ export type { InactiveBehavior } from "../../types/screen.types";
5
5
 
6
6
  export const DEFAULT_INACTIVE_BEHAVIOR: InactiveBehavior = IS_WEB
7
7
  ? "unmount"
8
- : "detach";
8
+ : "hide";
@@ -79,14 +79,15 @@ export const ActivityScreen = memo(function ActivityScreen({
79
79
  // a blank frame during the transition.
80
80
  activityState = 1;
81
81
  visible = true;
82
- } else if (inactiveBehavior === "freeze") {
82
+ } else if (inactiveBehavior === "pause") {
83
83
  activityState = 1;
84
84
  shouldFreeze = true;
85
85
  visible = true;
86
86
  } else {
87
- // `detach` hides native presentation. Non-nested `unmount`
88
- // removes the React subtree through the JS guard below.
87
+ // `hide` freezes and hides native presentation. Non-nested
88
+ // `unmount` removes the React subtree through the JS guard below.
89
89
  activityState = 0;
90
+ shouldFreeze = true;
90
91
  visible = false;
91
92
  }
92
93
  }
@@ -26,11 +26,7 @@ export default {
26
26
  Specs,
27
27
  };
28
28
 
29
- export type {
30
- NativeStackAdapterOptions,
31
- NativeStackNativeGestureOptions,
32
- ScreenTransitionDescriptorOptions,
33
- } from "./adapters/with-screen-transitions";
29
+ export type { NativeStackAdapterOptions } from "./adapters/with-screen-transitions";
34
30
  export { withScreenTransitions } from "./adapters/with-screen-transitions";
35
31
  export { snapTo } from "./animation/snap-to";
36
32
  export {
@@ -17,7 +17,6 @@ type ResolveSlotStylesContext = {
17
17
  localStylesMaps: LocalStyleLayers;
18
18
  ancestorStylesMap: NormalizedTransitionInterpolatedStyle;
19
19
  previousStyleStatesBySlot: ResettableStyleStatesBySlot;
20
- deferLocalSlotResets: boolean;
21
20
  resolvedStylesMap: NormalizedTransitionInterpolatedStyle;
22
21
  nextPreviousStyleStatesBySlot: ResettableStyleStatesBySlot;
23
22
  };
@@ -75,42 +74,32 @@ const hasResettableDisappearedKeys = (
75
74
  const getResolvedSlotOutput = ({
76
75
  slot,
77
76
  previousState,
78
- resetDroppedKeys,
79
- carryPreviousState,
80
77
  }: {
81
78
  slot: NormalizedTransitionSlotStyle | undefined;
82
79
  previousState: ResettableStyleState | undefined;
83
- resetDroppedKeys: boolean;
84
- carryPreviousState: boolean;
85
80
  }) => {
86
81
  "worklet";
87
82
  const state = getResolvedSlotState(slot);
88
83
 
89
- const hasStyleResetPatch =
90
- resetDroppedKeys &&
91
- hasResettableDisappearedKeys(
92
- previousState?.styleKeys,
93
- previousState?.styleResetValues,
94
- state.styleKeys,
95
- );
96
- const hasPropResetPatch =
97
- resetDroppedKeys &&
98
- hasResettableDisappearedKeys(
99
- previousState?.propKeys,
100
- previousState?.propResetValues,
101
- state.propKeys,
102
- );
84
+ const hasStyleResetPatch = hasResettableDisappearedKeys(
85
+ previousState?.styleKeys,
86
+ previousState?.styleResetValues,
87
+ state.styleKeys,
88
+ );
89
+ const hasPropResetPatch = hasResettableDisappearedKeys(
90
+ previousState?.propKeys,
91
+ previousState?.propResetValues,
92
+ state.propKeys,
93
+ );
103
94
  const hasResetPatch = hasEitherResetPatch(
104
95
  hasStyleResetPatch,
105
96
  hasPropResetPatch,
106
97
  );
107
- const nextState =
108
- state.nextState ?? (carryPreviousState ? previousState : undefined);
109
98
 
110
99
  if (!hasResetPatch) {
111
100
  return {
112
101
  resolvedSlot: getForwardedSlot(slot, state.hasAnyKeys),
113
- nextState,
102
+ nextState: state.nextState,
114
103
  };
115
104
  }
116
105
 
@@ -126,15 +115,10 @@ const getResolvedSlotOutput = ({
126
115
  hasStyleResetPatch,
127
116
  hasPropResetPatch,
128
117
  }),
129
- nextState,
118
+ nextState: state.nextState,
130
119
  };
131
120
  };
132
121
 
133
- const hasLocalStyleSource = (context: ResolveSlotStylesContext) => {
134
- "worklet";
135
- return context.localStylesMaps.length > 0;
136
- };
137
-
138
122
  const hasLocalSlot = (context: ResolveSlotStylesContext, slotId: string) => {
139
123
  "worklet";
140
124
 
@@ -147,25 +131,6 @@ const hasLocalSlot = (context: ResolveSlotStylesContext, slotId: string) => {
147
131
  return false;
148
132
  };
149
133
 
150
- const shouldDeferMissingLocalSlotReset = (
151
- context: ResolveSlotStylesContext,
152
- slotId: string,
153
- ) => {
154
- "worklet";
155
- const canInherit = shouldSlotInherit(slotId);
156
- const localSlotExists = hasLocalSlot(context, slotId);
157
- const hasInheritedSlot =
158
- canInherit && context.ancestorStylesMap[slotId] !== undefined;
159
-
160
- return (
161
- context.deferLocalSlotResets &&
162
- !hasLocalStyleSource(context) &&
163
- !canInherit &&
164
- !localSlotExists &&
165
- !hasInheritedSlot
166
- );
167
- };
168
-
169
134
  const mergeBucket = (
170
135
  resolvedBucket: Record<string, unknown> | undefined,
171
136
  source: Record<string, unknown> | undefined,
@@ -421,12 +386,9 @@ const appendResolvedSlot = (
421
386
  slotId: string,
422
387
  ) => {
423
388
  "worklet";
424
- const shouldDeferReset = shouldDeferMissingLocalSlotReset(context, slotId);
425
389
  const { resolvedSlot, nextState } = getResolvedSlotOutput({
426
390
  slot: getSlotForId(context, slotId),
427
391
  previousState: context.previousStyleStatesBySlot[slotId],
428
- resetDroppedKeys: !shouldDeferReset,
429
- carryPreviousState: shouldDeferReset,
430
392
  });
431
393
 
432
394
  writeResolvedSlotOutput({
@@ -505,12 +467,10 @@ export const resolveSlotStyles = ({
505
467
  localStylesMaps,
506
468
  ancestorStylesMap,
507
469
  previousStyleStatesBySlot,
508
- deferLocalSlotResets = false,
509
470
  }: {
510
471
  localStylesMaps: LocalStyleLayers;
511
472
  ancestorStylesMap: NormalizedTransitionInterpolatedStyle;
512
473
  previousStyleStatesBySlot: ResettableStyleStatesBySlot;
513
- deferLocalSlotResets?: boolean;
514
474
  }) => {
515
475
  "worklet";
516
476
  const resolvedStylesMap: NormalizedTransitionInterpolatedStyle = {};
@@ -519,7 +479,6 @@ export const resolveSlotStyles = ({
519
479
  localStylesMaps,
520
480
  ancestorStylesMap,
521
481
  previousStyleStatesBySlot,
522
- deferLocalSlotResets,
523
482
  resolvedStylesMap,
524
483
  nextPreviousStyleStatesBySlot,
525
484
  };
@@ -3,9 +3,8 @@ import {
3
3
  useDerivedValue,
4
4
  useSharedValue,
5
5
  } from "react-native-reanimated";
6
- import { NO_STYLES } from "../../../../constants";
6
+ import { NO_PROPS, NO_STYLES } from "../../../../constants";
7
7
  import type { NormalizedTransitionInterpolatedStyle } from "../../../../types/animation.types";
8
- import { useScreenAnimationContext } from "../../animation";
9
8
  import {
10
9
  type LocalStyleLayers,
11
10
  type ResettableStyleStatesBySlot,
@@ -22,30 +21,18 @@ export const useResolvedStylesMap = ({
22
21
  localStylesMaps,
23
22
  ancestorStylesMap,
24
23
  }: UseResolvedStylesMapParams) => {
25
- const { screenInterpolatorProps, screenInterpolatorPropsRevision } =
26
- useScreenAnimationContext();
27
- const previousStyleStatesBySlot = useSharedValue<ResettableStyleStatesBySlot>(
28
- {},
29
- );
24
+ const previousStyleStatesBySlot =
25
+ useSharedValue<ResettableStyleStatesBySlot>(NO_PROPS);
30
26
  const previousResolvedStylesMap =
31
27
  useSharedValue<NormalizedTransitionInterpolatedStyle>(NO_STYLES);
32
28
 
33
29
  return useDerivedValue(() => {
34
30
  "worklet";
35
- screenInterpolatorPropsRevision.get();
36
-
37
- const props = screenInterpolatorProps.get();
38
- // Keep missing local slots alive only when another route drives this screen
39
- // and no active local style layer is available. Once a current/next layer
40
- // runs, omitted local slots and dropped keys are intentional reset signals.
41
- const deferLocalSlotResets = !props.focused && !props.current.closing;
42
-
43
31
  const { resolvedStylesMap, nextPreviousStyleStatesBySlot } =
44
32
  resolveSlotStyles({
45
33
  localStylesMaps: localStylesMaps.get(),
46
34
  ancestorStylesMap: ancestorStylesMap?.get() ?? NO_STYLES,
47
35
  previousStyleStatesBySlot: previousStyleStatesBySlot.get(),
48
- deferLocalSlotResets,
49
36
  });
50
37
 
51
38
  previousStyleStatesBySlot.set(nextPreviousStyleStatesBySlot);
@@ -13,6 +13,7 @@ import {
13
13
  areDescriptorsEqual,
14
14
  areRouteChildStateMapsEqual,
15
15
  getRouteChildState,
16
+ routeKeyListsAreEqual,
16
17
  setsAreEqual,
17
18
  } from "./helpers";
18
19
  import type {
@@ -34,13 +35,6 @@ type BuildManagedStackStateParams<
34
35
  previousState?: LocalRoutesState<TDescriptor>;
35
36
  };
36
37
 
37
- const areRouteKeysEqual = (a: string[], b: string[]): boolean => {
38
- if (a === b) return true;
39
- if (a.length !== b.length) return false;
40
-
41
- return a.every((key, index) => key === b[index]);
42
- };
43
-
44
38
  const resolveStableDescriptorSource = <
45
39
  TDescriptor extends BaseStackDescriptor,
46
40
  >({
@@ -106,10 +100,13 @@ const getSceneActivityWindow = <
106
100
  >): SceneActivityWindow => {
107
101
  const focusedRouteKey = props.state.routes[props.state.index]?.key;
108
102
 
109
- let focusedIndex = Math.max(
110
- 0,
111
- routes.findIndex((route) => route.key === focusedRouteKey),
112
- );
103
+ let focusedIndex = routes.findIndex((route) => route.key === focusedRouteKey);
104
+
105
+ if (focusedIndex === -1) {
106
+ throw new Error(
107
+ `Focused route "${focusedRouteKey}" is missing from routes`,
108
+ );
109
+ }
113
110
 
114
111
  while (focusedIndex > 0 && closingRouteKeys.has(routes[focusedIndex]?.key)) {
115
112
  focusedIndex--;
@@ -355,7 +352,7 @@ export const buildManagedStackState = <
355
352
  scenes,
356
353
  routeKeys:
357
354
  params.previousState &&
358
- areRouteKeysEqual(params.previousState.routeKeys, routeKeys)
355
+ routeKeyListsAreEqual(params.previousState.routeKeys, routeKeys)
359
356
  ? params.previousState.routeKeys
360
357
  : routeKeys,
361
358
  shouldShowFloatOverlay,
@@ -10,6 +10,7 @@ import {
10
10
  areDescriptorsEqual,
11
11
  areRouteChildStateMapsEqual,
12
12
  getRouteChildStateMap,
13
+ routesHaveSameKeys,
13
14
  setsAreEqual,
14
15
  } from "./helpers";
15
16
  import { reconcileManagedRoutes } from "./reconcile-managed-routes";
@@ -35,15 +36,6 @@ const routesAreIdentical = <Route extends RouteWithKey>(
35
36
  return a.every((route, index) => route === b[index]);
36
37
  };
37
38
 
38
- const routeKeysAreEqual = <Route extends RouteWithKey>(
39
- a: Route[],
40
- b: Route[],
41
- ): boolean => {
42
- if (a.length !== b.length) return false;
43
-
44
- return a.every((route, index) => route.key === b[index]?.key);
45
- };
46
-
47
39
  export const deriveManagedStackState = <
48
40
  TDescriptor extends BaseStackDescriptor,
49
41
  TNavigation extends BaseStackNavigation,
@@ -85,7 +77,7 @@ export const deriveManagedStackState = <
85
77
  focusedRouteUnchanged &&
86
78
  closingRouteKeysUnchanged &&
87
79
  routeChildStatesUnchanged &&
88
- routeKeysAreEqual(current.routes, nextRoutesSnapshot) &&
80
+ routesHaveSameKeys(current.routes, nextRoutesSnapshot) &&
89
81
  areDescriptorSourceMapsEquivalent(
90
82
  current.sourceDescriptors,
91
83
  nextDescriptors,
@@ -38,6 +38,25 @@ export const setsAreEqual = <T>(
38
38
  return true;
39
39
  };
40
40
 
41
+ export const routeKeyListsAreEqual = (
42
+ a: readonly string[],
43
+ b: readonly string[],
44
+ ): boolean => {
45
+ if (a === b) return true;
46
+ if (a.length !== b.length) return false;
47
+
48
+ return a.every((key, index) => key === b[index]);
49
+ };
50
+
51
+ export const routesHaveSameKeys = <Route extends RouteWithKey>(
52
+ a: readonly Route[],
53
+ b: readonly Route[],
54
+ ): boolean => {
55
+ if (a.length !== b.length) return false;
56
+
57
+ return a.every((route, index) => route.key === b[index]?.key);
58
+ };
59
+
41
60
  export const getRouteChildState = (route: RouteWithKey): unknown => {
42
61
  if (!route || typeof route !== "object") {
43
62
  return undefined;
@@ -4,6 +4,7 @@ import type {
4
4
  } from "../../../../../types/stack.types";
5
5
  import { composeDescriptors } from "../../../../../utils/navigation/compose-descriptors";
6
6
  import { syncRoutesWithRemoved } from "../../../../../utils/navigation/sync-routes-with-removed";
7
+ import { routesHaveSameKeys } from "./helpers";
7
8
  import type {
8
9
  LocalRoutesState,
9
10
  ManagedDescriptorSources,
@@ -19,17 +20,6 @@ type ReconcileManagedRoutesParams<TDescriptor extends BaseStackDescriptor> = {
19
20
  closingRouteKeys: Set<string>;
20
21
  };
21
22
 
22
- const haveSameRouteKeys = <Route extends RouteWithKey>(
23
- previous: Route[],
24
- next: Route[],
25
- ): boolean => {
26
- if (previous.length !== next.length) {
27
- return false;
28
- }
29
-
30
- return previous.every((route, index) => route?.key === next[index]?.key);
31
- };
32
-
33
23
  const alignRoutesWithLatest = <
34
24
  Route extends RouteWithKey,
35
25
  DescriptorMap extends Record<string, unknown>,
@@ -155,7 +145,7 @@ export const reconcileManagedRoutes = <TDescriptor extends BaseStackDescriptor>(
155
145
  closingRouteKeys,
156
146
  } = params;
157
147
 
158
- const routeKeysUnchanged = haveSameRouteKeys(
148
+ const routeKeysUnchanged = routesHaveSameKeys(
159
149
  previousRoutesSnapshot,
160
150
  nextRoutesSnapshot,
161
151
  );
@@ -30,7 +30,7 @@ export const createManagedStackController = <
30
30
  ): ManagedStackControllerType<TDescriptor, TNavigation> => {
31
31
  const closingRouteKeys = new Set<string>();
32
32
  let props = initialProps;
33
- let previousPropRoutes = initialProps.state.routes;
33
+ let previousRoutesSnapshot = initialProps.state.routes;
34
34
  let snapshot: ManagedStackControllerSnapshot<TDescriptor> = {
35
35
  state: buildManagedStackState({
36
36
  props,
@@ -60,16 +60,16 @@ export const createManagedStackController = <
60
60
  };
61
61
 
62
62
  const update = (nextProps: ManagedStackProps<TDescriptor, TNavigation>) => {
63
- const previousRoutesSnapshot = previousPropRoutes;
63
+ const lastRoutesSnapshot = previousRoutesSnapshot;
64
64
  props = nextProps;
65
65
 
66
66
  const nextState = deriveManagedStackState({
67
67
  props,
68
68
  current: snapshot.state,
69
- previousRoutesSnapshot,
69
+ previousRoutesSnapshot: lastRoutesSnapshot,
70
70
  closingRouteKeys,
71
71
  });
72
- previousPropRoutes = nextProps.state.routes;
72
+ previousRoutesSnapshot = nextProps.state.routes;
73
73
 
74
74
  if (nextState === snapshot.state) {
75
75
  return;
@@ -231,6 +231,25 @@ export type BoundsNavigationRevealOptions = {
231
231
  * @default "freeform"
232
232
  */
233
233
  gestureProgressMode?: GestureProgressMode;
234
+ /**
235
+ * Scale applied to the unfocused background content while the reveal runs
236
+ * above it.
237
+ *
238
+ * @default 0.9375
239
+ */
240
+ backgroundScale?: number;
241
+ /**
242
+ * Whether reveal should reset the unfocused background content scale once the
243
+ * transition is logically settled.
244
+ *
245
+ * By default, reveal restores the background to scale `1` after settle so the
246
+ * next drag or programmatic dismiss starts from a fresh, unmodified layout
247
+ * measurement. Keeping the background transformed while idle can make the next
248
+ * measurement read the scaled screen instead of the real screen geometry.
249
+ *
250
+ * @default true
251
+ */
252
+ shouldBackgroundScaleResetOnSettled?: boolean;
234
253
  /**
235
254
  * Temporarily blocks pointer-event pass-through on the inactive content until
236
255
  * the source element transition handoff reaches progress `0.25`.