react-native-screen-transitions 3.0.0-rc.2 → 3.0.0-rc.4
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/README.md +421 -371
- package/lib/commonjs/blank-stack/components/{Overlay.js → overlay.js} +7 -5
- package/lib/commonjs/blank-stack/components/overlay.js.map +1 -0
- package/lib/commonjs/blank-stack/components/{Screens.js → screens.js} +20 -17
- package/lib/commonjs/blank-stack/components/screens.js.map +1 -0
- package/lib/commonjs/blank-stack/components/stack-view.js +101 -0
- package/lib/commonjs/blank-stack/components/stack-view.js.map +1 -0
- package/lib/commonjs/blank-stack/index.js +1 -8
- package/lib/commonjs/blank-stack/index.js.map +1 -1
- package/lib/commonjs/blank-stack/navigators/{createBlankStackNavigator.js → create-blank-stack-navigator.js} +3 -3
- package/lib/commonjs/blank-stack/navigators/create-blank-stack-navigator.js.map +1 -0
- package/lib/commonjs/blank-stack/utils/with-stack-navigation/helpers/compose-descriptors.js +1 -11
- package/lib/commonjs/blank-stack/utils/with-stack-navigation/helpers/compose-descriptors.js.map +1 -1
- package/lib/commonjs/blank-stack/utils/with-stack-navigation/hooks/use-closing-route-keys.js +1 -12
- package/lib/commonjs/blank-stack/utils/with-stack-navigation/hooks/use-closing-route-keys.js.map +1 -1
- package/lib/commonjs/blank-stack/utils/with-stack-navigation/hooks/use-stack-navigation-state.js.map +1 -1
- package/lib/commonjs/blank-stack/utils/with-stack-navigation/index.js +49 -55
- package/lib/commonjs/blank-stack/utils/with-stack-navigation/index.js.map +1 -1
- package/lib/commonjs/blank-stack/utils/with-stack-navigation/{_types.js → types.js} +1 -1
- package/lib/commonjs/blank-stack/utils/with-stack-navigation/types.js.map +1 -0
- package/lib/commonjs/native-stack/views/NativeStackView.native.js +110 -103
- package/lib/commonjs/native-stack/views/NativeStackView.native.js.map +1 -1
- package/lib/commonjs/shared/components/controllers/blank-stack-lifecycle.js +72 -0
- package/lib/commonjs/shared/components/controllers/blank-stack-lifecycle.js.map +1 -0
- package/lib/commonjs/shared/components/controllers/native-stack-lifecycle.js +79 -0
- package/lib/commonjs/shared/components/controllers/native-stack-lifecycle.js.map +1 -0
- package/lib/commonjs/shared/hooks/animation/use-screen-animation.js +49 -23
- package/lib/commonjs/shared/hooks/animation/use-screen-animation.js.map +1 -1
- package/lib/commonjs/shared/hooks/gestures/use-build-gestures.js +11 -6
- package/lib/commonjs/shared/hooks/gestures/use-build-gestures.js.map +1 -1
- package/lib/commonjs/shared/hooks/gestures/use-scroll-registry.js +7 -7
- package/lib/commonjs/shared/hooks/gestures/use-scroll-registry.js.map +1 -1
- package/lib/commonjs/shared/providers/flags.provider.js +25 -0
- package/lib/commonjs/shared/providers/flags.provider.js.map +1 -0
- package/lib/commonjs/shared/providers/gestures.provider.js +32 -5
- package/lib/commonjs/shared/providers/gestures.provider.js.map +1 -1
- package/lib/commonjs/shared/providers/register-bounds.provider.js +72 -45
- package/lib/commonjs/shared/providers/register-bounds.provider.js.map +1 -1
- package/lib/commonjs/shared/providers/routes.provider.js +48 -0
- package/lib/commonjs/shared/providers/routes.provider.js.map +1 -0
- package/lib/commonjs/shared/providers/screen-transition.provider.js.map +1 -1
- package/lib/commonjs/shared/stores/bounds.store.js +91 -47
- package/lib/commonjs/shared/stores/bounds.store.js.map +1 -1
- package/lib/commonjs/shared/types/state.types.js +9 -0
- package/lib/commonjs/shared/types/state.types.js.map +1 -0
- package/lib/commonjs/shared/utils/animation/compute-stack-progress.js +20 -0
- package/lib/commonjs/shared/utils/animation/compute-stack-progress.js.map +1 -0
- package/lib/commonjs/shared/utils/animation/derivations.js +1 -1
- package/lib/commonjs/shared/utils/animation/start-screen-transition.js +11 -11
- package/lib/commonjs/shared/utils/animation/start-screen-transition.js.map +1 -1
- package/lib/commonjs/shared/utils/bounds/helpers/is-bounds-equal.js +1 -1
- package/lib/commonjs/shared/utils/bounds/helpers/is-bounds-equal.js.map +1 -1
- package/lib/commonjs/shared/utils/bounds/index.js +4 -5
- package/lib/commonjs/shared/utils/bounds/index.js.map +1 -1
- package/lib/commonjs/shared/utils/create-provider.js +20 -1
- package/lib/commonjs/shared/utils/create-provider.js.map +1 -1
- package/lib/commonjs/shared/utils/reset-stores-for-screen.js +2 -0
- package/lib/commonjs/shared/utils/reset-stores-for-screen.js.map +1 -1
- package/lib/module/blank-stack/components/{Overlay.js → overlay.js} +7 -5
- package/lib/module/blank-stack/components/overlay.js.map +1 -0
- package/lib/module/blank-stack/components/screens.js +61 -0
- package/lib/module/blank-stack/components/screens.js.map +1 -0
- package/lib/module/blank-stack/components/stack-view.js +96 -0
- package/lib/module/blank-stack/components/stack-view.js.map +1 -0
- package/lib/module/blank-stack/index.js +1 -2
- package/lib/module/blank-stack/index.js.map +1 -1
- package/lib/module/blank-stack/navigators/{createBlankStackNavigator.js → create-blank-stack-navigator.js} +2 -2
- package/lib/module/blank-stack/navigators/create-blank-stack-navigator.js.map +1 -0
- package/lib/module/blank-stack/utils/with-stack-navigation/helpers/compose-descriptors.js +1 -11
- package/lib/module/blank-stack/utils/with-stack-navigation/helpers/compose-descriptors.js.map +1 -1
- package/lib/module/blank-stack/utils/with-stack-navigation/hooks/use-closing-route-keys.js +1 -12
- package/lib/module/blank-stack/utils/with-stack-navigation/hooks/use-closing-route-keys.js.map +1 -1
- package/lib/module/blank-stack/utils/with-stack-navigation/hooks/use-stack-navigation-state.js.map +1 -1
- package/lib/module/blank-stack/utils/with-stack-navigation/index.js +48 -54
- package/lib/module/blank-stack/utils/with-stack-navigation/index.js.map +1 -1
- package/lib/module/blank-stack/utils/with-stack-navigation/types.js +4 -0
- package/lib/module/blank-stack/utils/with-stack-navigation/types.js.map +1 -0
- package/lib/module/native-stack/views/NativeStackView.native.js +109 -102
- package/lib/module/native-stack/views/NativeStackView.native.js.map +1 -1
- package/lib/module/shared/components/controllers/blank-stack-lifecycle.js +66 -0
- package/lib/module/shared/components/controllers/blank-stack-lifecycle.js.map +1 -0
- package/lib/module/shared/components/controllers/native-stack-lifecycle.js +73 -0
- package/lib/module/shared/components/controllers/native-stack-lifecycle.js.map +1 -0
- package/lib/module/shared/hooks/animation/use-screen-animation.js +49 -23
- package/lib/module/shared/hooks/animation/use-screen-animation.js.map +1 -1
- package/lib/module/shared/hooks/gestures/use-build-gestures.js +11 -6
- package/lib/module/shared/hooks/gestures/use-build-gestures.js.map +1 -1
- package/lib/module/shared/hooks/gestures/use-scroll-registry.js +7 -7
- package/lib/module/shared/hooks/gestures/use-scroll-registry.js.map +1 -1
- package/lib/module/shared/providers/flags.provider.js +19 -0
- package/lib/module/shared/providers/flags.provider.js.map +1 -0
- package/lib/module/shared/providers/gestures.provider.js +31 -4
- package/lib/module/shared/providers/gestures.provider.js.map +1 -1
- package/lib/module/shared/providers/register-bounds.provider.js +72 -45
- package/lib/module/shared/providers/register-bounds.provider.js.map +1 -1
- package/lib/module/shared/providers/routes.provider.js +42 -0
- package/lib/module/shared/providers/routes.provider.js.map +1 -0
- package/lib/module/shared/providers/screen-transition.provider.js.map +1 -1
- package/lib/module/shared/stores/bounds.store.js +91 -47
- package/lib/module/shared/stores/bounds.store.js.map +1 -1
- package/lib/module/shared/types/state.types.js +5 -0
- package/lib/module/shared/types/state.types.js.map +1 -0
- package/lib/module/shared/utils/animation/compute-stack-progress.js +15 -0
- package/lib/module/shared/utils/animation/compute-stack-progress.js.map +1 -0
- package/lib/module/shared/utils/animation/derivations.js +1 -1
- package/lib/module/shared/utils/animation/start-screen-transition.js +11 -11
- package/lib/module/shared/utils/animation/start-screen-transition.js.map +1 -1
- package/lib/module/shared/utils/bounds/helpers/is-bounds-equal.js +1 -1
- package/lib/module/shared/utils/bounds/helpers/is-bounds-equal.js.map +1 -1
- package/lib/module/shared/utils/bounds/index.js +4 -5
- package/lib/module/shared/utils/bounds/index.js.map +1 -1
- package/lib/module/shared/utils/create-provider.js +20 -1
- package/lib/module/shared/utils/create-provider.js.map +1 -1
- package/lib/module/shared/utils/reset-stores-for-screen.js +2 -0
- package/lib/module/shared/utils/reset-stores-for-screen.js.map +1 -1
- package/lib/typescript/blank-stack/components/{Overlay.d.ts → overlay.d.ts} +1 -1
- package/lib/typescript/blank-stack/components/overlay.d.ts.map +1 -0
- package/lib/typescript/blank-stack/components/{Screens.d.ts → screens.d.ts} +1 -1
- package/lib/typescript/blank-stack/components/screens.d.ts.map +1 -0
- package/lib/typescript/blank-stack/components/stack-view.d.ts +3 -0
- package/lib/typescript/blank-stack/components/stack-view.d.ts.map +1 -0
- package/lib/typescript/blank-stack/index.d.ts +1 -2
- package/lib/typescript/blank-stack/index.d.ts.map +1 -1
- package/lib/typescript/blank-stack/navigators/{createBlankStackNavigator.d.ts → create-blank-stack-navigator.d.ts} +1 -1
- package/lib/typescript/blank-stack/navigators/create-blank-stack-navigator.d.ts.map +1 -0
- package/lib/typescript/blank-stack/types.d.ts +5 -39
- package/lib/typescript/blank-stack/types.d.ts.map +1 -1
- package/lib/typescript/blank-stack/utils/with-stack-navigation/helpers/compose-descriptors.d.ts.map +1 -1
- package/lib/typescript/blank-stack/utils/with-stack-navigation/hooks/use-closing-route-keys.d.ts.map +1 -1
- package/lib/typescript/blank-stack/utils/with-stack-navigation/hooks/use-stack-navigation-state.d.ts +1 -1
- package/lib/typescript/blank-stack/utils/with-stack-navigation/hooks/use-stack-navigation-state.d.ts.map +1 -1
- package/lib/typescript/blank-stack/utils/with-stack-navigation/index.d.ts +3 -5
- package/lib/typescript/blank-stack/utils/with-stack-navigation/index.d.ts.map +1 -1
- package/lib/typescript/blank-stack/utils/with-stack-navigation/{_types.d.ts → types.d.ts} +1 -1
- package/lib/typescript/blank-stack/utils/with-stack-navigation/types.d.ts.map +1 -0
- package/lib/typescript/native-stack/views/NativeStackView.native.d.ts.map +1 -1
- package/lib/typescript/shared/components/controllers/blank-stack-lifecycle.d.ts +8 -0
- package/lib/typescript/shared/components/controllers/blank-stack-lifecycle.d.ts.map +1 -0
- package/lib/typescript/shared/components/controllers/native-stack-lifecycle.d.ts +8 -0
- package/lib/typescript/shared/components/controllers/native-stack-lifecycle.d.ts.map +1 -0
- package/lib/typescript/shared/hooks/animation/use-screen-animation.d.ts.map +1 -1
- package/lib/typescript/shared/hooks/gestures/use-build-gestures.d.ts +2 -2
- package/lib/typescript/shared/hooks/gestures/use-build-gestures.d.ts.map +1 -1
- package/lib/typescript/shared/index.d.ts +20 -20
- package/lib/typescript/shared/providers/flags.provider.d.ts +10 -0
- package/lib/typescript/shared/providers/flags.provider.d.ts.map +1 -0
- package/lib/typescript/shared/providers/gestures.provider.d.ts +8 -2
- package/lib/typescript/shared/providers/gestures.provider.d.ts.map +1 -1
- package/lib/typescript/shared/providers/register-bounds.provider.d.ts.map +1 -1
- package/lib/typescript/shared/providers/routes.provider.d.ts +19 -0
- package/lib/typescript/shared/providers/routes.provider.d.ts.map +1 -0
- package/lib/typescript/shared/providers/screen-transition.provider.d.ts +2 -2
- package/lib/typescript/shared/providers/screen-transition.provider.d.ts.map +1 -1
- package/lib/typescript/shared/stores/bounds.store.d.ts +23 -11
- package/lib/typescript/shared/stores/bounds.store.d.ts.map +1 -1
- package/lib/typescript/shared/types/animation.types.d.ts +12 -0
- package/lib/typescript/shared/types/animation.types.d.ts.map +1 -1
- package/lib/typescript/shared/types/bounds.types.d.ts +2 -2
- package/lib/typescript/shared/types/bounds.types.d.ts.map +1 -1
- package/lib/typescript/shared/types/state.types.d.ts +3 -0
- package/lib/typescript/shared/types/state.types.d.ts.map +1 -0
- package/lib/typescript/shared/utils/animation/compute-stack-progress.d.ts +3 -0
- package/lib/typescript/shared/utils/animation/compute-stack-progress.d.ts.map +1 -0
- package/lib/typescript/shared/utils/animation/start-screen-transition.d.ts.map +1 -1
- package/lib/typescript/shared/utils/bounds/index.d.ts.map +1 -1
- package/lib/typescript/shared/utils/create-provider.d.ts +2 -2
- package/lib/typescript/shared/utils/create-provider.d.ts.map +1 -1
- package/lib/typescript/shared/utils/reset-stores-for-screen.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/blank-stack/components/{Overlay.tsx → overlay.tsx} +4 -3
- package/src/blank-stack/components/{Screens.tsx → screens.tsx} +24 -20
- package/src/blank-stack/components/stack-view.tsx +115 -0
- package/src/blank-stack/index.ts +1 -2
- package/src/blank-stack/navigators/{createBlankStackNavigator.tsx → create-blank-stack-navigator.tsx} +1 -1
- package/src/blank-stack/types.ts +6 -31
- package/src/blank-stack/utils/with-stack-navigation/helpers/compose-descriptors.ts +1 -8
- package/src/blank-stack/utils/with-stack-navigation/hooks/use-closing-route-keys.tsx +1 -12
- package/src/blank-stack/utils/with-stack-navigation/hooks/use-stack-navigation-state.tsx +1 -1
- package/src/blank-stack/utils/with-stack-navigation/index.tsx +42 -62
- package/src/native-stack/views/NativeStackView.native.tsx +121 -112
- package/src/shared/__tests__/bounds.store.test.ts +376 -167
- package/src/shared/__tests__/determine-dismissal.test.ts +2 -12
- package/src/shared/__tests__/geometry.test.ts +1 -1
- package/src/shared/__tests__/gesture.velocity.test.ts +2 -10
- package/src/shared/components/controllers/blank-stack-lifecycle.tsx +70 -0
- package/src/shared/components/controllers/native-stack-lifecycle.tsx +87 -0
- package/src/shared/hooks/animation/use-screen-animation.tsx +61 -30
- package/src/shared/hooks/gestures/use-build-gestures.tsx +16 -7
- package/src/shared/hooks/gestures/use-scroll-registry.tsx +7 -7
- package/src/shared/providers/flags.provider.tsx +21 -0
- package/src/shared/providers/gestures.provider.tsx +34 -5
- package/src/shared/providers/register-bounds.provider.tsx +86 -54
- package/src/shared/providers/routes.provider.tsx +54 -0
- package/src/shared/providers/screen-transition.provider.tsx +2 -2
- package/src/shared/stores/bounds.store.ts +90 -54
- package/src/shared/types/animation.types.ts +13 -0
- package/src/shared/types/bounds.types.ts +2 -2
- package/src/shared/types/state.types.ts +2 -0
- package/src/shared/utils/animation/compute-stack-progress.ts +16 -0
- package/src/shared/utils/animation/derivations.ts +1 -1
- package/src/shared/utils/animation/start-screen-transition.ts +13 -10
- package/src/shared/utils/bounds/helpers/is-bounds-equal.ts +1 -1
- package/src/shared/utils/bounds/index.ts +7 -10
- package/src/shared/utils/create-provider.tsx +35 -1
- package/src/shared/utils/reset-stores-for-screen.ts +2 -0
- package/lib/commonjs/blank-stack/components/Overlay.js.map +0 -1
- package/lib/commonjs/blank-stack/components/Screens.js.map +0 -1
- package/lib/commonjs/blank-stack/components/StackView.js +0 -93
- package/lib/commonjs/blank-stack/components/StackView.js.map +0 -1
- package/lib/commonjs/blank-stack/navigators/createBlankStackNavigator.js.map +0 -1
- package/lib/commonjs/blank-stack/utils/with-stack-navigation/_types.js.map +0 -1
- package/lib/commonjs/shared/components/controllers/screen-lifecycle.js +0 -142
- package/lib/commonjs/shared/components/controllers/screen-lifecycle.js.map +0 -1
- package/lib/commonjs/shared/hooks/gestures/use-parent-gesture-registry.js +0 -28
- package/lib/commonjs/shared/hooks/gestures/use-parent-gesture-registry.js.map +0 -1
- package/lib/module/blank-stack/components/Overlay.js.map +0 -1
- package/lib/module/blank-stack/components/Screens.js +0 -58
- package/lib/module/blank-stack/components/Screens.js.map +0 -1
- package/lib/module/blank-stack/components/StackView.js +0 -88
- package/lib/module/blank-stack/components/StackView.js.map +0 -1
- package/lib/module/blank-stack/navigators/createBlankStackNavigator.js.map +0 -1
- package/lib/module/blank-stack/utils/with-stack-navigation/_types.js +0 -4
- package/lib/module/blank-stack/utils/with-stack-navigation/_types.js.map +0 -1
- package/lib/module/shared/components/controllers/screen-lifecycle.js +0 -136
- package/lib/module/shared/components/controllers/screen-lifecycle.js.map +0 -1
- package/lib/module/shared/hooks/gestures/use-parent-gesture-registry.js +0 -23
- package/lib/module/shared/hooks/gestures/use-parent-gesture-registry.js.map +0 -1
- package/lib/typescript/blank-stack/components/Overlay.d.ts.map +0 -1
- package/lib/typescript/blank-stack/components/Screens.d.ts.map +0 -1
- package/lib/typescript/blank-stack/components/StackView.d.ts +0 -2
- package/lib/typescript/blank-stack/components/StackView.d.ts.map +0 -1
- package/lib/typescript/blank-stack/navigators/createBlankStackNavigator.d.ts.map +0 -1
- package/lib/typescript/blank-stack/utils/with-stack-navigation/_types.d.ts.map +0 -1
- package/lib/typescript/shared/components/controllers/screen-lifecycle.d.ts +0 -12
- package/lib/typescript/shared/components/controllers/screen-lifecycle.d.ts.map +0 -1
- package/lib/typescript/shared/hooks/gestures/use-parent-gesture-registry.d.ts +0 -6
- package/lib/typescript/shared/hooks/gestures/use-parent-gesture-registry.d.ts.map +0 -1
- package/src/blank-stack/components/StackView.tsx +0 -108
- package/src/shared/components/controllers/screen-lifecycle.tsx +0 -154
- package/src/shared/hooks/gestures/use-parent-gesture-registry.tsx +0 -18
- /package/src/blank-stack/utils/with-stack-navigation/{_types.ts → types.ts} +0 -0
|
@@ -43,27 +43,26 @@ interface RegisterBoundsContextValue {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
47
|
-
* Returns
|
|
46
|
+
* Builds the full ancestor key chain for nested navigators.
|
|
47
|
+
* Returns an array of screen keys from immediate parent to root.
|
|
48
|
+
* [parentKey, grandparentKey, greatGrandparentKey, ...]
|
|
48
49
|
*/
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (!existsInParent && parentState.index !== undefined) {
|
|
63
|
-
return parentState.routes[parentState.index]?.key;
|
|
50
|
+
const getAncestorKeys = (current: TransitionDescriptor): string[] => {
|
|
51
|
+
const ancestors: string[] = [];
|
|
52
|
+
let nav = current.navigation.getParent();
|
|
53
|
+
|
|
54
|
+
while (nav) {
|
|
55
|
+
const state = nav.getState();
|
|
56
|
+
if (state?.routes && state.index !== undefined) {
|
|
57
|
+
const focusedRoute = state.routes[state.index];
|
|
58
|
+
if (focusedRoute?.key) {
|
|
59
|
+
ancestors.push(focusedRoute.key);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
nav = nav.getParent();
|
|
64
63
|
}
|
|
65
64
|
|
|
66
|
-
return
|
|
65
|
+
return ancestors;
|
|
67
66
|
};
|
|
68
67
|
|
|
69
68
|
/**
|
|
@@ -73,13 +72,13 @@ const getParentScreenKey = (current: TransitionDescriptor) => {
|
|
|
73
72
|
const useInitialLayoutHandler = (params: {
|
|
74
73
|
sharedBoundTag?: string;
|
|
75
74
|
currentScreenKey: string;
|
|
76
|
-
|
|
75
|
+
ancestorKeys: string[];
|
|
77
76
|
maybeMeasureAndStore: (options: MaybeMeasureAndStoreParams) => void;
|
|
78
77
|
}) => {
|
|
79
78
|
const {
|
|
80
79
|
sharedBoundTag,
|
|
81
80
|
currentScreenKey,
|
|
82
|
-
|
|
81
|
+
ancestorKeys,
|
|
83
82
|
maybeMeasureAndStore,
|
|
84
83
|
} = params;
|
|
85
84
|
|
|
@@ -87,57 +86,85 @@ const useInitialLayoutHandler = (params: {
|
|
|
87
86
|
currentScreenKey,
|
|
88
87
|
"animating",
|
|
89
88
|
);
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
89
|
+
|
|
90
|
+
// Check if any ancestor is animating
|
|
91
|
+
const ancestorAnimations = ancestorKeys.map((key) =>
|
|
92
|
+
AnimationStore.getAnimation(key, "animating"),
|
|
93
|
+
);
|
|
93
94
|
|
|
94
95
|
const hasMeasuredOnLayout = useSharedValue(false);
|
|
95
96
|
|
|
96
97
|
return useCallback(() => {
|
|
97
98
|
"worklet";
|
|
98
|
-
if (!sharedBoundTag || hasMeasuredOnLayout.
|
|
99
|
-
|
|
99
|
+
if (!sharedBoundTag || hasMeasuredOnLayout.get()) return;
|
|
100
|
+
|
|
101
|
+
// Check if current or any ancestor is animating
|
|
102
|
+
let isAnyAnimating = isAnimating.get();
|
|
103
|
+
for (let i = 0; i < ancestorAnimations.length; i++) {
|
|
104
|
+
if (ancestorAnimations[i].get()) {
|
|
105
|
+
isAnyAnimating = 1;
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (!isAnyAnimating) return;
|
|
100
111
|
|
|
101
112
|
maybeMeasureAndStore({
|
|
102
113
|
shouldSetSource: false,
|
|
103
114
|
shouldSetDestination: true,
|
|
104
115
|
});
|
|
105
116
|
|
|
106
|
-
hasMeasuredOnLayout.
|
|
117
|
+
hasMeasuredOnLayout.set(true);
|
|
107
118
|
}, [
|
|
108
119
|
sharedBoundTag,
|
|
109
120
|
hasMeasuredOnLayout,
|
|
110
121
|
isAnimating,
|
|
111
|
-
|
|
122
|
+
ancestorAnimations,
|
|
112
123
|
maybeMeasureAndStore,
|
|
113
124
|
]);
|
|
114
125
|
};
|
|
115
126
|
|
|
127
|
+
/**
|
|
128
|
+
* Measures non-pressable elements when screen becomes blurred.
|
|
129
|
+
* Captures bounds right before transition starts.
|
|
130
|
+
*/
|
|
116
131
|
/**
|
|
117
132
|
* Measures non-pressable elements when screen becomes blurred.
|
|
118
133
|
* Captures bounds right before transition starts.
|
|
119
134
|
*/
|
|
120
135
|
const useBlurMeasurement = (params: {
|
|
121
136
|
sharedBoundTag?: string;
|
|
137
|
+
ancestorKeys: string[];
|
|
122
138
|
maybeMeasureAndStore: (options: MaybeMeasureAndStoreParams) => void;
|
|
123
139
|
}) => {
|
|
124
|
-
const {
|
|
125
|
-
const
|
|
140
|
+
const { current } = useKeys();
|
|
141
|
+
const { sharedBoundTag, ancestorKeys, maybeMeasureAndStore } = params;
|
|
126
142
|
const hasCapturedSource = useRef(false);
|
|
127
143
|
|
|
144
|
+
const ancestorClosing = [current.route.key, ...ancestorKeys].map((key) =>
|
|
145
|
+
AnimationStore.getAnimation(key, "closing"),
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
const maybeMeasureOnBlur = useStableCallbackValue(() => {
|
|
149
|
+
"worklet";
|
|
150
|
+
|
|
151
|
+
//.some doesnt work here apparently... :-(
|
|
152
|
+
for (const closing of ancestorClosing) {
|
|
153
|
+
if (closing.get()) return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
maybeMeasureAndStore({ shouldSetSource: true });
|
|
157
|
+
});
|
|
158
|
+
|
|
128
159
|
useFocusEffect(
|
|
129
160
|
useCallback(() => {
|
|
130
|
-
isFocused.current = true;
|
|
131
161
|
hasCapturedSource.current = false;
|
|
132
162
|
|
|
133
163
|
return () => {
|
|
134
|
-
if (!sharedBoundTag) return;
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
isFocused.current = false;
|
|
138
|
-
runOnUI(maybeMeasureAndStore)({ shouldSetSource: true });
|
|
164
|
+
if (!sharedBoundTag || hasCapturedSource.current) return;
|
|
165
|
+
runOnUI(maybeMeasureOnBlur)();
|
|
139
166
|
};
|
|
140
|
-
}, [sharedBoundTag,
|
|
167
|
+
}, [sharedBoundTag, maybeMeasureOnBlur]),
|
|
141
168
|
);
|
|
142
169
|
|
|
143
170
|
return {
|
|
@@ -157,7 +184,7 @@ const useParentSyncReaction = (params: {
|
|
|
157
184
|
const { parentContext, maybeMeasureAndStore } = params;
|
|
158
185
|
|
|
159
186
|
useAnimatedReaction(
|
|
160
|
-
() => parentContext?.updateSignal.
|
|
187
|
+
() => parentContext?.updateSignal.get(),
|
|
161
188
|
(value) => {
|
|
162
189
|
"worklet";
|
|
163
190
|
if (value === 0 || value === undefined) return;
|
|
@@ -173,11 +200,12 @@ const { RegisterBoundsProvider, useRegisterBoundsContext } = createProvider(
|
|
|
173
200
|
({ style, onPress, sharedBoundTag, animatedRef, children }) => {
|
|
174
201
|
const { current } = useKeys();
|
|
175
202
|
const currentScreenKey = current.route.key;
|
|
176
|
-
const
|
|
203
|
+
const ancestorKeys = useMemo(() => getAncestorKeys(current), [current]);
|
|
177
204
|
|
|
178
205
|
// Context & signals
|
|
179
206
|
const parentContext: RegisterBoundsContextValue | null =
|
|
180
207
|
useRegisterBoundsContext();
|
|
208
|
+
|
|
181
209
|
const ownSignal = useSharedValue(0);
|
|
182
210
|
const updateSignal: SharedValue<number> =
|
|
183
211
|
parentContext?.updateSignal ?? ownSignal;
|
|
@@ -191,7 +219,7 @@ const { RegisterBoundsProvider, useRegisterBoundsContext } = createProvider(
|
|
|
191
219
|
const emitUpdate = useStableCallbackValue(() => {
|
|
192
220
|
"worklet";
|
|
193
221
|
const isRoot = !parentContext;
|
|
194
|
-
if (isRoot) updateSignal.
|
|
222
|
+
if (isRoot) updateSignal.set(updateSignal.get() + 1);
|
|
195
223
|
});
|
|
196
224
|
|
|
197
225
|
const maybeMeasureAndStore = useStableCallbackValue(
|
|
@@ -208,28 +236,31 @@ const { RegisterBoundsProvider, useRegisterBoundsContext } = createProvider(
|
|
|
208
236
|
|
|
209
237
|
emitUpdate();
|
|
210
238
|
|
|
211
|
-
|
|
212
|
-
BoundStore.registerOccurrence(
|
|
239
|
+
BoundStore.registerSnapshot(
|
|
213
240
|
sharedBoundTag,
|
|
214
241
|
currentScreenKey,
|
|
215
242
|
measured,
|
|
216
243
|
preparedStyles,
|
|
244
|
+
ancestorKeys,
|
|
217
245
|
);
|
|
218
246
|
|
|
219
|
-
// Set as source (on press or blur)
|
|
220
247
|
if (shouldSetSource) {
|
|
221
|
-
if (isAnimating.
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
);
|
|
226
|
-
BoundStore.setLinkSource(
|
|
248
|
+
if (isAnimating.get()) {
|
|
249
|
+
// If animation is already in progress,
|
|
250
|
+
// lets use the existing measuremenets.
|
|
251
|
+
const existing = BoundStore.getSnapshot(
|
|
227
252
|
sharedBoundTag,
|
|
228
253
|
currentScreenKey,
|
|
229
|
-
existing.bounds,
|
|
230
|
-
preparedStyles,
|
|
231
|
-
parentScreenKey,
|
|
232
254
|
);
|
|
255
|
+
if (existing) {
|
|
256
|
+
BoundStore.setLinkSource(
|
|
257
|
+
sharedBoundTag,
|
|
258
|
+
currentScreenKey,
|
|
259
|
+
existing.bounds,
|
|
260
|
+
preparedStyles,
|
|
261
|
+
ancestorKeys,
|
|
262
|
+
);
|
|
263
|
+
}
|
|
233
264
|
return;
|
|
234
265
|
}
|
|
235
266
|
BoundStore.setLinkSource(
|
|
@@ -237,7 +268,7 @@ const { RegisterBoundsProvider, useRegisterBoundsContext } = createProvider(
|
|
|
237
268
|
currentScreenKey,
|
|
238
269
|
measured,
|
|
239
270
|
preparedStyles,
|
|
240
|
-
|
|
271
|
+
ancestorKeys,
|
|
241
272
|
);
|
|
242
273
|
}
|
|
243
274
|
|
|
@@ -248,7 +279,7 @@ const { RegisterBoundsProvider, useRegisterBoundsContext } = createProvider(
|
|
|
248
279
|
currentScreenKey,
|
|
249
280
|
measured,
|
|
250
281
|
preparedStyles,
|
|
251
|
-
|
|
282
|
+
ancestorKeys,
|
|
252
283
|
);
|
|
253
284
|
}
|
|
254
285
|
|
|
@@ -259,7 +290,7 @@ const { RegisterBoundsProvider, useRegisterBoundsContext } = createProvider(
|
|
|
259
290
|
const handleInitialLayout = useInitialLayoutHandler({
|
|
260
291
|
sharedBoundTag,
|
|
261
292
|
currentScreenKey,
|
|
262
|
-
|
|
293
|
+
ancestorKeys,
|
|
263
294
|
maybeMeasureAndStore,
|
|
264
295
|
});
|
|
265
296
|
|
|
@@ -267,6 +298,7 @@ const { RegisterBoundsProvider, useRegisterBoundsContext } = createProvider(
|
|
|
267
298
|
const { markSourceCaptured } = useBlurMeasurement({
|
|
268
299
|
sharedBoundTag,
|
|
269
300
|
maybeMeasureAndStore,
|
|
301
|
+
ancestorKeys,
|
|
270
302
|
});
|
|
271
303
|
|
|
272
304
|
useParentSyncReaction({ parentContext, maybeMeasureAndStore });
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import {
|
|
3
|
+
AnimationStore,
|
|
4
|
+
type AnimationStoreMap,
|
|
5
|
+
} from "../stores/animation.store";
|
|
6
|
+
import createProvider from "../utils/create-provider";
|
|
7
|
+
|
|
8
|
+
interface RoutesProviderProps {
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
routeKeys: string[];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface RoutesContextValue {
|
|
14
|
+
/**
|
|
15
|
+
* Array of route keys for all routes in the stack, in order.
|
|
16
|
+
*/
|
|
17
|
+
routeKeys: string[];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const { RoutesProvider, useRoutesContext } = createProvider("Routes", {
|
|
21
|
+
guarded: false,
|
|
22
|
+
})<RoutesProviderProps, RoutesContextValue>(({ routeKeys }) => ({
|
|
23
|
+
value: { routeKeys },
|
|
24
|
+
}));
|
|
25
|
+
|
|
26
|
+
export { RoutesProvider, useRoutesContext };
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Hook to get animation values for all screens from a given index onwards.
|
|
30
|
+
* Useful for computing accumulated progress across multiple screens.
|
|
31
|
+
*/
|
|
32
|
+
export function useStackAnimationValues(
|
|
33
|
+
currentRouteKey: string | undefined,
|
|
34
|
+
): AnimationStoreMap[] {
|
|
35
|
+
const routesContext = useRoutesContext();
|
|
36
|
+
|
|
37
|
+
return useMemo(() => {
|
|
38
|
+
if (!currentRouteKey || !routesContext) {
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const { routeKeys } = routesContext;
|
|
43
|
+
const currentIndex = routeKeys.indexOf(currentRouteKey);
|
|
44
|
+
|
|
45
|
+
if (currentIndex === -1) {
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Get animation values for all screens from current index onwards
|
|
50
|
+
return routeKeys
|
|
51
|
+
.slice(currentIndex)
|
|
52
|
+
.map((key) => AnimationStore.getAll(key));
|
|
53
|
+
}, [currentRouteKey, routesContext]);
|
|
54
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type React from "react";
|
|
2
2
|
import type { ComponentType } from "react";
|
|
3
|
-
import type { ScreenLifecycleProps } from "../components/controllers/screen-lifecycle";
|
|
4
3
|
import { RootTransitionAware } from "../components/root-transition-aware";
|
|
4
|
+
import type { Any } from "../types/utils.types";
|
|
5
5
|
import { ScreenGestureProvider } from "./gestures.provider";
|
|
6
6
|
import { KeysProvider, type TransitionDescriptor } from "./keys.provider";
|
|
7
7
|
import { TransitionStylesProvider } from "./transition-styles.provider";
|
|
@@ -11,7 +11,7 @@ type Props<TDescriptor extends TransitionDescriptor> = {
|
|
|
11
11
|
current: TDescriptor;
|
|
12
12
|
next?: TDescriptor;
|
|
13
13
|
children: React.ReactNode;
|
|
14
|
-
LifecycleController: ComponentType<
|
|
14
|
+
LifecycleController: ComponentType<Any>;
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
export function ScreenTransitionProvider<
|
|
@@ -8,51 +8,42 @@ import type { Any } from "../types/utils.types";
|
|
|
8
8
|
type TagID = string;
|
|
9
9
|
type ScreenKey = string;
|
|
10
10
|
|
|
11
|
-
export type
|
|
11
|
+
export type Snapshot = {
|
|
12
12
|
bounds: MeasuredDimensions;
|
|
13
13
|
styles: StyleProps;
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
type ScreenIdentifier = {
|
|
17
17
|
screenKey: ScreenKey;
|
|
18
|
-
|
|
18
|
+
ancestorKeys?: ScreenKey[];
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
type TagLink = {
|
|
22
|
-
source: ScreenIdentifier &
|
|
23
|
-
destination: (ScreenIdentifier &
|
|
22
|
+
source: ScreenIdentifier & Snapshot;
|
|
23
|
+
destination: (ScreenIdentifier & Snapshot) | null;
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
type TagState = {
|
|
27
|
-
|
|
27
|
+
snapshots: Record<ScreenKey, Snapshot & { ancestorKeys?: ScreenKey[] }>;
|
|
28
28
|
linkStack: TagLink[];
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
-
/**
|
|
32
|
-
* Note on cleanup: We intentionally skip automatic cleanup of old links.
|
|
33
|
-
* The linkStack grows by one entry per navigation, but `getActiveLink`
|
|
34
|
-
* finds the correct link via screenKey matching regardless of stack size.
|
|
35
|
-
* This is unlikely to cause performance issues in typical apps, but if
|
|
36
|
-
* memory becomes a concern in apps with heavy navigation (hundreds of
|
|
37
|
-
* transitions), we should consider implementing cleanup on screen unmount using
|
|
38
|
-
* screenKey filtering.
|
|
39
|
-
*/
|
|
40
|
-
|
|
41
31
|
const registry = makeMutable<Record<TagID, TagState>>({});
|
|
42
32
|
|
|
43
|
-
function
|
|
33
|
+
function registerSnapshot(
|
|
44
34
|
tag: TagID,
|
|
45
35
|
screenKey: ScreenKey,
|
|
46
36
|
bounds: MeasuredDimensions,
|
|
47
37
|
styles: StyleProps = {},
|
|
38
|
+
ancestorKeys?: ScreenKey[],
|
|
48
39
|
) {
|
|
49
40
|
"worklet";
|
|
50
41
|
registry.modify((state: Any) => {
|
|
51
42
|
"worklet";
|
|
52
43
|
if (!state[tag]) {
|
|
53
|
-
state[tag] = {
|
|
44
|
+
state[tag] = { snapshots: {}, linkStack: [] };
|
|
54
45
|
}
|
|
55
|
-
state[tag].
|
|
46
|
+
state[tag].snapshots[screenKey] = { bounds, styles, ancestorKeys };
|
|
56
47
|
return state;
|
|
57
48
|
});
|
|
58
49
|
}
|
|
@@ -62,16 +53,15 @@ function setLinkSource(
|
|
|
62
53
|
screenKey: ScreenKey,
|
|
63
54
|
bounds: MeasuredDimensions,
|
|
64
55
|
styles: StyleProps = {},
|
|
65
|
-
|
|
56
|
+
ancestorKeys?: ScreenKey[],
|
|
66
57
|
) {
|
|
67
58
|
"worklet";
|
|
68
59
|
registry.modify((state: Any) => {
|
|
69
60
|
"worklet";
|
|
70
|
-
if (!state[tag]) state[tag] = {
|
|
61
|
+
if (!state[tag]) state[tag] = { snapshots: {}, linkStack: [] };
|
|
71
62
|
|
|
72
|
-
// Push new link onto stack
|
|
73
63
|
state[tag].linkStack.push({
|
|
74
|
-
source: { screenKey,
|
|
64
|
+
source: { screenKey, ancestorKeys, bounds, styles },
|
|
75
65
|
destination: null,
|
|
76
66
|
});
|
|
77
67
|
return state;
|
|
@@ -83,7 +73,7 @@ function setLinkDestination(
|
|
|
83
73
|
screenKey: ScreenKey,
|
|
84
74
|
bounds: MeasuredDimensions,
|
|
85
75
|
styles: StyleProps = {},
|
|
86
|
-
|
|
76
|
+
ancestorKeys?: ScreenKey[],
|
|
87
77
|
) {
|
|
88
78
|
"worklet";
|
|
89
79
|
registry.modify((state: Any) => {
|
|
@@ -94,7 +84,7 @@ function setLinkDestination(
|
|
|
94
84
|
// Find the topmost link without a destination
|
|
95
85
|
for (let i = stack.length - 1; i >= 0; i--) {
|
|
96
86
|
if (stack[i].destination === null) {
|
|
97
|
-
stack[i].destination = { screenKey,
|
|
87
|
+
stack[i].destination = { screenKey, ancestorKeys, bounds, styles };
|
|
98
88
|
break;
|
|
99
89
|
}
|
|
100
90
|
}
|
|
@@ -102,22 +92,53 @@ function setLinkDestination(
|
|
|
102
92
|
});
|
|
103
93
|
}
|
|
104
94
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
// Helper to check if a screen identifier matches a given key
|
|
95
|
+
/**
|
|
96
|
+
* Helper to check if a screen identifier matches a given key.
|
|
97
|
+
* Checks both direct screenKey match and ancestor chain.
|
|
98
|
+
*/
|
|
111
99
|
function matchesScreenKey(
|
|
112
100
|
identifier: ScreenIdentifier | null | undefined,
|
|
113
101
|
key: ScreenKey,
|
|
114
102
|
): boolean {
|
|
115
103
|
"worklet";
|
|
116
104
|
if (!identifier) return false;
|
|
117
|
-
|
|
105
|
+
|
|
106
|
+
// Direct match
|
|
107
|
+
if (identifier.screenKey === key) return true;
|
|
108
|
+
|
|
109
|
+
// Check ancestor chain
|
|
110
|
+
return identifier.ancestorKeys?.includes(key) ?? false;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Get snapshot by tag and optional key.
|
|
115
|
+
* If key is provided, supports ancestor matching - if the key matches any ancestor
|
|
116
|
+
* of a stored snapshot, that snapshot will be returned.
|
|
117
|
+
* If key is omitted, returns the most recently registered snapshot.
|
|
118
|
+
*/
|
|
119
|
+
function getSnapshot(tag: TagID, key: ScreenKey): Snapshot | null {
|
|
120
|
+
"worklet";
|
|
121
|
+
const tagState = registry.value[tag];
|
|
122
|
+
if (!tagState) return null;
|
|
123
|
+
|
|
124
|
+
// Direct match in occurrences
|
|
125
|
+
if (tagState.snapshots[key]) {
|
|
126
|
+
const snap = tagState.snapshots[key];
|
|
127
|
+
return { bounds: snap.bounds, styles: snap.styles };
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Ancestor match
|
|
131
|
+
for (const screenKey in tagState.snapshots) {
|
|
132
|
+
const snap = tagState.snapshots[screenKey];
|
|
133
|
+
if (snap.ancestorKeys?.includes(key)) {
|
|
134
|
+
return { bounds: snap.bounds, styles: snap.styles };
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return null;
|
|
118
139
|
}
|
|
119
140
|
|
|
120
|
-
function getActiveLink(tag: TagID, screenKey?: ScreenKey
|
|
141
|
+
function getActiveLink(tag: TagID, screenKey?: ScreenKey): TagLink | null {
|
|
121
142
|
"worklet";
|
|
122
143
|
const stack = registry.value[tag]?.linkStack;
|
|
123
144
|
|
|
@@ -127,40 +148,55 @@ function getActiveLink(tag: TagID, screenKey?: ScreenKey, isClosing?: boolean) {
|
|
|
127
148
|
|
|
128
149
|
// If screenKey provided, find link involving that screen
|
|
129
150
|
if (screenKey) {
|
|
130
|
-
// When closing (backward nav), we want the link where this screen is the DESTINATION
|
|
131
|
-
// When opening (forward nav), we want the link where this screen is the DESTINATION too
|
|
132
|
-
// The source is always the "from" screen, destination is the "to" screen
|
|
133
|
-
|
|
134
|
-
if (isClosing) {
|
|
135
|
-
// Backward: find link where I am the destination (I'm going back to source)
|
|
136
|
-
for (let i = stack.length - 1; i >= 0; i--) {
|
|
137
|
-
const link = stack[i];
|
|
138
|
-
if (matchesScreenKey(link.destination, screenKey)) {
|
|
139
|
-
return link;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Forward or fallback: find any link involving this screen
|
|
145
151
|
for (let i = stack.length - 1; i >= 0; i--) {
|
|
146
152
|
const link = stack[i];
|
|
147
|
-
if (
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
)
|
|
153
|
+
if (!link.destination) continue;
|
|
154
|
+
|
|
155
|
+
const isSource = matchesScreenKey(link.source, screenKey);
|
|
156
|
+
const isDestination = matchesScreenKey(link.destination, screenKey);
|
|
157
|
+
|
|
158
|
+
if (isSource || isDestination) {
|
|
159
|
+
// If I match the source, I'm closing (going back to where I came from)
|
|
151
160
|
return link;
|
|
152
161
|
}
|
|
153
162
|
}
|
|
154
163
|
return null;
|
|
155
164
|
}
|
|
156
165
|
|
|
157
|
-
|
|
166
|
+
const lastLink = stack[stack.length - 1];
|
|
167
|
+
return lastLink ? lastLink : null;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Clear all snapshots and links for a screen across all tags.
|
|
172
|
+
* Called when a screen unmounts.
|
|
173
|
+
*/
|
|
174
|
+
function clear(screenKey: ScreenKey) {
|
|
175
|
+
"worklet";
|
|
176
|
+
registry.modify((state: Any) => {
|
|
177
|
+
"worklet";
|
|
178
|
+
for (const tag in state) {
|
|
179
|
+
// Remove snapshot
|
|
180
|
+
if (state[tag].snapshots[screenKey]) {
|
|
181
|
+
delete state[tag].snapshots[screenKey];
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Remove links involving this screen
|
|
185
|
+
state[tag].linkStack = state[tag].linkStack.filter((link: TagLink) => {
|
|
186
|
+
const sourceMatches = matchesScreenKey(link.source, screenKey);
|
|
187
|
+
const destMatches = matchesScreenKey(link.destination, screenKey);
|
|
188
|
+
return !sourceMatches && !destMatches;
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
return state;
|
|
192
|
+
});
|
|
158
193
|
}
|
|
159
194
|
|
|
160
195
|
export const BoundStore = {
|
|
161
|
-
|
|
196
|
+
registerSnapshot,
|
|
162
197
|
setLinkSource,
|
|
163
198
|
setLinkDestination,
|
|
164
199
|
getActiveLink,
|
|
165
|
-
|
|
200
|
+
getSnapshot,
|
|
201
|
+
clear,
|
|
166
202
|
};
|
|
@@ -75,6 +75,19 @@ export interface ScreenInterpolationProps {
|
|
|
75
75
|
*/
|
|
76
76
|
progress: number;
|
|
77
77
|
|
|
78
|
+
/**
|
|
79
|
+
* Accumulated progress from the current screen's position onwards in the stack.
|
|
80
|
+
* Unlike `progress` (0-2), this ranges from 0-N where N is the number of screens
|
|
81
|
+
* above the current screen. Each screen at index I sees stackProgress as the
|
|
82
|
+
* sum of all progress values from index I to the top of the stack.
|
|
83
|
+
*
|
|
84
|
+
* Example: With 4 screens pushed, screen at index 1 would see stackProgress = 3
|
|
85
|
+
* when all screens are fully transitioned.
|
|
86
|
+
*
|
|
87
|
+
* Falls back to `progress` when not in blank-stack.
|
|
88
|
+
*/
|
|
89
|
+
stackProgress: number;
|
|
90
|
+
|
|
78
91
|
/**
|
|
79
92
|
* Function that provides access to bounds builders for creating shared element transitions.
|
|
80
93
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MeasuredDimensions, StyleProps } from "react-native-reanimated";
|
|
2
|
-
import type {
|
|
2
|
+
import type { Snapshot } from "../stores/bounds.store";
|
|
3
3
|
import type {
|
|
4
4
|
BoundsBuilderOptions,
|
|
5
5
|
BoundsReturnType,
|
|
@@ -21,5 +21,5 @@ export type BoundEntry = {
|
|
|
21
21
|
|
|
22
22
|
export type BoundsAccessor = {
|
|
23
23
|
<T extends BoundsBuilderOptions>(options: T): BoundsReturnType<T>;
|
|
24
|
-
|
|
24
|
+
getSnapshot: (id: string, key?: string) => Snapshot | null;
|
|
25
25
|
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { AnimationStoreMap } from "../../stores/animation.store";
|
|
2
|
+
|
|
3
|
+
export const computeStackProgress = (
|
|
4
|
+
stackAnimationValues: AnimationStoreMap[],
|
|
5
|
+
fallback: number = 0,
|
|
6
|
+
) => {
|
|
7
|
+
"worklet";
|
|
8
|
+
let computedStackProgress: number | undefined;
|
|
9
|
+
if (stackAnimationValues.length > 0) {
|
|
10
|
+
computedStackProgress = 0;
|
|
11
|
+
for (let i = 0; i < stackAnimationValues.length; i += 1) {
|
|
12
|
+
computedStackProgress += stackAnimationValues[i].progress.value;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return computedStackProgress ?? fallback;
|
|
16
|
+
};
|
|
@@ -11,7 +11,7 @@ interface DerivationsParams {
|
|
|
11
11
|
export const derivations = ({ current, next }: DerivationsParams) => {
|
|
12
12
|
"worklet";
|
|
13
13
|
|
|
14
|
-
// The combined progress
|
|
14
|
+
// The combined progress (current + next, 0-2 range)
|
|
15
15
|
const progress = current.progress + (next?.progress ?? 0);
|
|
16
16
|
|
|
17
17
|
// Whether the current screen is focused
|