react-native-screen-transitions 3.2.0-beta.3 → 3.2.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.
- package/README.md +327 -672
- package/lib/commonjs/shared/components/screen-lifecycle.js +9 -133
- package/lib/commonjs/shared/components/screen-lifecycle.js.map +1 -1
- package/lib/commonjs/shared/constants.js +1 -0
- package/lib/commonjs/shared/constants.js.map +1 -1
- package/lib/commonjs/shared/hooks/animation/use-screen-animation.js +3 -0
- package/lib/commonjs/shared/hooks/animation/use-screen-animation.js.map +1 -1
- package/lib/commonjs/shared/hooks/lifecycle/use-close-transition.js +127 -0
- package/lib/commonjs/shared/hooks/lifecycle/use-close-transition.js.map +1 -0
- package/lib/commonjs/shared/hooks/lifecycle/use-open-transition.js +35 -0
- package/lib/commonjs/shared/hooks/lifecycle/use-open-transition.js.map +1 -0
- package/lib/commonjs/shared/hooks/lifecycle/use-screen-events.js +58 -0
- package/lib/commonjs/shared/hooks/lifecycle/use-screen-events.js.map +1 -0
- package/lib/commonjs/shared/hooks/navigation/use-history.js +24 -0
- package/lib/commonjs/shared/hooks/navigation/use-history.js.map +1 -0
- package/lib/commonjs/shared/index.js +7 -0
- package/lib/commonjs/shared/index.js.map +1 -1
- package/lib/commonjs/shared/providers/screen/keys.provider.js +0 -4
- package/lib/commonjs/shared/providers/screen/keys.provider.js.map +1 -1
- package/lib/commonjs/shared/providers/screen/screen-composer.js +7 -5
- package/lib/commonjs/shared/providers/screen/screen-composer.js.map +1 -1
- package/lib/commonjs/shared/providers/screen/styles.provider.js +41 -32
- package/lib/commonjs/shared/providers/screen/styles.provider.js.map +1 -1
- package/lib/commonjs/shared/providers/stack/direct.provider.js +9 -0
- package/lib/commonjs/shared/providers/stack/direct.provider.js.map +1 -1
- package/lib/commonjs/shared/providers/stack/managed.provider.js +9 -0
- package/lib/commonjs/shared/providers/stack/managed.provider.js.map +1 -1
- package/lib/commonjs/shared/stores/animation.store.js +3 -13
- package/lib/commonjs/shared/stores/animation.store.js.map +1 -1
- package/lib/commonjs/shared/stores/history.store.js +185 -0
- package/lib/commonjs/shared/stores/history.store.js.map +1 -0
- package/lib/commonjs/shared/types/stack.types.js.map +1 -1
- package/lib/commonjs/shared/utils/animation/start-screen-transition.js +5 -1
- package/lib/commonjs/shared/utils/animation/start-screen-transition.js.map +1 -1
- package/lib/commonjs/shared/utils/bounds/index.js +19 -4
- package/lib/commonjs/shared/utils/bounds/index.js.map +1 -1
- package/lib/module/shared/components/screen-lifecycle.js +9 -132
- package/lib/module/shared/components/screen-lifecycle.js.map +1 -1
- package/lib/module/shared/constants.js +1 -0
- package/lib/module/shared/constants.js.map +1 -1
- package/lib/module/shared/hooks/animation/use-screen-animation.js +3 -0
- package/lib/module/shared/hooks/animation/use-screen-animation.js.map +1 -1
- package/lib/module/shared/hooks/lifecycle/use-close-transition.js +122 -0
- package/lib/module/shared/hooks/lifecycle/use-close-transition.js.map +1 -0
- package/lib/module/shared/hooks/lifecycle/use-open-transition.js +32 -0
- package/lib/module/shared/hooks/lifecycle/use-open-transition.js.map +1 -0
- package/lib/module/shared/hooks/lifecycle/use-screen-events.js +54 -0
- package/lib/module/shared/hooks/lifecycle/use-screen-events.js.map +1 -0
- package/lib/module/shared/hooks/navigation/use-history.js +20 -0
- package/lib/module/shared/hooks/navigation/use-history.js.map +1 -0
- package/lib/module/shared/index.js +1 -0
- package/lib/module/shared/index.js.map +1 -1
- package/lib/module/shared/providers/screen/keys.provider.js +0 -4
- package/lib/module/shared/providers/screen/keys.provider.js.map +1 -1
- package/lib/module/shared/providers/screen/screen-composer.js +7 -5
- package/lib/module/shared/providers/screen/screen-composer.js.map +1 -1
- package/lib/module/shared/providers/screen/styles.provider.js +41 -32
- package/lib/module/shared/providers/screen/styles.provider.js.map +1 -1
- package/lib/module/shared/providers/stack/direct.provider.js +10 -1
- package/lib/module/shared/providers/stack/direct.provider.js.map +1 -1
- package/lib/module/shared/providers/stack/managed.provider.js +10 -1
- package/lib/module/shared/providers/stack/managed.provider.js.map +1 -1
- package/lib/module/shared/stores/animation.store.js +4 -14
- package/lib/module/shared/stores/animation.store.js.map +1 -1
- package/lib/module/shared/stores/history.store.js +181 -0
- package/lib/module/shared/stores/history.store.js.map +1 -0
- package/lib/module/shared/types/stack.types.js.map +1 -1
- package/lib/module/shared/utils/animation/start-screen-transition.js +5 -1
- package/lib/module/shared/utils/animation/start-screen-transition.js.map +1 -1
- package/lib/module/shared/utils/bounds/index.js +19 -4
- package/lib/module/shared/utils/bounds/index.js.map +1 -1
- package/lib/typescript/blank-stack/types.d.ts +0 -3
- package/lib/typescript/blank-stack/types.d.ts.map +1 -1
- package/lib/typescript/component-stack/types.d.ts +0 -3
- package/lib/typescript/component-stack/types.d.ts.map +1 -1
- package/lib/typescript/shared/components/screen-lifecycle.d.ts +4 -1
- package/lib/typescript/shared/components/screen-lifecycle.d.ts.map +1 -1
- package/lib/typescript/shared/constants.d.ts.map +1 -1
- package/lib/typescript/shared/hooks/animation/use-screen-animation.d.ts.map +1 -1
- package/lib/typescript/shared/hooks/lifecycle/use-close-transition.d.ts +13 -0
- package/lib/typescript/shared/hooks/lifecycle/use-close-transition.d.ts.map +1 -0
- package/lib/typescript/shared/hooks/lifecycle/use-open-transition.d.ts +11 -0
- package/lib/typescript/shared/hooks/lifecycle/use-open-transition.d.ts.map +1 -0
- package/lib/typescript/shared/hooks/lifecycle/use-screen-events.d.ts +7 -0
- package/lib/typescript/shared/hooks/lifecycle/use-screen-events.d.ts.map +1 -0
- package/lib/typescript/shared/hooks/navigation/use-history.d.ts +37 -0
- package/lib/typescript/shared/hooks/navigation/use-history.d.ts.map +1 -0
- package/lib/typescript/shared/index.d.ts +3 -2
- package/lib/typescript/shared/index.d.ts.map +1 -1
- package/lib/typescript/shared/providers/screen/keys.provider.d.ts +0 -6
- package/lib/typescript/shared/providers/screen/keys.provider.d.ts.map +1 -1
- package/lib/typescript/shared/providers/screen/screen-composer.d.ts.map +1 -1
- package/lib/typescript/shared/providers/screen/styles.provider.d.ts.map +1 -1
- package/lib/typescript/shared/providers/stack/direct.provider.d.ts.map +1 -1
- package/lib/typescript/shared/providers/stack/managed.provider.d.ts.map +1 -1
- package/lib/typescript/shared/stores/animation.store.d.ts +3 -4
- package/lib/typescript/shared/stores/animation.store.d.ts.map +1 -1
- package/lib/typescript/shared/stores/history.store.d.ts +82 -0
- package/lib/typescript/shared/stores/history.store.d.ts.map +1 -0
- package/lib/typescript/shared/types/animation.types.d.ts +8 -0
- package/lib/typescript/shared/types/animation.types.d.ts.map +1 -1
- package/lib/typescript/shared/types/bounds.types.d.ts +1 -1
- package/lib/typescript/shared/types/bounds.types.d.ts.map +1 -1
- package/lib/typescript/shared/types/stack.types.d.ts +1 -0
- package/lib/typescript/shared/types/stack.types.d.ts.map +1 -1
- 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/package.json +28 -2
- package/src/blank-stack/types.ts +0 -8
- package/src/component-stack/types.ts +0 -9
- package/src/shared/__tests__/history.store.test.ts +550 -0
- package/src/shared/components/screen-lifecycle.tsx +13 -149
- package/src/shared/constants.ts +1 -0
- package/src/shared/hooks/animation/use-screen-animation.tsx +4 -0
- package/src/shared/hooks/lifecycle/use-close-transition.ts +147 -0
- package/src/shared/hooks/lifecycle/use-open-transition.ts +30 -0
- package/src/shared/hooks/lifecycle/use-screen-events.ts +62 -0
- package/src/shared/hooks/navigation/use-history.ts +63 -0
- package/src/shared/index.ts +1 -0
- package/src/shared/providers/screen/keys.provider.tsx +0 -16
- package/src/shared/providers/screen/screen-composer.tsx +6 -10
- package/src/shared/providers/screen/styles.provider.tsx +40 -34
- package/src/shared/providers/stack/direct.provider.tsx +11 -1
- package/src/shared/providers/stack/managed.provider.tsx +11 -1
- package/src/shared/stores/animation.store.ts +6 -20
- package/src/shared/stores/history.store.ts +201 -0
- package/src/shared/types/animation.types.ts +9 -0
- package/src/shared/types/bounds.types.ts +1 -0
- package/src/shared/types/stack.types.ts +1 -0
- package/src/shared/utils/animation/start-screen-transition.ts +4 -1
- package/src/shared/utils/bounds/index.ts +29 -3
- package/lib/commonjs/shared/utils/read-shared-value.js +0 -17
- package/lib/commonjs/shared/utils/read-shared-value.js.map +0 -1
- package/lib/module/shared/utils/read-shared-value.js +0 -14
- package/lib/module/shared/utils/read-shared-value.js.map +0 -1
- package/lib/typescript/shared/utils/read-shared-value.d.ts +0 -7
- package/lib/typescript/shared/utils/read-shared-value.d.ts.map +0 -1
- package/src/shared/utils/read-shared-value.ts +0 -15
|
@@ -4,7 +4,7 @@ import type {
|
|
|
4
4
|
StackNavigationState,
|
|
5
5
|
} from "@react-navigation/native";
|
|
6
6
|
import * as React from "react";
|
|
7
|
-
import { useMemo } from "react";
|
|
7
|
+
import { useEffect, useMemo } from "react";
|
|
8
8
|
import { type DerivedValue, useDerivedValue } from "react-native-reanimated";
|
|
9
9
|
import type {
|
|
10
10
|
NativeStackDescriptor,
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
type StackContextValue,
|
|
17
17
|
} from "../../hooks/navigation/use-stack";
|
|
18
18
|
import { AnimationStore } from "../../stores/animation.store";
|
|
19
|
+
import { HistoryStore } from "../../stores/history.store";
|
|
19
20
|
import { useStackCoreContext } from "./core.provider";
|
|
20
21
|
|
|
21
22
|
export interface DirectStackScene {
|
|
@@ -216,6 +217,15 @@ function withDirectStack<TProps extends DirectStackProps>(
|
|
|
216
217
|
Component: React.ComponentType<DirectStackContextValue>,
|
|
217
218
|
): React.FC<TProps> {
|
|
218
219
|
return function DirectStackProvider(props: TProps) {
|
|
220
|
+
const navigatorKey = props.state.key;
|
|
221
|
+
|
|
222
|
+
// Clean up history when navigator unmounts
|
|
223
|
+
useEffect(() => {
|
|
224
|
+
return () => {
|
|
225
|
+
HistoryStore.clearNavigator(navigatorKey);
|
|
226
|
+
};
|
|
227
|
+
}, [navigatorKey]);
|
|
228
|
+
|
|
219
229
|
const { stackContextValue, ...lifecycleValue } = useDirectStackValue(props);
|
|
220
230
|
|
|
221
231
|
return (
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Route } from "@react-navigation/native";
|
|
2
2
|
import * as React from "react";
|
|
3
|
-
import { useMemo } from "react";
|
|
3
|
+
import { useEffect, useMemo } from "react";
|
|
4
4
|
import {
|
|
5
5
|
type DerivedValue,
|
|
6
6
|
type SharedValue,
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
type StackContextValue,
|
|
12
12
|
} from "../../hooks/navigation/use-stack";
|
|
13
13
|
import { AnimationStore } from "../../stores/animation.store";
|
|
14
|
+
import { HistoryStore } from "../../stores/history.store";
|
|
14
15
|
import type {
|
|
15
16
|
BaseStackDescriptor,
|
|
16
17
|
BaseStackNavigation,
|
|
@@ -211,6 +212,15 @@ function withManagedStack<
|
|
|
211
212
|
return function ManagedStackProvider(
|
|
212
213
|
props: ManagedStackProps<TDescriptor, TNavigation>,
|
|
213
214
|
) {
|
|
215
|
+
const navigatorKey = props.state.key;
|
|
216
|
+
|
|
217
|
+
// Clean up history when navigator unmounts
|
|
218
|
+
useEffect(() => {
|
|
219
|
+
return () => {
|
|
220
|
+
HistoryStore.clearNavigator(navigatorKey);
|
|
221
|
+
};
|
|
222
|
+
}, [navigatorKey]);
|
|
223
|
+
|
|
214
224
|
const { stackContextValue, ...lifecycleValue } = useManagedStackValue<
|
|
215
225
|
TDescriptor,
|
|
216
226
|
TNavigation
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
cancelAnimation,
|
|
3
|
-
makeMutable,
|
|
4
|
-
type SharedValue,
|
|
5
|
-
} from "react-native-reanimated";
|
|
1
|
+
import { makeMutable, type SharedValue } from "react-native-reanimated";
|
|
6
2
|
import type { ScreenKey } from "../types/screen.types";
|
|
7
3
|
|
|
8
4
|
export type AnimationStoreMap = {
|
|
9
5
|
progress: SharedValue<number>;
|
|
10
|
-
closing: SharedValue<number>;
|
|
11
6
|
animating: SharedValue<number>;
|
|
7
|
+
closing: SharedValue<number>;
|
|
8
|
+
entering: SharedValue<number>;
|
|
12
9
|
};
|
|
13
10
|
|
|
14
11
|
const store: Record<ScreenKey, AnimationStoreMap> = {};
|
|
@@ -20,7 +17,8 @@ const ensure = (key: ScreenKey) => {
|
|
|
20
17
|
progress: makeMutable(0),
|
|
21
18
|
closing: makeMutable(0),
|
|
22
19
|
animating: makeMutable(0),
|
|
23
|
-
|
|
20
|
+
entering: makeMutable(1),
|
|
21
|
+
} satisfies AnimationStoreMap;
|
|
24
22
|
store[key] = bag;
|
|
25
23
|
}
|
|
26
24
|
return bag;
|
|
@@ -28,7 +26,7 @@ const ensure = (key: ScreenKey) => {
|
|
|
28
26
|
|
|
29
27
|
function getAnimation(
|
|
30
28
|
key: ScreenKey,
|
|
31
|
-
type:
|
|
29
|
+
type: keyof AnimationStoreMap,
|
|
32
30
|
): SharedValue<number> {
|
|
33
31
|
return ensure(key)[type];
|
|
34
32
|
}
|
|
@@ -39,23 +37,11 @@ function getAll(key: ScreenKey) {
|
|
|
39
37
|
|
|
40
38
|
function clear(routeKey: ScreenKey) {
|
|
41
39
|
"worklet";
|
|
42
|
-
const bag = store[routeKey];
|
|
43
|
-
if (bag) {
|
|
44
|
-
cancelAnimation(bag.progress);
|
|
45
|
-
cancelAnimation(bag.closing);
|
|
46
|
-
cancelAnimation(bag.animating);
|
|
47
|
-
}
|
|
48
40
|
delete store[routeKey];
|
|
49
41
|
}
|
|
50
42
|
|
|
51
|
-
function debugStoreSize() {
|
|
52
|
-
console.log("[AnimationStore] Size:", Object.keys(store).length);
|
|
53
|
-
console.log("[AnimationStore] Keys:", Object.keys(store));
|
|
54
|
-
}
|
|
55
|
-
|
|
56
43
|
export const AnimationStore = {
|
|
57
44
|
getAnimation,
|
|
58
45
|
clear,
|
|
59
46
|
getAll,
|
|
60
|
-
debugStoreSize,
|
|
61
47
|
};
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import type { ScreenKey } from "../types/screen.types";
|
|
2
|
+
import type { BaseStackDescriptor } from "../types/stack.types";
|
|
3
|
+
|
|
4
|
+
const HISTORY_LIMIT = 100;
|
|
5
|
+
|
|
6
|
+
interface HistoryEntry {
|
|
7
|
+
descriptor: BaseStackDescriptor;
|
|
8
|
+
navigatorKey: string;
|
|
9
|
+
timestamp: number;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// Map preserves insertion order - index 0 = oldest, last = most recent
|
|
13
|
+
const history = new Map<ScreenKey, HistoryEntry>();
|
|
14
|
+
const listeners = new Set<() => void>();
|
|
15
|
+
|
|
16
|
+
// Cached snapshot for useSyncExternalStore
|
|
17
|
+
let cachedSnapshot: ReadonlyMap<ScreenKey, HistoryEntry> = history;
|
|
18
|
+
|
|
19
|
+
function updateSnapshot(): void {
|
|
20
|
+
cachedSnapshot = new Map(history);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function notifyListeners(): void {
|
|
24
|
+
updateSnapshot();
|
|
25
|
+
listeners.forEach((listener) => {
|
|
26
|
+
listener();
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Subscribe for useSyncExternalStore compatibility
|
|
32
|
+
*/
|
|
33
|
+
function subscribe(listener: () => void): () => void {
|
|
34
|
+
listeners.add(listener);
|
|
35
|
+
return () => listeners.delete(listener);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Get current snapshot for useSyncExternalStore
|
|
40
|
+
*/
|
|
41
|
+
function getSnapshot(): ReadonlyMap<ScreenKey, HistoryEntry> {
|
|
42
|
+
return cachedSnapshot;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Add or move screen to top (most recent).
|
|
47
|
+
* LRU behavior: if exists, delete and re-add to move to end.
|
|
48
|
+
* @param descriptor - The screen descriptor
|
|
49
|
+
* @param navigatorKey - The navigator's key (for cleanup on unmount)
|
|
50
|
+
* @param historyKey - Optional custom key (defaults to navigatorKey:routeName)
|
|
51
|
+
*/
|
|
52
|
+
function focus(
|
|
53
|
+
descriptor: BaseStackDescriptor,
|
|
54
|
+
navigatorKey: string,
|
|
55
|
+
historyKey?: ScreenKey,
|
|
56
|
+
): void {
|
|
57
|
+
const key = historyKey ?? `${navigatorKey}:${descriptor.route.name}`;
|
|
58
|
+
|
|
59
|
+
// Delete first (if exists) to reset position - this is the LRU "move to top"
|
|
60
|
+
history.delete(key);
|
|
61
|
+
|
|
62
|
+
// Add to end (most recent)
|
|
63
|
+
history.set(key, {
|
|
64
|
+
descriptor,
|
|
65
|
+
navigatorKey,
|
|
66
|
+
timestamp: Date.now(),
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Evict oldest if over limit
|
|
70
|
+
while (history.size > HISTORY_LIMIT) {
|
|
71
|
+
const oldestKey = history.keys().next().value;
|
|
72
|
+
if (oldestKey) {
|
|
73
|
+
history.delete(oldestKey);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
notifyListeners();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Get most recent entry (for forward nav).
|
|
82
|
+
*/
|
|
83
|
+
function getMostRecent(): HistoryEntry | undefined {
|
|
84
|
+
const entries = Array.from(history.values());
|
|
85
|
+
return entries[entries.length - 1];
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Get N most recent entries (most recent first).
|
|
90
|
+
*/
|
|
91
|
+
function getRecent(n: number): HistoryEntry[] {
|
|
92
|
+
const entries = Array.from(history.values());
|
|
93
|
+
return entries.slice(-n).reverse();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Get entry by key.
|
|
98
|
+
*/
|
|
99
|
+
function get(key: ScreenKey): HistoryEntry | undefined {
|
|
100
|
+
return history.get(key);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Check if key exists.
|
|
105
|
+
*/
|
|
106
|
+
function has(key: ScreenKey): boolean {
|
|
107
|
+
return history.has(key);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Get all entries for a navigator (in recency order, most recent first).
|
|
112
|
+
*/
|
|
113
|
+
function getByNavigator(navigatorKey: string): HistoryEntry[] {
|
|
114
|
+
const entries: HistoryEntry[] = [];
|
|
115
|
+
for (const entry of history.values()) {
|
|
116
|
+
if (entry.navigatorKey === navigatorKey) {
|
|
117
|
+
entries.push(entry);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return entries.reverse();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Get path between two screens (for multi-waypoint interpolation).
|
|
125
|
+
* Returns keys in order from 'from' to 'to'.
|
|
126
|
+
*/
|
|
127
|
+
function getPath(fromKey: ScreenKey, toKey: ScreenKey): ScreenKey[] {
|
|
128
|
+
const keys = Array.from(history.keys());
|
|
129
|
+
const fromIndex = keys.indexOf(fromKey);
|
|
130
|
+
const toIndex = keys.indexOf(toKey);
|
|
131
|
+
|
|
132
|
+
if (fromIndex < 0 || toIndex < 0) return [];
|
|
133
|
+
|
|
134
|
+
const start = Math.min(fromIndex, toIndex);
|
|
135
|
+
const end = Math.max(fromIndex, toIndex);
|
|
136
|
+
const path = keys.slice(start, end + 1);
|
|
137
|
+
|
|
138
|
+
// Return in correct direction
|
|
139
|
+
return fromIndex > toIndex ? path.reverse() : path;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Clear all entries for a navigator (on unmount).
|
|
144
|
+
*/
|
|
145
|
+
function clearNavigator(navigatorKey: string): void {
|
|
146
|
+
const keysToRemove: ScreenKey[] = [];
|
|
147
|
+
for (const [key, entry] of history.entries()) {
|
|
148
|
+
if (entry.navigatorKey === navigatorKey) {
|
|
149
|
+
keysToRemove.push(key);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (keysToRemove.length > 0) {
|
|
154
|
+
for (const key of keysToRemove) {
|
|
155
|
+
history.delete(key);
|
|
156
|
+
}
|
|
157
|
+
notifyListeners();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Get current size of history.
|
|
163
|
+
*/
|
|
164
|
+
function size(): number {
|
|
165
|
+
return history.size;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Convert to array (in recency order, oldest first).
|
|
170
|
+
*/
|
|
171
|
+
function toArray(): HistoryEntry[] {
|
|
172
|
+
return Array.from(history.values());
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Clear all history entries (for testing).
|
|
177
|
+
* @internal
|
|
178
|
+
*/
|
|
179
|
+
function _reset(): void {
|
|
180
|
+
history.clear();
|
|
181
|
+
listeners.clear();
|
|
182
|
+
cachedSnapshot = new Map();
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export const HistoryStore = {
|
|
186
|
+
focus,
|
|
187
|
+
getMostRecent,
|
|
188
|
+
getRecent,
|
|
189
|
+
get,
|
|
190
|
+
has,
|
|
191
|
+
getByNavigator,
|
|
192
|
+
getPath,
|
|
193
|
+
clearNavigator,
|
|
194
|
+
size,
|
|
195
|
+
toArray,
|
|
196
|
+
subscribe,
|
|
197
|
+
getSnapshot,
|
|
198
|
+
_reset,
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
export type { HistoryEntry };
|
|
@@ -40,6 +40,15 @@ export type ScreenTransitionState = {
|
|
|
40
40
|
*/
|
|
41
41
|
closing: number;
|
|
42
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Whether this screen is in the process of entering.
|
|
45
|
+
* - `0`: Screen is closing or inactive
|
|
46
|
+
* - `1`: Screen is opening/entering
|
|
47
|
+
*
|
|
48
|
+
* Use this to trigger different animations when navigating back vs forward.
|
|
49
|
+
*/
|
|
50
|
+
entering: number;
|
|
51
|
+
|
|
43
52
|
/**
|
|
44
53
|
* Whether this screen is currently animating.
|
|
45
54
|
* - `0`: No animation in progress
|
|
@@ -32,10 +32,13 @@ export const startScreenTransition = ({
|
|
|
32
32
|
? { ...config, velocity: initialVelocity }
|
|
33
33
|
: config;
|
|
34
34
|
|
|
35
|
-
const { progress, animating, closing } = animations;
|
|
35
|
+
const { progress, animating, closing, entering } = animations;
|
|
36
36
|
|
|
37
37
|
if (target === "close") {
|
|
38
38
|
closing.set(TRUE);
|
|
39
|
+
entering.set(FALSE);
|
|
40
|
+
} else {
|
|
41
|
+
entering.set(TRUE);
|
|
39
42
|
}
|
|
40
43
|
|
|
41
44
|
if (!config) {
|
|
@@ -230,15 +230,41 @@ export const createBounds = (
|
|
|
230
230
|
const interpolateBounds = (
|
|
231
231
|
tag: string,
|
|
232
232
|
property: keyof MeasuredDimensions,
|
|
233
|
+
fallbackOrTargetKey?: number | string,
|
|
233
234
|
fallback?: number,
|
|
234
235
|
): number => {
|
|
235
236
|
"worklet";
|
|
236
|
-
const link = getLink(tag);
|
|
237
237
|
const entering = !props.next;
|
|
238
238
|
const range = entering ? ENTER_RANGE : EXIT_RANGE;
|
|
239
239
|
|
|
240
|
-
|
|
241
|
-
|
|
240
|
+
// If third param is a string, it's a targetKey (snapshot approach)
|
|
241
|
+
if (typeof fallbackOrTargetKey === "string") {
|
|
242
|
+
const targetKey = fallbackOrTargetKey;
|
|
243
|
+
const currentKey = props.current?.route?.key;
|
|
244
|
+
const fb = fallback ?? 0;
|
|
245
|
+
|
|
246
|
+
const currentSnapshot = currentKey
|
|
247
|
+
? BoundStore.getSnapshot(tag, currentKey)
|
|
248
|
+
: null;
|
|
249
|
+
const targetSnapshot = BoundStore.getSnapshot(tag, targetKey);
|
|
250
|
+
|
|
251
|
+
const currentValue = currentSnapshot?.bounds?.[property] ?? fb;
|
|
252
|
+
const targetValue = targetSnapshot?.bounds?.[property] ?? fb;
|
|
253
|
+
|
|
254
|
+
return interpolate(
|
|
255
|
+
props.progress,
|
|
256
|
+
range,
|
|
257
|
+
[targetValue, currentValue],
|
|
258
|
+
"clamp",
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Otherwise, use link approach (existing behavior)
|
|
263
|
+
const link = getLink(tag);
|
|
264
|
+
const fb = fallbackOrTargetKey ?? 0;
|
|
265
|
+
|
|
266
|
+
const sourceValue = link?.source?.bounds?.[property] ?? fb;
|
|
267
|
+
const destValue = link?.destination?.bounds?.[property] ?? fb;
|
|
242
268
|
|
|
243
269
|
return interpolate(
|
|
244
270
|
props.progress,
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.readSharedValue = void 0;
|
|
7
|
-
var _reactNativeReanimated = require("react-native-reanimated");
|
|
8
|
-
/**
|
|
9
|
-
* Safely read a SharedValue from the UI thread.
|
|
10
|
-
* Avoids the "cannot read .value inside component render" warning.
|
|
11
|
-
*/
|
|
12
|
-
const readSharedValue = exports.readSharedValue = (0, _reactNativeReanimated.executeOnUIRuntimeSync)(sv => {
|
|
13
|
-
"worklet";
|
|
14
|
-
|
|
15
|
-
return sv.value;
|
|
16
|
-
});
|
|
17
|
-
//# sourceMappingURL=read-shared-value.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["_reactNativeReanimated","require","readSharedValue","exports","executeOnUIRuntimeSync","sv","value"],"sourceRoot":"../../../../src","sources":["shared/utils/read-shared-value.ts"],"mappings":";;;;;;AAAA,IAAAA,sBAAA,GAAAC,OAAA;AAKA;AACA;AACA;AACA;AACO,MAAMC,eAAe,GAAAC,OAAA,CAAAD,eAAA,GAAG,IAAAE,6CAAsB,EAChDC,EAAkB,IAAQ;EAC7B,SAAS;;EACT,OAAOA,EAAE,CAACC,KAAK;AAChB,CACD,CAAC","ignoreList":[]}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import { executeOnUIRuntimeSync } from "react-native-reanimated";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Safely read a SharedValue from the UI thread.
|
|
7
|
-
* Avoids the "cannot read .value inside component render" warning.
|
|
8
|
-
*/
|
|
9
|
-
export const readSharedValue = executeOnUIRuntimeSync(sv => {
|
|
10
|
-
"worklet";
|
|
11
|
-
|
|
12
|
-
return sv.value;
|
|
13
|
-
});
|
|
14
|
-
//# sourceMappingURL=read-shared-value.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["executeOnUIRuntimeSync","readSharedValue","sv","value"],"sourceRoot":"../../../../src","sources":["shared/utils/read-shared-value.ts"],"mappings":";;AAAA,SACCA,sBAAsB,QAEhB,yBAAyB;;AAEhC;AACA;AACA;AACA;AACA,OAAO,MAAMC,eAAe,GAAGD,sBAAsB,CAChDE,EAAkB,IAAQ;EAC7B,SAAS;;EACT,OAAOA,EAAE,CAACC,KAAK;AAChB,CACD,CAAC","ignoreList":[]}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { type SharedValue } from "react-native-reanimated";
|
|
2
|
-
/**
|
|
3
|
-
* Safely read a SharedValue from the UI thread.
|
|
4
|
-
* Avoids the "cannot read .value inside component render" warning.
|
|
5
|
-
*/
|
|
6
|
-
export declare const readSharedValue: <T>(sv: SharedValue<T>) => T;
|
|
7
|
-
//# sourceMappingURL=read-shared-value.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"read-shared-value.d.ts","sourceRoot":"","sources":["../../../../src/shared/utils/read-shared-value.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,WAAW,EAChB,MAAM,yBAAyB,CAAC;AAEjC;;;GAGG;AACH,eAAO,MAAM,eAAe,GAC1B,CAAC,0BAIF,CAAC"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
executeOnUIRuntimeSync,
|
|
3
|
-
type SharedValue,
|
|
4
|
-
} from "react-native-reanimated";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Safely read a SharedValue from the UI thread.
|
|
8
|
-
* Avoids the "cannot read .value inside component render" warning.
|
|
9
|
-
*/
|
|
10
|
-
export const readSharedValue = executeOnUIRuntimeSync(
|
|
11
|
-
<T>(sv: SharedValue<T>): T => {
|
|
12
|
-
"worklet";
|
|
13
|
-
return sv.value;
|
|
14
|
-
},
|
|
15
|
-
);
|