react-native-screen-transitions 3.3.0-beta.2 → 3.3.0-beta.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 +95 -31
- package/lib/commonjs/shared/animation/snap-to.js +17 -10
- package/lib/commonjs/shared/animation/snap-to.js.map +1 -1
- package/lib/commonjs/shared/components/create-transition-aware-component.js +20 -18
- package/lib/commonjs/shared/components/create-transition-aware-component.js.map +1 -1
- package/lib/commonjs/shared/components/screen-container.js +68 -9
- package/lib/commonjs/shared/components/screen-container.js.map +1 -1
- package/lib/commonjs/shared/constants.js +8 -1
- package/lib/commonjs/shared/constants.js.map +1 -1
- package/lib/commonjs/shared/hooks/gestures/use-build-gestures.js +49 -39
- package/lib/commonjs/shared/hooks/gestures/use-build-gestures.js.map +1 -1
- package/lib/commonjs/shared/hooks/gestures/use-screen-gesture-handlers.js +110 -61
- package/lib/commonjs/shared/hooks/gestures/use-screen-gesture-handlers.js.map +1 -1
- package/lib/commonjs/shared/hooks/gestures/use-scroll-registry.js +67 -70
- package/lib/commonjs/shared/hooks/gestures/use-scroll-registry.js.map +1 -1
- package/lib/commonjs/shared/providers/gestures.provider.js +113 -25
- package/lib/commonjs/shared/providers/gestures.provider.js.map +1 -1
- package/lib/commonjs/shared/types/ownership.types.js +71 -0
- package/lib/commonjs/shared/types/ownership.types.js.map +1 -0
- package/lib/commonjs/shared/utils/gesture/check-gesture-activation.js +72 -128
- package/lib/commonjs/shared/utils/gesture/check-gesture-activation.js.map +1 -1
- package/lib/commonjs/shared/utils/gesture/compute-claimed-directions.js +81 -0
- package/lib/commonjs/shared/utils/gesture/compute-claimed-directions.js.map +1 -0
- package/lib/commonjs/shared/utils/gesture/determine-snap-target.js +1 -1
- package/lib/commonjs/shared/utils/gesture/determine-snap-target.js.map +1 -1
- package/lib/commonjs/shared/utils/gesture/find-collapse-target.js +48 -0
- package/lib/commonjs/shared/utils/gesture/find-collapse-target.js.map +1 -0
- package/lib/commonjs/shared/utils/gesture/resolve-ownership.js +87 -0
- package/lib/commonjs/shared/utils/gesture/resolve-ownership.js.map +1 -0
- package/lib/commonjs/shared/utils/gesture/velocity.js +16 -5
- package/lib/commonjs/shared/utils/gesture/velocity.js.map +1 -1
- package/lib/module/shared/animation/snap-to.js +16 -10
- package/lib/module/shared/animation/snap-to.js.map +1 -1
- package/lib/module/shared/components/create-transition-aware-component.js +20 -18
- package/lib/module/shared/components/create-transition-aware-component.js.map +1 -1
- package/lib/module/shared/components/screen-container.js +68 -10
- package/lib/module/shared/components/screen-container.js.map +1 -1
- package/lib/module/shared/constants.js +7 -0
- package/lib/module/shared/constants.js.map +1 -1
- package/lib/module/shared/hooks/gestures/use-build-gestures.js +49 -39
- package/lib/module/shared/hooks/gestures/use-build-gestures.js.map +1 -1
- package/lib/module/shared/hooks/gestures/use-screen-gesture-handlers.js +112 -63
- package/lib/module/shared/hooks/gestures/use-screen-gesture-handlers.js.map +1 -1
- package/lib/module/shared/hooks/gestures/use-scroll-registry.js +68 -70
- package/lib/module/shared/hooks/gestures/use-scroll-registry.js.map +1 -1
- package/lib/module/shared/providers/gestures.provider.js +113 -25
- package/lib/module/shared/providers/gestures.provider.js.map +1 -1
- package/lib/module/shared/types/ownership.types.js +67 -0
- package/lib/module/shared/types/ownership.types.js.map +1 -0
- package/lib/module/shared/utils/gesture/check-gesture-activation.js +70 -126
- package/lib/module/shared/utils/gesture/check-gesture-activation.js.map +1 -1
- package/lib/module/shared/utils/gesture/compute-claimed-directions.js +77 -0
- package/lib/module/shared/utils/gesture/compute-claimed-directions.js.map +1 -0
- package/lib/module/shared/utils/gesture/determine-snap-target.js +1 -1
- package/lib/module/shared/utils/gesture/determine-snap-target.js.map +1 -1
- package/lib/module/shared/utils/gesture/find-collapse-target.js +44 -0
- package/lib/module/shared/utils/gesture/find-collapse-target.js.map +1 -0
- package/lib/module/shared/utils/gesture/resolve-ownership.js +83 -0
- package/lib/module/shared/utils/gesture/resolve-ownership.js.map +1 -0
- package/lib/module/shared/utils/gesture/velocity.js +16 -5
- package/lib/module/shared/utils/gesture/velocity.js.map +1 -1
- package/lib/typescript/shared/animation/snap-to.d.ts.map +1 -1
- package/lib/typescript/shared/components/create-transition-aware-component.d.ts.map +1 -1
- package/lib/typescript/shared/components/screen-container.d.ts.map +1 -1
- package/lib/typescript/shared/constants.d.ts +6 -0
- package/lib/typescript/shared/constants.d.ts.map +1 -1
- package/lib/typescript/shared/hooks/gestures/use-build-gestures.d.ts +15 -3
- package/lib/typescript/shared/hooks/gestures/use-build-gestures.d.ts.map +1 -1
- package/lib/typescript/shared/hooks/gestures/use-screen-gesture-handlers.d.ts +52 -2
- package/lib/typescript/shared/hooks/gestures/use-screen-gesture-handlers.d.ts.map +1 -1
- package/lib/typescript/shared/hooks/gestures/use-scroll-registry.d.ts +11 -6
- package/lib/typescript/shared/hooks/gestures/use-scroll-registry.d.ts.map +1 -1
- package/lib/typescript/shared/hooks/use-backdrop-pointer-events.d.ts +1 -1
- package/lib/typescript/shared/hooks/use-backdrop-pointer-events.d.ts.map +1 -1
- package/lib/typescript/shared/providers/gestures.provider.d.ts +28 -3
- package/lib/typescript/shared/providers/gestures.provider.d.ts.map +1 -1
- package/lib/typescript/shared/types/ownership.types.d.ts +52 -0
- package/lib/typescript/shared/types/ownership.types.d.ts.map +1 -0
- package/lib/typescript/shared/types/screen.types.d.ts +22 -1
- package/lib/typescript/shared/types/screen.types.d.ts.map +1 -1
- package/lib/typescript/shared/utils/gesture/check-gesture-activation.d.ts +23 -19
- package/lib/typescript/shared/utils/gesture/check-gesture-activation.d.ts.map +1 -1
- package/lib/typescript/shared/utils/gesture/compute-claimed-directions.d.ts +23 -0
- package/lib/typescript/shared/utils/gesture/compute-claimed-directions.d.ts.map +1 -0
- package/lib/typescript/shared/utils/gesture/determine-snap-target.d.ts +5 -1
- package/lib/typescript/shared/utils/gesture/determine-snap-target.d.ts.map +1 -1
- package/lib/typescript/shared/utils/gesture/find-collapse-target.d.ts +17 -0
- package/lib/typescript/shared/utils/gesture/find-collapse-target.d.ts.map +1 -0
- package/lib/typescript/shared/utils/gesture/resolve-ownership.d.ts +36 -0
- package/lib/typescript/shared/utils/gesture/resolve-ownership.d.ts.map +1 -0
- package/lib/typescript/shared/utils/gesture/velocity.d.ts.map +1 -1
- package/package.json +121 -120
- package/src/shared/animation/snap-to.ts +17 -11
- package/src/shared/components/create-transition-aware-component.tsx +28 -25
- package/src/shared/components/screen-container.tsx +79 -12
- package/src/shared/constants.ts +7 -0
- package/src/shared/hooks/gestures/use-build-gestures.tsx +80 -44
- package/src/shared/hooks/gestures/use-screen-gesture-handlers.ts +147 -71
- package/src/shared/hooks/gestures/use-scroll-registry.tsx +94 -86
- package/src/shared/hooks/use-backdrop-pointer-events.ts +1 -1
- package/src/shared/providers/gestures.provider.tsx +168 -25
- package/src/shared/types/ownership.types.ts +77 -0
- package/src/shared/types/screen.types.ts +24 -1
- package/src/shared/utils/gesture/check-gesture-activation.ts +82 -116
- package/src/shared/utils/gesture/compute-claimed-directions.ts +93 -0
- package/src/shared/utils/gesture/determine-snap-target.ts +6 -2
- package/src/shared/utils/gesture/find-collapse-target.ts +42 -0
- package/src/shared/utils/gesture/resolve-ownership.ts +110 -0
- package/src/shared/utils/gesture/velocity.ts +16 -6
- package/src/shared/__tests__/bounds.store.test.ts +0 -394
- package/src/shared/__tests__/derivations.test.ts +0 -156
- package/src/shared/__tests__/determine-dismissal.test.ts +0 -111
- package/src/shared/__tests__/determine-snap-target.test.ts +0 -268
- package/src/shared/__tests__/geometry.test.ts +0 -130
- package/src/shared/__tests__/gesture-activation.test.ts +0 -471
- package/src/shared/__tests__/gesture.velocity.test.ts +0 -131
- package/src/shared/__tests__/history.store.test.ts +0 -550
- package/src/shared/__tests__/sync-routes-with-removed.test.ts +0 -137
- package/src/shared/__tests__/validate-snap-points.test.ts +0 -125
|
@@ -1,550 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it } from "bun:test";
|
|
2
|
-
import { HistoryStore } from "../stores/history.store";
|
|
3
|
-
import type { BaseStackDescriptor } from "../types/stack.types";
|
|
4
|
-
|
|
5
|
-
// Helper to create mock descriptors
|
|
6
|
-
const createDescriptor = (
|
|
7
|
-
name: string,
|
|
8
|
-
navigatorKey = "nav-1",
|
|
9
|
-
): BaseStackDescriptor =>
|
|
10
|
-
({
|
|
11
|
-
route: { key: `${name}-instance`, name },
|
|
12
|
-
navigation: { getState: () => ({ key: navigatorKey }) },
|
|
13
|
-
options: {},
|
|
14
|
-
render: () => null,
|
|
15
|
-
}) as unknown as BaseStackDescriptor;
|
|
16
|
-
|
|
17
|
-
// Helper to generate expected history key
|
|
18
|
-
const historyKey = (name: string, navigatorKey = "nav-1") =>
|
|
19
|
-
`${navigatorKey}:${name}`;
|
|
20
|
-
|
|
21
|
-
// Reset history before each test
|
|
22
|
-
beforeEach(() => {
|
|
23
|
-
HistoryStore._reset();
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
// =============================================================================
|
|
27
|
-
// Unit Tests - focus (LRU behavior)
|
|
28
|
-
// =============================================================================
|
|
29
|
-
|
|
30
|
-
describe("HistoryStore.focus - LRU behavior", () => {
|
|
31
|
-
it("adds new screen to history", () => {
|
|
32
|
-
const descriptor = createDescriptor("screen-a");
|
|
33
|
-
|
|
34
|
-
HistoryStore.focus(descriptor, "nav-1");
|
|
35
|
-
|
|
36
|
-
expect(HistoryStore.has(historyKey("screen-a"))).toBe(true);
|
|
37
|
-
expect(HistoryStore.size()).toBe(1);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it("adds multiple screens in order", () => {
|
|
41
|
-
HistoryStore.focus(createDescriptor("a"), "nav-1");
|
|
42
|
-
HistoryStore.focus(createDescriptor("b"), "nav-1");
|
|
43
|
-
HistoryStore.focus(createDescriptor("c"), "nav-1");
|
|
44
|
-
|
|
45
|
-
const entries = HistoryStore.toArray();
|
|
46
|
-
expect(entries.length).toBe(3);
|
|
47
|
-
expect(entries[0].descriptor.route.name).toBe("a"); // oldest
|
|
48
|
-
expect(entries[1].descriptor.route.name).toBe("b");
|
|
49
|
-
expect(entries[2].descriptor.route.name).toBe("c"); // most recent
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it("moves existing screen to top (LRU reorder)", () => {
|
|
53
|
-
// Initial order: [A, B, C, D, E]
|
|
54
|
-
HistoryStore.focus(createDescriptor("a"), "nav-1");
|
|
55
|
-
HistoryStore.focus(createDescriptor("b"), "nav-1");
|
|
56
|
-
HistoryStore.focus(createDescriptor("c"), "nav-1");
|
|
57
|
-
HistoryStore.focus(createDescriptor("d"), "nav-1");
|
|
58
|
-
HistoryStore.focus(createDescriptor("e"), "nav-1");
|
|
59
|
-
|
|
60
|
-
// Focus B again - should move to top
|
|
61
|
-
HistoryStore.focus(createDescriptor("b"), "nav-1");
|
|
62
|
-
|
|
63
|
-
const entries = HistoryStore.toArray();
|
|
64
|
-
expect(entries.length).toBe(5); // No duplicates
|
|
65
|
-
expect(entries.map((e) => e.descriptor.route.name)).toEqual([
|
|
66
|
-
"a",
|
|
67
|
-
"c",
|
|
68
|
-
"d",
|
|
69
|
-
"e",
|
|
70
|
-
"b", // B moved to top
|
|
71
|
-
]);
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
it("LRU reorder - complex scenario (browser history simulation)", () => {
|
|
75
|
-
// Simulate: Click b1, b2, b3, b4, b5
|
|
76
|
-
HistoryStore.focus(createDescriptor("b1"), "nav-1");
|
|
77
|
-
HistoryStore.focus(createDescriptor("b2"), "nav-1");
|
|
78
|
-
HistoryStore.focus(createDescriptor("b3"), "nav-1");
|
|
79
|
-
HistoryStore.focus(createDescriptor("b4"), "nav-1");
|
|
80
|
-
HistoryStore.focus(createDescriptor("b5"), "nav-1");
|
|
81
|
-
|
|
82
|
-
expect(HistoryStore.toArray().map((e) => e.descriptor.route.name)).toEqual([
|
|
83
|
-
"b1",
|
|
84
|
-
"b2",
|
|
85
|
-
"b3",
|
|
86
|
-
"b4",
|
|
87
|
-
"b5",
|
|
88
|
-
]);
|
|
89
|
-
|
|
90
|
-
// Click b1 again - moves to top, removed from original position
|
|
91
|
-
HistoryStore.focus(createDescriptor("b1"), "nav-1");
|
|
92
|
-
|
|
93
|
-
expect(HistoryStore.toArray().map((e) => e.descriptor.route.name)).toEqual([
|
|
94
|
-
"b2", // b1 was here, now gone
|
|
95
|
-
"b3",
|
|
96
|
-
"b4",
|
|
97
|
-
"b5",
|
|
98
|
-
"b1", // b1 moved to top
|
|
99
|
-
]);
|
|
100
|
-
|
|
101
|
-
// Click b2 - moves to top
|
|
102
|
-
HistoryStore.focus(createDescriptor("b2"), "nav-1");
|
|
103
|
-
|
|
104
|
-
expect(HistoryStore.toArray().map((e) => e.descriptor.route.name)).toEqual([
|
|
105
|
-
"b3", // b2 was here, now gone
|
|
106
|
-
"b4",
|
|
107
|
-
"b5",
|
|
108
|
-
"b1",
|
|
109
|
-
"b2", // b2 moved to top
|
|
110
|
-
]);
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
it("updates descriptor when refocusing", () => {
|
|
114
|
-
const original = createDescriptor("a");
|
|
115
|
-
const updated = {
|
|
116
|
-
...createDescriptor("a"),
|
|
117
|
-
options: { title: "Updated" },
|
|
118
|
-
} as unknown as BaseStackDescriptor;
|
|
119
|
-
|
|
120
|
-
HistoryStore.focus(original, "nav-1");
|
|
121
|
-
HistoryStore.focus(updated, "nav-1");
|
|
122
|
-
|
|
123
|
-
const entry = HistoryStore.get(historyKey("a"));
|
|
124
|
-
expect(entry?.descriptor.options).toEqual({ title: "Updated" });
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
// =============================================================================
|
|
129
|
-
// Unit Tests - Limit / Eviction
|
|
130
|
-
// =============================================================================
|
|
131
|
-
|
|
132
|
-
describe("HistoryStore - limit and eviction", () => {
|
|
133
|
-
it("evicts oldest when limit exceeded", () => {
|
|
134
|
-
// Add 101 entries (limit is 100)
|
|
135
|
-
for (let i = 0; i < 101; i++) {
|
|
136
|
-
HistoryStore.focus(createDescriptor(`screen-${i}`), "nav-1");
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
expect(HistoryStore.size()).toBe(100);
|
|
140
|
-
expect(HistoryStore.has(historyKey("screen-0"))).toBe(false); // Oldest evicted
|
|
141
|
-
expect(HistoryStore.has(historyKey("screen-1"))).toBe(true); // Second oldest kept
|
|
142
|
-
expect(HistoryStore.has(historyKey("screen-100"))).toBe(true); // Most recent kept
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
it("evicts multiple when way over limit", () => {
|
|
146
|
-
// Add 105 entries
|
|
147
|
-
for (let i = 0; i < 105; i++) {
|
|
148
|
-
HistoryStore.focus(createDescriptor(`screen-${i}`), "nav-1");
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
expect(HistoryStore.size()).toBe(100);
|
|
152
|
-
expect(HistoryStore.has(historyKey("screen-0"))).toBe(false);
|
|
153
|
-
expect(HistoryStore.has(historyKey("screen-4"))).toBe(false);
|
|
154
|
-
expect(HistoryStore.has(historyKey("screen-5"))).toBe(true);
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
it("refocusing does not cause extra eviction", () => {
|
|
158
|
-
// Add 99 entries
|
|
159
|
-
for (let i = 0; i < 99; i++) {
|
|
160
|
-
HistoryStore.focus(createDescriptor(`screen-${i}`), "nav-1");
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// Refocus an existing entry - should not trigger eviction
|
|
164
|
-
HistoryStore.focus(createDescriptor("screen-50"), "nav-1");
|
|
165
|
-
|
|
166
|
-
expect(HistoryStore.size()).toBe(99);
|
|
167
|
-
expect(HistoryStore.has(historyKey("screen-0"))).toBe(true);
|
|
168
|
-
});
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
// =============================================================================
|
|
172
|
-
// Unit Tests - Query methods
|
|
173
|
-
// =============================================================================
|
|
174
|
-
|
|
175
|
-
describe("HistoryStore.getMostRecent", () => {
|
|
176
|
-
it("returns undefined when empty", () => {
|
|
177
|
-
expect(HistoryStore.getMostRecent()).toBeUndefined();
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
it("returns most recent entry", () => {
|
|
181
|
-
HistoryStore.focus(createDescriptor("a"), "nav-1");
|
|
182
|
-
HistoryStore.focus(createDescriptor("b"), "nav-1");
|
|
183
|
-
HistoryStore.focus(createDescriptor("c"), "nav-1");
|
|
184
|
-
|
|
185
|
-
const recent = HistoryStore.getMostRecent();
|
|
186
|
-
expect(recent?.descriptor.route.name).toBe("c");
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
it("returns newly focused entry after LRU reorder", () => {
|
|
190
|
-
HistoryStore.focus(createDescriptor("a"), "nav-1");
|
|
191
|
-
HistoryStore.focus(createDescriptor("b"), "nav-1");
|
|
192
|
-
HistoryStore.focus(createDescriptor("a"), "nav-1"); // Refocus A
|
|
193
|
-
|
|
194
|
-
const recent = HistoryStore.getMostRecent();
|
|
195
|
-
expect(recent?.descriptor.route.name).toBe("a");
|
|
196
|
-
});
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
describe("HistoryStore.getRecent", () => {
|
|
200
|
-
it("returns empty array when empty", () => {
|
|
201
|
-
expect(HistoryStore.getRecent(5)).toEqual([]);
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
it("returns N most recent entries (most recent first)", () => {
|
|
205
|
-
HistoryStore.focus(createDescriptor("a"), "nav-1");
|
|
206
|
-
HistoryStore.focus(createDescriptor("b"), "nav-1");
|
|
207
|
-
HistoryStore.focus(createDescriptor("c"), "nav-1");
|
|
208
|
-
HistoryStore.focus(createDescriptor("d"), "nav-1");
|
|
209
|
-
|
|
210
|
-
const recent = HistoryStore.getRecent(2);
|
|
211
|
-
expect(recent.length).toBe(2);
|
|
212
|
-
expect(recent[0].descriptor.route.name).toBe("d"); // Most recent first
|
|
213
|
-
expect(recent[1].descriptor.route.name).toBe("c");
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
it("returns all if N > size", () => {
|
|
217
|
-
HistoryStore.focus(createDescriptor("a"), "nav-1");
|
|
218
|
-
HistoryStore.focus(createDescriptor("b"), "nav-1");
|
|
219
|
-
|
|
220
|
-
const recent = HistoryStore.getRecent(10);
|
|
221
|
-
expect(recent.length).toBe(2);
|
|
222
|
-
});
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
describe("HistoryStore.get / has", () => {
|
|
226
|
-
it("get returns undefined for unknown key", () => {
|
|
227
|
-
expect(HistoryStore.get("unknown")).toBeUndefined();
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
it("has returns false for unknown key", () => {
|
|
231
|
-
expect(HistoryStore.has("unknown")).toBe(false);
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
it("get returns entry for known key", () => {
|
|
235
|
-
HistoryStore.focus(createDescriptor("a"), "nav-1");
|
|
236
|
-
|
|
237
|
-
const entry = HistoryStore.get(historyKey("a"));
|
|
238
|
-
expect(entry).toBeDefined();
|
|
239
|
-
expect(entry?.descriptor.route.name).toBe("a");
|
|
240
|
-
expect(entry?.navigatorKey).toBe("nav-1");
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
it("has returns true for known key", () => {
|
|
244
|
-
HistoryStore.focus(createDescriptor("a"), "nav-1");
|
|
245
|
-
expect(HistoryStore.has(historyKey("a"))).toBe(true);
|
|
246
|
-
});
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
// =============================================================================
|
|
250
|
-
// Unit Tests - Navigator scoped queries
|
|
251
|
-
// =============================================================================
|
|
252
|
-
|
|
253
|
-
describe("HistoryStore.getByNavigator", () => {
|
|
254
|
-
it("returns empty array for unknown navigator", () => {
|
|
255
|
-
HistoryStore.focus(createDescriptor("a"), "nav-1");
|
|
256
|
-
|
|
257
|
-
expect(HistoryStore.getByNavigator("nav-2")).toEqual([]);
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
it("returns entries for specific navigator only", () => {
|
|
261
|
-
HistoryStore.focus(createDescriptor("a", "nav-1"), "nav-1");
|
|
262
|
-
HistoryStore.focus(createDescriptor("b", "nav-2"), "nav-2");
|
|
263
|
-
HistoryStore.focus(createDescriptor("c", "nav-1"), "nav-1");
|
|
264
|
-
HistoryStore.focus(createDescriptor("d", "nav-2"), "nav-2");
|
|
265
|
-
|
|
266
|
-
const nav1 = HistoryStore.getByNavigator("nav-1");
|
|
267
|
-
expect(nav1.length).toBe(2);
|
|
268
|
-
expect(nav1.map((e) => e.descriptor.route.name)).toEqual(["c", "a"]); // Most recent first
|
|
269
|
-
|
|
270
|
-
const nav2 = HistoryStore.getByNavigator("nav-2");
|
|
271
|
-
expect(nav2.length).toBe(2);
|
|
272
|
-
expect(nav2.map((e) => e.descriptor.route.name)).toEqual(["d", "b"]);
|
|
273
|
-
});
|
|
274
|
-
|
|
275
|
-
it("returns in recency order (most recent first)", () => {
|
|
276
|
-
HistoryStore.focus(createDescriptor("a"), "nav-1");
|
|
277
|
-
HistoryStore.focus(createDescriptor("b"), "nav-1");
|
|
278
|
-
HistoryStore.focus(createDescriptor("c"), "nav-1");
|
|
279
|
-
|
|
280
|
-
const entries = HistoryStore.getByNavigator("nav-1");
|
|
281
|
-
expect(entries[0].descriptor.route.name).toBe("c"); // Most recent
|
|
282
|
-
expect(entries[2].descriptor.route.name).toBe("a"); // Oldest
|
|
283
|
-
});
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
describe("HistoryStore.clearNavigator", () => {
|
|
287
|
-
it("removes all entries for specified navigator", () => {
|
|
288
|
-
HistoryStore.focus(createDescriptor("a", "nav-1"), "nav-1");
|
|
289
|
-
HistoryStore.focus(createDescriptor("b", "nav-2"), "nav-2");
|
|
290
|
-
HistoryStore.focus(createDescriptor("c", "nav-1"), "nav-1");
|
|
291
|
-
|
|
292
|
-
HistoryStore.clearNavigator("nav-1");
|
|
293
|
-
|
|
294
|
-
expect(HistoryStore.size()).toBe(1);
|
|
295
|
-
expect(HistoryStore.has(historyKey("a", "nav-1"))).toBe(false);
|
|
296
|
-
expect(HistoryStore.has(historyKey("c", "nav-1"))).toBe(false);
|
|
297
|
-
expect(HistoryStore.has(historyKey("b", "nav-2"))).toBe(true);
|
|
298
|
-
});
|
|
299
|
-
|
|
300
|
-
it("does nothing for unknown navigator", () => {
|
|
301
|
-
HistoryStore.focus(createDescriptor("a"), "nav-1");
|
|
302
|
-
|
|
303
|
-
HistoryStore.clearNavigator("nav-unknown");
|
|
304
|
-
|
|
305
|
-
expect(HistoryStore.size()).toBe(1);
|
|
306
|
-
});
|
|
307
|
-
});
|
|
308
|
-
|
|
309
|
-
// =============================================================================
|
|
310
|
-
// Unit Tests - getPath (for multi-waypoint interpolation)
|
|
311
|
-
// =============================================================================
|
|
312
|
-
|
|
313
|
-
describe("HistoryStore.getPath", () => {
|
|
314
|
-
it("returns empty array if fromKey not found", () => {
|
|
315
|
-
HistoryStore.focus(createDescriptor("a"), "nav-1");
|
|
316
|
-
HistoryStore.focus(createDescriptor("b"), "nav-1");
|
|
317
|
-
|
|
318
|
-
expect(HistoryStore.getPath("unknown", historyKey("b"))).toEqual([]);
|
|
319
|
-
});
|
|
320
|
-
|
|
321
|
-
it("returns empty array if toKey not found", () => {
|
|
322
|
-
HistoryStore.focus(createDescriptor("a"), "nav-1");
|
|
323
|
-
HistoryStore.focus(createDescriptor("b"), "nav-1");
|
|
324
|
-
|
|
325
|
-
expect(HistoryStore.getPath(historyKey("a"), "unknown")).toEqual([]);
|
|
326
|
-
});
|
|
327
|
-
|
|
328
|
-
it("returns path from older to newer (forward direction)", () => {
|
|
329
|
-
HistoryStore.focus(createDescriptor("a"), "nav-1");
|
|
330
|
-
HistoryStore.focus(createDescriptor("b"), "nav-1");
|
|
331
|
-
HistoryStore.focus(createDescriptor("c"), "nav-1");
|
|
332
|
-
HistoryStore.focus(createDescriptor("d"), "nav-1");
|
|
333
|
-
HistoryStore.focus(createDescriptor("e"), "nav-1");
|
|
334
|
-
|
|
335
|
-
const path = HistoryStore.getPath(historyKey("a"), historyKey("e"));
|
|
336
|
-
expect(path).toEqual([
|
|
337
|
-
historyKey("a"),
|
|
338
|
-
historyKey("b"),
|
|
339
|
-
historyKey("c"),
|
|
340
|
-
historyKey("d"),
|
|
341
|
-
historyKey("e"),
|
|
342
|
-
]);
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
it("returns path from newer to older (backward direction)", () => {
|
|
346
|
-
HistoryStore.focus(createDescriptor("a"), "nav-1");
|
|
347
|
-
HistoryStore.focus(createDescriptor("b"), "nav-1");
|
|
348
|
-
HistoryStore.focus(createDescriptor("c"), "nav-1");
|
|
349
|
-
HistoryStore.focus(createDescriptor("d"), "nav-1");
|
|
350
|
-
HistoryStore.focus(createDescriptor("e"), "nav-1");
|
|
351
|
-
|
|
352
|
-
const path = HistoryStore.getPath(historyKey("e"), historyKey("a"));
|
|
353
|
-
expect(path).toEqual([
|
|
354
|
-
historyKey("e"),
|
|
355
|
-
historyKey("d"),
|
|
356
|
-
historyKey("c"),
|
|
357
|
-
historyKey("b"),
|
|
358
|
-
historyKey("a"),
|
|
359
|
-
]);
|
|
360
|
-
});
|
|
361
|
-
|
|
362
|
-
it("returns path for partial range", () => {
|
|
363
|
-
HistoryStore.focus(createDescriptor("a"), "nav-1");
|
|
364
|
-
HistoryStore.focus(createDescriptor("b"), "nav-1");
|
|
365
|
-
HistoryStore.focus(createDescriptor("c"), "nav-1");
|
|
366
|
-
HistoryStore.focus(createDescriptor("d"), "nav-1");
|
|
367
|
-
HistoryStore.focus(createDescriptor("e"), "nav-1");
|
|
368
|
-
|
|
369
|
-
const path = HistoryStore.getPath(historyKey("b"), historyKey("d"));
|
|
370
|
-
expect(path).toEqual([historyKey("b"), historyKey("c"), historyKey("d")]);
|
|
371
|
-
});
|
|
372
|
-
|
|
373
|
-
it("returns single key if from === to", () => {
|
|
374
|
-
HistoryStore.focus(createDescriptor("a"), "nav-1");
|
|
375
|
-
HistoryStore.focus(createDescriptor("b"), "nav-1");
|
|
376
|
-
|
|
377
|
-
const path = HistoryStore.getPath(historyKey("b"), historyKey("b"));
|
|
378
|
-
expect(path).toEqual([historyKey("b")]);
|
|
379
|
-
});
|
|
380
|
-
|
|
381
|
-
it("respects LRU reordering in path", () => {
|
|
382
|
-
// Initial: [A, B, C, D, E]
|
|
383
|
-
HistoryStore.focus(createDescriptor("a"), "nav-1");
|
|
384
|
-
HistoryStore.focus(createDescriptor("b"), "nav-1");
|
|
385
|
-
HistoryStore.focus(createDescriptor("c"), "nav-1");
|
|
386
|
-
HistoryStore.focus(createDescriptor("d"), "nav-1");
|
|
387
|
-
HistoryStore.focus(createDescriptor("e"), "nav-1");
|
|
388
|
-
|
|
389
|
-
// Refocus B - now: [A, C, D, E, B]
|
|
390
|
-
HistoryStore.focus(createDescriptor("b"), "nav-1");
|
|
391
|
-
|
|
392
|
-
// Path from A to B should reflect new order
|
|
393
|
-
const path = HistoryStore.getPath(historyKey("a"), historyKey("b"));
|
|
394
|
-
expect(path).toEqual([
|
|
395
|
-
historyKey("a"),
|
|
396
|
-
historyKey("c"),
|
|
397
|
-
historyKey("d"),
|
|
398
|
-
historyKey("e"),
|
|
399
|
-
historyKey("b"),
|
|
400
|
-
]);
|
|
401
|
-
});
|
|
402
|
-
});
|
|
403
|
-
|
|
404
|
-
// =============================================================================
|
|
405
|
-
// Scenario Tests - Navigation Flows
|
|
406
|
-
// =============================================================================
|
|
407
|
-
|
|
408
|
-
describe("Scenario: DismissAll interpolation", () => {
|
|
409
|
-
it("provides path for dismissAll from E to A", () => {
|
|
410
|
-
// Navigate: A → B → C → D → E
|
|
411
|
-
HistoryStore.focus(createDescriptor("a"), "nav-1");
|
|
412
|
-
HistoryStore.focus(createDescriptor("b"), "nav-1");
|
|
413
|
-
HistoryStore.focus(createDescriptor("c"), "nav-1");
|
|
414
|
-
HistoryStore.focus(createDescriptor("d"), "nav-1");
|
|
415
|
-
HistoryStore.focus(createDescriptor("e"), "nav-1");
|
|
416
|
-
|
|
417
|
-
// DismissAll from E to A - need path for interpolation
|
|
418
|
-
const path = HistoryStore.getPath(historyKey("e"), historyKey("a"));
|
|
419
|
-
expect(path).toEqual([
|
|
420
|
-
historyKey("e"),
|
|
421
|
-
historyKey("d"),
|
|
422
|
-
historyKey("c"),
|
|
423
|
-
historyKey("b"),
|
|
424
|
-
historyKey("a"),
|
|
425
|
-
]);
|
|
426
|
-
});
|
|
427
|
-
});
|
|
428
|
-
|
|
429
|
-
describe("Scenario: Forward navigation", () => {
|
|
430
|
-
it("dismissed screen remains in history for forward nav", () => {
|
|
431
|
-
// Navigate: A → B → C
|
|
432
|
-
HistoryStore.focus(createDescriptor("a"), "nav-1");
|
|
433
|
-
HistoryStore.focus(createDescriptor("b"), "nav-1");
|
|
434
|
-
HistoryStore.focus(createDescriptor("c"), "nav-1");
|
|
435
|
-
|
|
436
|
-
// Simulate going back to B (C dismissed but NOT removed from history)
|
|
437
|
-
HistoryStore.focus(createDescriptor("b"), "nav-1");
|
|
438
|
-
|
|
439
|
-
// C is still in history (before B since B was just refocused)
|
|
440
|
-
expect(HistoryStore.has(historyKey("c"))).toBe(true);
|
|
441
|
-
|
|
442
|
-
// Order is now [A, C, B] - C didn't move, B moved to top
|
|
443
|
-
const entries = HistoryStore.toArray();
|
|
444
|
-
expect(entries.map((e) => e.descriptor.route.name)).toEqual([
|
|
445
|
-
"a",
|
|
446
|
-
"c",
|
|
447
|
-
"b",
|
|
448
|
-
]);
|
|
449
|
-
|
|
450
|
-
// For forward nav, we could go back to C
|
|
451
|
-
// (In practice, forward nav would look at what was most recent before B)
|
|
452
|
-
});
|
|
453
|
-
});
|
|
454
|
-
|
|
455
|
-
describe("Scenario: Cross-navigator history", () => {
|
|
456
|
-
it("maintains global order across navigators", () => {
|
|
457
|
-
// Tab 1: A → B
|
|
458
|
-
HistoryStore.focus(createDescriptor("a", "tab-1"), "tab-1");
|
|
459
|
-
HistoryStore.focus(createDescriptor("b", "tab-1"), "tab-1");
|
|
460
|
-
|
|
461
|
-
// Switch to Tab 2: C → D
|
|
462
|
-
HistoryStore.focus(createDescriptor("c", "tab-2"), "tab-2");
|
|
463
|
-
HistoryStore.focus(createDescriptor("d", "tab-2"), "tab-2");
|
|
464
|
-
|
|
465
|
-
// Switch back to Tab 1, focus A
|
|
466
|
-
HistoryStore.focus(createDescriptor("a", "tab-1"), "tab-1");
|
|
467
|
-
|
|
468
|
-
// Global order: [B, C, D, A]
|
|
469
|
-
const entries = HistoryStore.toArray();
|
|
470
|
-
expect(entries.map((e) => e.descriptor.route.name)).toEqual([
|
|
471
|
-
"b",
|
|
472
|
-
"c",
|
|
473
|
-
"d",
|
|
474
|
-
"a",
|
|
475
|
-
]);
|
|
476
|
-
|
|
477
|
-
// Tab-specific order
|
|
478
|
-
const tab1 = HistoryStore.getByNavigator("tab-1");
|
|
479
|
-
expect(tab1.map((e) => e.descriptor.route.name)).toEqual(["a", "b"]);
|
|
480
|
-
|
|
481
|
-
const tab2 = HistoryStore.getByNavigator("tab-2");
|
|
482
|
-
expect(tab2.map((e) => e.descriptor.route.name)).toEqual(["d", "c"]);
|
|
483
|
-
});
|
|
484
|
-
|
|
485
|
-
it("getMostRecent returns globally most recent regardless of navigator", () => {
|
|
486
|
-
HistoryStore.focus(createDescriptor("a", "tab-1"), "tab-1");
|
|
487
|
-
HistoryStore.focus(createDescriptor("b", "tab-2"), "tab-2");
|
|
488
|
-
HistoryStore.focus(createDescriptor("c", "tab-1"), "tab-1");
|
|
489
|
-
|
|
490
|
-
expect(HistoryStore.getMostRecent()?.descriptor.route.name).toBe("c");
|
|
491
|
-
expect(HistoryStore.getMostRecent()?.navigatorKey).toBe("tab-1");
|
|
492
|
-
});
|
|
493
|
-
});
|
|
494
|
-
|
|
495
|
-
describe("Scenario: Nested navigator cleanup", () => {
|
|
496
|
-
it("modal navigator cleanup does not affect parent", () => {
|
|
497
|
-
// Parent stack
|
|
498
|
-
HistoryStore.focus(createDescriptor("home", "stack-main"), "stack-main");
|
|
499
|
-
HistoryStore.focus(
|
|
500
|
-
createDescriptor("details", "stack-main"),
|
|
501
|
-
"stack-main",
|
|
502
|
-
);
|
|
503
|
-
|
|
504
|
-
// Modal opens with its own navigator
|
|
505
|
-
HistoryStore.focus(
|
|
506
|
-
createDescriptor("modal-a", "stack-modal"),
|
|
507
|
-
"stack-modal",
|
|
508
|
-
);
|
|
509
|
-
HistoryStore.focus(
|
|
510
|
-
createDescriptor("modal-b", "stack-modal"),
|
|
511
|
-
"stack-modal",
|
|
512
|
-
);
|
|
513
|
-
|
|
514
|
-
expect(HistoryStore.size()).toBe(4);
|
|
515
|
-
|
|
516
|
-
// Modal closes - cleanup modal navigator
|
|
517
|
-
HistoryStore.clearNavigator("stack-modal");
|
|
518
|
-
|
|
519
|
-
expect(HistoryStore.size()).toBe(2);
|
|
520
|
-
expect(HistoryStore.has(historyKey("home", "stack-main"))).toBe(true);
|
|
521
|
-
expect(HistoryStore.has(historyKey("details", "stack-main"))).toBe(true);
|
|
522
|
-
expect(HistoryStore.has(historyKey("modal-a", "stack-modal"))).toBe(false);
|
|
523
|
-
expect(HistoryStore.has(historyKey("modal-b", "stack-modal"))).toBe(false);
|
|
524
|
-
});
|
|
525
|
-
});
|
|
526
|
-
|
|
527
|
-
// =============================================================================
|
|
528
|
-
// Unit Tests - Subscribe / Snapshot (for React integration)
|
|
529
|
-
// =============================================================================
|
|
530
|
-
|
|
531
|
-
describe("HistoryStore.subscribe / getSnapshot", () => {
|
|
532
|
-
it("getSnapshot returns current state", () => {
|
|
533
|
-
HistoryStore.focus(createDescriptor("a"), "nav-1");
|
|
534
|
-
|
|
535
|
-
const snapshot = HistoryStore.getSnapshot();
|
|
536
|
-
expect(snapshot.size).toBe(1);
|
|
537
|
-
expect(snapshot.get(historyKey("a"))).toBeDefined();
|
|
538
|
-
});
|
|
539
|
-
|
|
540
|
-
it("snapshot is updated after focus", () => {
|
|
541
|
-
const snapshot1 = HistoryStore.getSnapshot();
|
|
542
|
-
expect(snapshot1.size).toBe(0);
|
|
543
|
-
|
|
544
|
-
HistoryStore.focus(createDescriptor("a"), "nav-1");
|
|
545
|
-
|
|
546
|
-
const snapshot2 = HistoryStore.getSnapshot();
|
|
547
|
-
expect(snapshot2.size).toBe(1);
|
|
548
|
-
expect(snapshot1).not.toBe(snapshot2); // New reference
|
|
549
|
-
});
|
|
550
|
-
});
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it } from "bun:test";
|
|
2
|
-
import { AnimationStore } from "../stores/animation.store";
|
|
3
|
-
import { GestureStore } from "../stores/gesture.store";
|
|
4
|
-
import { syncRoutesWithRemoved } from "../utils/navigation/sync-routes-with-removed";
|
|
5
|
-
|
|
6
|
-
const createRoute = (key: string) => ({ key });
|
|
7
|
-
|
|
8
|
-
const createClosingRouteKeys = () => {
|
|
9
|
-
const keys = new Set<string>();
|
|
10
|
-
const sharedValue: string[] = [];
|
|
11
|
-
return {
|
|
12
|
-
ref: { current: keys } as React.RefObject<Set<string>>,
|
|
13
|
-
shared: {
|
|
14
|
-
value: sharedValue,
|
|
15
|
-
get: () => sharedValue,
|
|
16
|
-
set: (v: string[]) => {
|
|
17
|
-
sharedValue.length = 0;
|
|
18
|
-
sharedValue.push(...v);
|
|
19
|
-
},
|
|
20
|
-
addListener: () => () => {},
|
|
21
|
-
removeListener: () => {},
|
|
22
|
-
modify: (fn?: (v: string[]) => string[], _forceUpdate?: boolean) => {
|
|
23
|
-
if (fn) {
|
|
24
|
-
const result = fn(sharedValue);
|
|
25
|
-
sharedValue.length = 0;
|
|
26
|
-
sharedValue.push(...result);
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
add: (key: string) => {
|
|
31
|
-
keys.add(key);
|
|
32
|
-
},
|
|
33
|
-
remove: (key: string) => {
|
|
34
|
-
keys.delete(key);
|
|
35
|
-
},
|
|
36
|
-
clear: () => keys.clear(),
|
|
37
|
-
};
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
// Helper to set up a route's animation state
|
|
41
|
-
const setRouteState = (
|
|
42
|
-
routeKey: string,
|
|
43
|
-
state: {
|
|
44
|
-
progress?: number;
|
|
45
|
-
closing?: number;
|
|
46
|
-
isDragging?: number;
|
|
47
|
-
isDismissing?: number;
|
|
48
|
-
},
|
|
49
|
-
) => {
|
|
50
|
-
const animations = AnimationStore.getAll(routeKey);
|
|
51
|
-
const gestures = GestureStore.getRouteGestures(routeKey);
|
|
52
|
-
|
|
53
|
-
if (state.progress !== undefined) animations.progress.value = state.progress;
|
|
54
|
-
if (state.closing !== undefined) animations.closing.value = state.closing;
|
|
55
|
-
if (state.isDragging !== undefined)
|
|
56
|
-
gestures.isDragging.value = state.isDragging;
|
|
57
|
-
if (state.isDismissing !== undefined)
|
|
58
|
-
gestures.isDismissing.value = state.isDismissing;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
// Reset stores before each test
|
|
62
|
-
beforeEach(() => {
|
|
63
|
-
globalThis.resetMutableRegistry();
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
describe("syncRoutesWithRemoved", () => {
|
|
67
|
-
describe("basic routing", () => {
|
|
68
|
-
it("returns empty routes when nextRoutes is empty", () => {
|
|
69
|
-
const closingRouteKeys = createClosingRouteKeys();
|
|
70
|
-
const result = syncRoutesWithRemoved({
|
|
71
|
-
prevRoutes: [createRoute("a")],
|
|
72
|
-
prevDescriptors: {},
|
|
73
|
-
nextRoutes: [],
|
|
74
|
-
nextDescriptors: {},
|
|
75
|
-
closingRouteKeys,
|
|
76
|
-
});
|
|
77
|
-
expect(result.routes).toEqual([]);
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it("returns nextRoutes unchanged for normal push (A -> B)", () => {
|
|
81
|
-
const closingRouteKeys = createClosingRouteKeys();
|
|
82
|
-
|
|
83
|
-
// Both routes fully visible
|
|
84
|
-
setRouteState("a", { progress: 1 });
|
|
85
|
-
setRouteState("b", { progress: 1 });
|
|
86
|
-
|
|
87
|
-
const result = syncRoutesWithRemoved({
|
|
88
|
-
prevRoutes: [createRoute("a")],
|
|
89
|
-
prevDescriptors: { a: {} },
|
|
90
|
-
nextRoutes: [createRoute("a"), createRoute("b")],
|
|
91
|
-
nextDescriptors: { a: {}, b: {} },
|
|
92
|
-
closingRouteKeys,
|
|
93
|
-
});
|
|
94
|
-
expect(result.routes.map((r) => r.key)).toEqual(["a", "b"]);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it("returns nextRoutes unchanged for normal stack (A -> B -> C)", () => {
|
|
98
|
-
const closingRouteKeys = createClosingRouteKeys();
|
|
99
|
-
|
|
100
|
-
setRouteState("a", { progress: 1 });
|
|
101
|
-
setRouteState("b", { progress: 1 });
|
|
102
|
-
setRouteState("c", { progress: 1 });
|
|
103
|
-
|
|
104
|
-
const result = syncRoutesWithRemoved({
|
|
105
|
-
prevRoutes: [createRoute("a"), createRoute("b")],
|
|
106
|
-
prevDescriptors: { a: {}, b: {} },
|
|
107
|
-
nextRoutes: [createRoute("a"), createRoute("b"), createRoute("c")],
|
|
108
|
-
nextDescriptors: { a: {}, b: {}, c: {} },
|
|
109
|
-
closingRouteKeys,
|
|
110
|
-
});
|
|
111
|
-
expect(result.routes.map((r) => r.key)).toEqual(["a", "b", "c"]);
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
describe("normal back navigation", () => {
|
|
117
|
-
it("keeps closing route at end for normal back (C -> B)", () => {
|
|
118
|
-
const closingRouteKeys = createClosingRouteKeys();
|
|
119
|
-
|
|
120
|
-
setRouteState("a", { progress: 1 });
|
|
121
|
-
setRouteState("b", { progress: 1 });
|
|
122
|
-
setRouteState("c", { progress: 1 });
|
|
123
|
-
|
|
124
|
-
const result = syncRoutesWithRemoved({
|
|
125
|
-
prevRoutes: [createRoute("a"), createRoute("b"), createRoute("c")],
|
|
126
|
-
prevDescriptors: { a: {}, b: {}, c: {} },
|
|
127
|
-
nextRoutes: [createRoute("a"), createRoute("b")],
|
|
128
|
-
nextDescriptors: { a: {}, b: {} },
|
|
129
|
-
closingRouteKeys,
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
// c should be added to end for close animation
|
|
133
|
-
expect(result.routes.map((r) => r.key)).toEqual(["a", "b", "c"]);
|
|
134
|
-
expect(closingRouteKeys.ref.current.has("c")).toBe(true);
|
|
135
|
-
});
|
|
136
|
-
});
|
|
137
|
-
});
|