react-native-screen-transitions 3.7.0-beta.1 → 3.7.0-beta.2
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.
- package/lib/commonjs/shared/providers/screen/animation/helpers/accessors/use-build-transition-accessor.js +10 -1
- package/lib/commonjs/shared/providers/screen/animation/helpers/accessors/use-build-transition-accessor.js.map +1 -1
- package/lib/commonjs/shared/providers/screen/animation/helpers/pipeline.js.map +1 -1
- package/lib/commonjs/shared/providers/screen/animation/helpers/read-screen-animation-revisions.js +20 -0
- package/lib/commonjs/shared/providers/screen/animation/helpers/read-screen-animation-revisions.js.map +1 -0
- package/lib/commonjs/shared/providers/screen/animation/use-screen-animation.js +2 -13
- package/lib/commonjs/shared/providers/screen/animation/use-screen-animation.js.map +1 -1
- package/lib/commonjs/shared/providers/screen/gestures/ownership/shadowing-claims.js +18 -0
- package/lib/commonjs/shared/providers/screen/gestures/ownership/shadowing-claims.js.map +1 -0
- package/lib/commonjs/shared/providers/screen/gestures/ownership/use-walk-up-and-register-shadowing-claims.js +47 -1
- package/lib/commonjs/shared/providers/screen/gestures/ownership/use-walk-up-and-register-shadowing-claims.js.map +1 -1
- package/lib/commonjs/shared/providers/screen/styles/hooks/use-interpolated-style-maps.js +12 -3
- package/lib/commonjs/shared/providers/screen/styles/hooks/use-interpolated-style-maps.js.map +1 -1
- package/lib/commonjs/shared/providers/stack/helpers/managed-stack-state/helpers/build-managed-stack-state.js +23 -20
- package/lib/commonjs/shared/providers/stack/helpers/managed-stack-state/helpers/build-managed-stack-state.js.map +1 -1
- package/lib/module/shared/providers/screen/animation/helpers/accessors/use-build-transition-accessor.js +10 -1
- package/lib/module/shared/providers/screen/animation/helpers/accessors/use-build-transition-accessor.js.map +1 -1
- package/lib/module/shared/providers/screen/animation/helpers/pipeline.js.map +1 -1
- package/lib/module/shared/providers/screen/animation/helpers/read-screen-animation-revisions.js +15 -0
- package/lib/module/shared/providers/screen/animation/helpers/read-screen-animation-revisions.js.map +1 -0
- package/lib/module/shared/providers/screen/animation/use-screen-animation.js +1 -12
- package/lib/module/shared/providers/screen/animation/use-screen-animation.js.map +1 -1
- package/lib/module/shared/providers/screen/gestures/ownership/shadowing-claims.js +13 -0
- package/lib/module/shared/providers/screen/gestures/ownership/shadowing-claims.js.map +1 -0
- package/lib/module/shared/providers/screen/gestures/ownership/use-walk-up-and-register-shadowing-claims.js +49 -3
- package/lib/module/shared/providers/screen/gestures/ownership/use-walk-up-and-register-shadowing-claims.js.map +1 -1
- package/lib/module/shared/providers/screen/styles/hooks/use-interpolated-style-maps.js +12 -3
- package/lib/module/shared/providers/screen/styles/hooks/use-interpolated-style-maps.js.map +1 -1
- package/lib/module/shared/providers/stack/helpers/managed-stack-state/helpers/build-managed-stack-state.js +23 -20
- package/lib/module/shared/providers/stack/helpers/managed-stack-state/helpers/build-managed-stack-state.js.map +1 -1
- package/lib/module/shared/types/animation.types.js.map +1 -1
- package/lib/typescript/shared/index.d.ts +1 -1
- package/lib/typescript/shared/index.d.ts.map +1 -1
- package/lib/typescript/shared/providers/screen/animation/helpers/accessors/use-build-transition-accessor.d.ts.map +1 -1
- package/lib/typescript/shared/providers/screen/animation/helpers/pipeline.d.ts +1 -1
- package/lib/typescript/shared/providers/screen/animation/helpers/pipeline.d.ts.map +1 -1
- package/lib/typescript/shared/providers/screen/animation/helpers/read-screen-animation-revisions.d.ts +3 -0
- package/lib/typescript/shared/providers/screen/animation/helpers/read-screen-animation-revisions.d.ts.map +1 -0
- package/lib/typescript/shared/providers/screen/animation/use-screen-animation.d.ts.map +1 -1
- package/lib/typescript/shared/providers/screen/gestures/ownership/shadowing-claims.d.ts +8 -0
- package/lib/typescript/shared/providers/screen/gestures/ownership/shadowing-claims.d.ts.map +1 -0
- package/lib/typescript/shared/providers/screen/gestures/ownership/use-walk-up-and-register-shadowing-claims.d.ts.map +1 -1
- package/lib/typescript/shared/providers/screen/styles/hooks/use-interpolated-style-maps.d.ts.map +1 -1
- package/lib/typescript/shared/providers/stack/helpers/managed-stack-state/helpers/build-managed-stack-state.d.ts.map +1 -1
- package/lib/typescript/shared/providers/stack/helpers/managed-stack-state/helpers/types.d.ts +2 -3
- package/lib/typescript/shared/providers/stack/helpers/managed-stack-state/helpers/types.d.ts.map +1 -1
- package/lib/typescript/shared/types/animation.types.d.ts +14 -0
- package/lib/typescript/shared/types/animation.types.d.ts.map +1 -1
- package/lib/typescript/shared/types/index.d.ts +1 -1
- package/lib/typescript/shared/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/shared/index.ts +3 -0
- package/src/shared/providers/screen/animation/helpers/accessors/use-build-transition-accessor.ts +14 -0
- package/src/shared/providers/screen/animation/helpers/pipeline.ts +4 -1
- package/src/shared/providers/screen/animation/helpers/read-screen-animation-revisions.ts +25 -0
- package/src/shared/providers/screen/animation/use-screen-animation.tsx +1 -21
- package/src/shared/providers/screen/gestures/ownership/shadowing-claims.ts +18 -0
- package/src/shared/providers/screen/gestures/ownership/use-walk-up-and-register-shadowing-claims.ts +64 -3
- package/src/shared/providers/screen/styles/hooks/use-interpolated-style-maps.tsx +15 -1
- package/src/shared/providers/stack/helpers/managed-stack-state/helpers/build-managed-stack-state.ts +38 -24
- package/src/shared/providers/stack/helpers/managed-stack-state/helpers/types.ts +2 -3
- package/src/shared/types/animation.types.ts +18 -0
- package/src/shared/types/index.ts +3 -0
package/package.json
CHANGED
package/src/shared/index.ts
CHANGED
|
@@ -61,7 +61,10 @@ export type {
|
|
|
61
61
|
OverlayProps,
|
|
62
62
|
ScreenInterpolationProps,
|
|
63
63
|
ScreenStyleInterpolator,
|
|
64
|
+
ScreenTransitionAccessor,
|
|
64
65
|
ScreenTransitionConfig,
|
|
66
|
+
ScreenTransitionDepthTarget,
|
|
67
|
+
ScreenTransitionTarget,
|
|
65
68
|
TransitionInterpolatedStyle,
|
|
66
69
|
TransitionSlotStyle,
|
|
67
70
|
TransitionSpec,
|
package/src/shared/providers/screen/animation/helpers/accessors/use-build-transition-accessor.ts
CHANGED
|
@@ -72,6 +72,20 @@ export const createTransitionAccessor = (
|
|
|
72
72
|
return {
|
|
73
73
|
...frame,
|
|
74
74
|
bounds: source.boundsAccessor,
|
|
75
|
+
transition: (target?: ScreenTransitionTarget) => {
|
|
76
|
+
"worklet";
|
|
77
|
+
const targetIndex = resolveTargetIndex(
|
|
78
|
+
target,
|
|
79
|
+
sourceIndex,
|
|
80
|
+
currentSources.length,
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
if (targetIndex === -1) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return buildScope(targetIndex);
|
|
88
|
+
},
|
|
75
89
|
};
|
|
76
90
|
};
|
|
77
91
|
|
|
@@ -23,7 +23,10 @@ import type { SelectedInterpolatorOptions } from "./selected-interpolator-option
|
|
|
23
23
|
import { deriveStackProgress } from "./stack-progress";
|
|
24
24
|
import { useBuildTransitionState } from "./use-build-transition-state";
|
|
25
25
|
|
|
26
|
-
export type ScreenInterpolatorFrame = Omit<
|
|
26
|
+
export type ScreenInterpolatorFrame = Omit<
|
|
27
|
+
ScreenInterpolationProps,
|
|
28
|
+
"bounds" | "transition"
|
|
29
|
+
>;
|
|
27
30
|
|
|
28
31
|
interface ScreenAnimationPipeline {
|
|
29
32
|
screenInterpolatorProps: SharedValue<ScreenInterpolatorFrame>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ScreenAnimationDescendantSources,
|
|
3
|
+
ScreenAnimationSource,
|
|
4
|
+
ScreenInterpolatorPropsRevision,
|
|
5
|
+
} from "../types";
|
|
6
|
+
|
|
7
|
+
export const readScreenAnimationRevisions = (
|
|
8
|
+
screenInterpolatorPropsRevision: ScreenInterpolatorPropsRevision,
|
|
9
|
+
ancestorScreenAnimationSources: ScreenAnimationSource[],
|
|
10
|
+
descendantScreenAnimationSources: ScreenAnimationDescendantSources,
|
|
11
|
+
) => {
|
|
12
|
+
"worklet";
|
|
13
|
+
screenInterpolatorPropsRevision.get();
|
|
14
|
+
|
|
15
|
+
for (let index = 0; index < ancestorScreenAnimationSources.length; index++) {
|
|
16
|
+
ancestorScreenAnimationSources[
|
|
17
|
+
index
|
|
18
|
+
]?.screenInterpolatorPropsRevision.get();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const descendantSources = descendantScreenAnimationSources.get();
|
|
22
|
+
for (let index = 0; index < descendantSources.length; index++) {
|
|
23
|
+
descendantSources[index]?.source.screenInterpolatorPropsRevision.get();
|
|
24
|
+
}
|
|
25
|
+
};
|
|
@@ -5,10 +5,9 @@ import type {
|
|
|
5
5
|
} from "../../../types/animation.types";
|
|
6
6
|
import { useScreenAnimationContext } from "./animation.provider";
|
|
7
7
|
import { useBuildTransitionAccessor } from "./helpers/accessors/use-build-transition-accessor";
|
|
8
|
+
import { readScreenAnimationRevisions } from "./helpers/read-screen-animation-revisions";
|
|
8
9
|
import type {
|
|
9
|
-
ScreenAnimationDescendantSources,
|
|
10
10
|
ScreenAnimationLegacyTarget,
|
|
11
|
-
ScreenAnimationSource,
|
|
12
11
|
ScreenAnimationTarget,
|
|
13
12
|
} from "./types";
|
|
14
13
|
|
|
@@ -58,25 +57,6 @@ export function useScreenAnimation(
|
|
|
58
57
|
return animation;
|
|
59
58
|
}
|
|
60
59
|
|
|
61
|
-
const readScreenAnimationRevisions = (
|
|
62
|
-
screenInterpolatorPropsRevision: DerivedValue<number>,
|
|
63
|
-
ancestorScreenAnimationSources: ScreenAnimationSource[],
|
|
64
|
-
descendantScreenAnimationSources: ScreenAnimationDescendantSources,
|
|
65
|
-
) => {
|
|
66
|
-
"worklet";
|
|
67
|
-
screenInterpolatorPropsRevision.get();
|
|
68
|
-
|
|
69
|
-
for (let index = 0; index < ancestorScreenAnimationSources.length; index++) {
|
|
70
|
-
ancestorScreenAnimationSources[
|
|
71
|
-
index
|
|
72
|
-
]?.screenInterpolatorPropsRevision.get();
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// The accessor reads descendant sources through this shared value. Reading it
|
|
76
|
-
// here makes this derived value rerun when descendants mount or unmount.
|
|
77
|
-
descendantScreenAnimationSources.get();
|
|
78
|
-
};
|
|
79
|
-
|
|
80
60
|
const isTransitionTarget = (
|
|
81
61
|
target: ScreenAnimationTarget,
|
|
82
62
|
): target is ScreenTransitionTarget => {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ClaimedDirections } from "../../../../types/ownership.types";
|
|
2
|
+
import type { StackSceneActivity } from "../../../../types/stack.types";
|
|
3
|
+
|
|
4
|
+
export const resolveShadowingClaimDirections = ({
|
|
5
|
+
currentActivity,
|
|
6
|
+
currentClaimedDirections,
|
|
7
|
+
previousClaimedDirections,
|
|
8
|
+
}: {
|
|
9
|
+
currentActivity: StackSceneActivity | undefined;
|
|
10
|
+
currentClaimedDirections: ClaimedDirections;
|
|
11
|
+
previousClaimedDirections: ClaimedDirections;
|
|
12
|
+
}): ClaimedDirections => {
|
|
13
|
+
if (currentActivity === "closing") {
|
|
14
|
+
return previousClaimedDirections;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return currentClaimedDirections;
|
|
18
|
+
};
|
package/src/shared/providers/screen/gestures/ownership/use-walk-up-and-register-shadowing-claims.ts
CHANGED
|
@@ -4,11 +4,18 @@ import {
|
|
|
4
4
|
type ClaimedDirections,
|
|
5
5
|
DIRECTIONS,
|
|
6
6
|
type Direction,
|
|
7
|
+
NO_CLAIMS,
|
|
7
8
|
} from "../../../../types/ownership.types";
|
|
8
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
type BaseDescriptor,
|
|
11
|
+
useDescriptorDerivations,
|
|
12
|
+
useDescriptors,
|
|
13
|
+
} from "../../../screen/descriptors";
|
|
9
14
|
import { useGestureContext } from "../gestures.provider";
|
|
10
15
|
import { walkGestureAncestors } from "../shared/ancestors";
|
|
16
|
+
import { resolveScreenGestureConfig } from "../shared/policy";
|
|
11
17
|
import type { GestureContextType } from "../types";
|
|
18
|
+
import { resolveShadowingClaimDirections } from "./shadowing-claims";
|
|
12
19
|
|
|
13
20
|
type ShadowedAncestor = {
|
|
14
21
|
ancestor: GestureContextType;
|
|
@@ -93,6 +100,27 @@ const clearShadowingClaims = (
|
|
|
93
100
|
}
|
|
94
101
|
};
|
|
95
102
|
|
|
103
|
+
const getDescriptorIsFirstKey = (descriptor: BaseDescriptor): boolean => {
|
|
104
|
+
const navigationState = descriptor.navigation.getState();
|
|
105
|
+
const routes = navigationState?.routes ?? [];
|
|
106
|
+
return routes.findIndex((route) => route.key === descriptor.route.key) === 0;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const getDescriptorClaimedDirections = (
|
|
110
|
+
descriptor: BaseDescriptor | undefined,
|
|
111
|
+
gestureContext: GestureContextType | null,
|
|
112
|
+
): ClaimedDirections => {
|
|
113
|
+
if (!descriptor) {
|
|
114
|
+
return NO_CLAIMS;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return resolveScreenGestureConfig({
|
|
118
|
+
options: descriptor.options,
|
|
119
|
+
isFirstKey: getDescriptorIsFirstKey(descriptor),
|
|
120
|
+
gestureContext,
|
|
121
|
+
}).participation.claimedDirections;
|
|
122
|
+
};
|
|
123
|
+
|
|
96
124
|
/**
|
|
97
125
|
* Registers this screen with ancestors that claim the same direction.
|
|
98
126
|
*
|
|
@@ -108,11 +136,44 @@ export function useWalkUpAndRegisterShadowingClaims(
|
|
|
108
136
|
claimedDirections: ClaimedDirections,
|
|
109
137
|
): void {
|
|
110
138
|
const parentContext = useGestureContext();
|
|
139
|
+
const { current, previous } = useDescriptors();
|
|
111
140
|
const { isTopMostScreen, currentScreenKey } = useDescriptorDerivations();
|
|
112
141
|
|
|
142
|
+
/*
|
|
143
|
+
* We want to calculate effective claimed directions as claimedDirections is not enough for us.
|
|
144
|
+
* What this solves is lingering claimed directions when a screen is closing.
|
|
145
|
+
*
|
|
146
|
+
* Overlay claims horizontal
|
|
147
|
+
* └─ A has no local horizontal claim
|
|
148
|
+
* └─ B claims horizontal (closing)
|
|
149
|
+
* └─ C claims horizontal (closing)
|
|
150
|
+
*
|
|
151
|
+
* Closing screens are still mounted, so they can still block parent gestures.
|
|
152
|
+
* But they cannot receive touches anymore.
|
|
153
|
+
*
|
|
154
|
+
* So when B/C are closing and the user is really touching A, B/C should not
|
|
155
|
+
* keep blocking the parent with their own gesture config.
|
|
156
|
+
*
|
|
157
|
+
* A closing screen should act like the visible screen underneath it:
|
|
158
|
+
* - if the screen underneath claims the gesture, keep blocking the parent
|
|
159
|
+
* - if the screen underneath does not claim it, let the parent handle it
|
|
160
|
+
*/
|
|
161
|
+
const effectiveClaimedDirections = useMemo(
|
|
162
|
+
() =>
|
|
163
|
+
resolveShadowingClaimDirections({
|
|
164
|
+
currentActivity: current.activity,
|
|
165
|
+
currentClaimedDirections: claimedDirections,
|
|
166
|
+
previousClaimedDirections: getDescriptorClaimedDirections(
|
|
167
|
+
previous,
|
|
168
|
+
parentContext,
|
|
169
|
+
),
|
|
170
|
+
}),
|
|
171
|
+
[current.activity, claimedDirections, previous, parentContext],
|
|
172
|
+
);
|
|
173
|
+
|
|
113
174
|
const shadowedAncestors = useMemo(
|
|
114
|
-
() => findShadowedAncestors(parentContext,
|
|
115
|
-
[parentContext,
|
|
175
|
+
() => findShadowedAncestors(parentContext, effectiveClaimedDirections),
|
|
176
|
+
[parentContext, effectiveClaimedDirections],
|
|
116
177
|
);
|
|
117
178
|
|
|
118
179
|
useLayoutEffect(() => {
|
|
@@ -9,7 +9,9 @@ import type {
|
|
|
9
9
|
import { logger } from "../../../../utils/logger";
|
|
10
10
|
import { useScreenAnimationContext } from "../../animation";
|
|
11
11
|
import { useBuildBoundsAccessor } from "../../animation/helpers/accessors/use-build-bounds-accessor";
|
|
12
|
+
import { useBuildTransitionAccessor } from "../../animation/helpers/accessors/use-build-transition-accessor";
|
|
12
13
|
import type { ScreenInterpolatorFrame } from "../../animation/helpers/pipeline";
|
|
14
|
+
import { readScreenAnimationRevisions } from "../../animation/helpers/read-screen-animation-revisions";
|
|
13
15
|
import { syncSelectedInterpolatorOptions } from "../../animation/helpers/selected-interpolator-options";
|
|
14
16
|
import { useDescriptorDerivations } from "../../descriptors";
|
|
15
17
|
import {
|
|
@@ -34,6 +36,7 @@ type RunInterpolatorParams = {
|
|
|
34
36
|
progress: ScreenInterpolatorFrame["progress"];
|
|
35
37
|
next: ScreenInterpolatorFrame["next"];
|
|
36
38
|
bounds: Parameters<ScreenStyleInterpolator>[0]["bounds"];
|
|
39
|
+
transition: Parameters<ScreenStyleInterpolator>[0]["transition"];
|
|
37
40
|
shouldDeferStyleBuckets: boolean;
|
|
38
41
|
};
|
|
39
42
|
|
|
@@ -60,6 +63,7 @@ const runInterpolator = ({
|
|
|
60
63
|
progress,
|
|
61
64
|
next,
|
|
62
65
|
bounds,
|
|
66
|
+
transition,
|
|
63
67
|
shouldDeferStyleBuckets,
|
|
64
68
|
}: RunInterpolatorParams): InterpolatorResult | undefined => {
|
|
65
69
|
"worklet";
|
|
@@ -74,6 +78,7 @@ const runInterpolator = ({
|
|
|
74
78
|
progress,
|
|
75
79
|
next,
|
|
76
80
|
bounds,
|
|
81
|
+
transition,
|
|
77
82
|
});
|
|
78
83
|
|
|
79
84
|
const rawStyleMap: TransitionInterpolatedStyle | undefined =
|
|
@@ -137,8 +142,11 @@ export const useInterpolatedStylesMap = () => {
|
|
|
137
142
|
selectedInterpolatorOptions,
|
|
138
143
|
nextInterpolator,
|
|
139
144
|
currentInterpolator,
|
|
145
|
+
ancestorScreenAnimationSources,
|
|
146
|
+
descendantScreenAnimationSources,
|
|
140
147
|
} = useScreenAnimationContext();
|
|
141
148
|
const boundsAccessor = useBuildBoundsAccessor();
|
|
149
|
+
const transition = useBuildTransitionAccessor();
|
|
142
150
|
const pendingLifecycleStartBlockCount = SystemStore.getValue(
|
|
143
151
|
currentScreenKey,
|
|
144
152
|
"pendingLifecycleStartBlockCount",
|
|
@@ -148,7 +156,11 @@ export const useInterpolatedStylesMap = () => {
|
|
|
148
156
|
|
|
149
157
|
return useDerivedValue<LocalStyleLayers>(() => {
|
|
150
158
|
"worklet";
|
|
151
|
-
|
|
159
|
+
readScreenAnimationRevisions(
|
|
160
|
+
screenInterpolatorPropsRevision,
|
|
161
|
+
ancestorScreenAnimationSources,
|
|
162
|
+
descendantScreenAnimationSources,
|
|
163
|
+
);
|
|
152
164
|
const props = screenInterpolatorProps.get();
|
|
153
165
|
|
|
154
166
|
/**
|
|
@@ -199,6 +211,7 @@ export const useInterpolatedStylesMap = () => {
|
|
|
199
211
|
progress: effectiveProgress,
|
|
200
212
|
next: effectiveNext,
|
|
201
213
|
bounds: boundsAccessor,
|
|
214
|
+
transition,
|
|
202
215
|
shouldDeferStyleBuckets,
|
|
203
216
|
});
|
|
204
217
|
|
|
@@ -223,6 +236,7 @@ export const useInterpolatedStylesMap = () => {
|
|
|
223
236
|
progress: effectiveProgress,
|
|
224
237
|
next: effectiveNext,
|
|
225
238
|
bounds: boundsAccessor,
|
|
239
|
+
transition,
|
|
226
240
|
shouldDeferStyleBuckets,
|
|
227
241
|
});
|
|
228
242
|
|
package/src/shared/providers/stack/helpers/managed-stack-state/helpers/build-managed-stack-state.ts
CHANGED
|
@@ -59,11 +59,10 @@ const resolveStableDescriptorSource = <
|
|
|
59
59
|
};
|
|
60
60
|
|
|
61
61
|
const getSceneActivity = ({
|
|
62
|
-
|
|
62
|
+
activeIndex,
|
|
63
|
+
inertIndex,
|
|
63
64
|
isClosing,
|
|
64
65
|
sceneIndex,
|
|
65
|
-
topIndex,
|
|
66
|
-
topIsClosing,
|
|
67
66
|
}: SceneActivityWindow & {
|
|
68
67
|
isClosing: boolean;
|
|
69
68
|
sceneIndex: number;
|
|
@@ -72,21 +71,33 @@ const getSceneActivity = ({
|
|
|
72
71
|
return "closing";
|
|
73
72
|
}
|
|
74
73
|
|
|
75
|
-
if (
|
|
76
|
-
return sceneIndex === focusedIndex ? "inert" : "inactive";
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (sceneIndex === topIndex) {
|
|
74
|
+
if (sceneIndex === activeIndex) {
|
|
80
75
|
return "active";
|
|
81
76
|
}
|
|
82
77
|
|
|
83
|
-
if (sceneIndex ===
|
|
78
|
+
if (sceneIndex === inertIndex) {
|
|
84
79
|
return "inert";
|
|
85
80
|
}
|
|
86
81
|
|
|
87
82
|
return "inactive";
|
|
88
83
|
};
|
|
89
84
|
|
|
85
|
+
const getNonClosingSceneIndices = <TDescriptor extends BaseStackDescriptor>(
|
|
86
|
+
routes: ManagedRoutes<TDescriptor>,
|
|
87
|
+
closingRouteKeys: ReadonlySet<string>,
|
|
88
|
+
) => {
|
|
89
|
+
const indices: number[] = [];
|
|
90
|
+
|
|
91
|
+
for (let index = 0; index < routes.length; index++) {
|
|
92
|
+
const route = routes[index];
|
|
93
|
+
if (route && !closingRouteKeys.has(route.key)) {
|
|
94
|
+
indices.push(index);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return indices;
|
|
99
|
+
};
|
|
100
|
+
|
|
90
101
|
const getSceneActivityWindow = <
|
|
91
102
|
TDescriptor extends BaseStackDescriptor,
|
|
92
103
|
TNavigation extends BaseStackNavigation,
|
|
@@ -98,29 +109,32 @@ const getSceneActivityWindow = <
|
|
|
98
109
|
TDescriptor,
|
|
99
110
|
TNavigation
|
|
100
111
|
>): SceneActivityWindow => {
|
|
101
|
-
const
|
|
112
|
+
const nonClosingIndices = getNonClosingSceneIndices(routes, closingRouteKeys);
|
|
102
113
|
|
|
103
|
-
|
|
114
|
+
const topNonClosingIndex =
|
|
115
|
+
nonClosingIndices[nonClosingIndices.length - 1] ?? -1;
|
|
104
116
|
|
|
105
|
-
|
|
117
|
+
const hasClosingRouteAboveActive =
|
|
118
|
+
topNonClosingIndex !== -1 && topNonClosingIndex < routes.length - 1;
|
|
119
|
+
|
|
120
|
+
const activeIndex = hasClosingRouteAboveActive ? -1 : topNonClosingIndex;
|
|
121
|
+
const inertIndex = hasClosingRouteAboveActive
|
|
122
|
+
? topNonClosingIndex
|
|
123
|
+
: (nonClosingIndices[nonClosingIndices.length - 2] ?? -1);
|
|
124
|
+
|
|
125
|
+
const focusedRouteKey = props.state.routes[props.state.index]?.key;
|
|
126
|
+
if (
|
|
127
|
+
focusedRouteKey &&
|
|
128
|
+
!routes.some((route) => route.key === focusedRouteKey)
|
|
129
|
+
) {
|
|
106
130
|
throw new Error(
|
|
107
131
|
`Focused route "${focusedRouteKey}" is missing from routes`,
|
|
108
132
|
);
|
|
109
133
|
}
|
|
110
134
|
|
|
111
|
-
while (focusedIndex > 0 && closingRouteKeys.has(routes[focusedIndex]?.key)) {
|
|
112
|
-
focusedIndex--;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const topIndex = routes.length - 1;
|
|
116
|
-
const topRoute = routes[topIndex];
|
|
117
|
-
const topIsClosing =
|
|
118
|
-
topRoute !== undefined && closingRouteKeys.has(topRoute.key);
|
|
119
|
-
|
|
120
135
|
return {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
topIsClosing,
|
|
136
|
+
activeIndex,
|
|
137
|
+
inertIndex,
|
|
124
138
|
};
|
|
125
139
|
};
|
|
126
140
|
|
|
@@ -176,6 +176,10 @@ export type ScreenTransitionDepthTarget = {
|
|
|
176
176
|
|
|
177
177
|
export type ScreenTransitionTarget = ScreenTransitionDepthTarget;
|
|
178
178
|
|
|
179
|
+
export type ScreenTransitionAccessor = (
|
|
180
|
+
target?: ScreenTransitionTarget,
|
|
181
|
+
) => ScreenInterpolationProps | null;
|
|
182
|
+
|
|
179
183
|
export interface ScreenInterpolationProps {
|
|
180
184
|
/**
|
|
181
185
|
* Values for the screen that came before the current one in the navigation stack.
|
|
@@ -239,6 +243,20 @@ export interface ScreenInterpolationProps {
|
|
|
239
243
|
*/
|
|
240
244
|
bounds: BoundsAccessor;
|
|
241
245
|
|
|
246
|
+
/**
|
|
247
|
+
* Resolves interpolation props for this screen's transition timeline or an
|
|
248
|
+
* ancestor/descendant transition timeline.
|
|
249
|
+
*
|
|
250
|
+
* Calling without a target returns the current transition.
|
|
251
|
+
* `transition({ depth: -1 })` returns the immediate parent transition.
|
|
252
|
+
* `transition({ depth: 1 })` returns the immediate child transition.
|
|
253
|
+
* `transition({ depth: 0 })` returns the current transition.
|
|
254
|
+
*
|
|
255
|
+
* When called from a returned transition scope, targets are resolved relative
|
|
256
|
+
* to that scope.
|
|
257
|
+
*/
|
|
258
|
+
transition: ScreenTransitionAccessor;
|
|
259
|
+
|
|
242
260
|
/**
|
|
243
261
|
* The screen state that is currently driving the transition (either current or next, whichever is focused).
|
|
244
262
|
*/
|
|
@@ -4,8 +4,11 @@ export type {
|
|
|
4
4
|
AnimationConfig,
|
|
5
5
|
ScreenInterpolationProps,
|
|
6
6
|
ScreenStyleInterpolator,
|
|
7
|
+
ScreenTransitionAccessor,
|
|
8
|
+
ScreenTransitionDepthTarget,
|
|
7
9
|
ScreenTransitionOptions,
|
|
8
10
|
ScreenTransitionState,
|
|
11
|
+
ScreenTransitionTarget,
|
|
9
12
|
TransitionInterpolatedStyle,
|
|
10
13
|
TransitionInterpolatorOptions,
|
|
11
14
|
TransitionSlotStyle,
|