@amazon-devices/react-navigation__routers 7.0.9000000000 → 8.0.9000000000-rn-83
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/SystemBundles/b6cc62e27d70be8722b0e7aef9fd04a870d49127e6c724fe934d1f8ca4ff8177.bundle +1298 -0
- package/SystemBundles/b6cc62e27d70be8722b0e7aef9fd04a870d49127e6c724fe934d1f8ca4ff8177.map +373 -0
- package/SystemModules/amzn__react-navigation__routers-8.modules.txt +9 -0
- package/SystemModules/amzn__react-navigation__routers-8.private.modules.txt +1 -0
- package/SystemModules/keplerscript-system-bundle-config.json +4 -4
- package/kepler-compatibility.json +2 -2
- package/lib/module/BaseRouter.js +6 -4
- package/lib/module/BaseRouter.js.map +1 -1
- package/lib/module/CommonActions.js +48 -7
- package/lib/module/CommonActions.js.map +1 -1
- package/lib/module/DrawerRouter.js +6 -6
- package/lib/module/DrawerRouter.js.map +1 -1
- package/lib/module/StackRouter.js +261 -80
- package/lib/module/StackRouter.js.map +1 -1
- package/lib/module/TabRouter.js +117 -34
- package/lib/module/TabRouter.js.map +1 -1
- package/lib/module/createParamsFromAction.js +16 -0
- package/lib/module/createParamsFromAction.js.map +1 -0
- package/lib/module/createRouteFromAction.js +21 -0
- package/lib/module/createRouteFromAction.js.map +1 -0
- package/lib/module/index.js +8 -6
- package/lib/module/index.js.map +1 -1
- package/lib/module/package.json +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -1
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/BaseRouter.d.ts +23 -20
- package/lib/typescript/src/BaseRouter.d.ts.map +1 -1
- package/lib/typescript/src/CommonActions.d.ts +66 -18
- package/lib/typescript/src/CommonActions.d.ts.map +1 -1
- package/lib/typescript/src/DrawerRouter.d.ts +18 -6
- package/lib/typescript/src/DrawerRouter.d.ts.map +1 -1
- package/lib/typescript/src/StackRouter.d.ts +73 -11
- package/lib/typescript/src/StackRouter.d.ts.map +1 -1
- package/lib/typescript/src/TabRouter.d.ts +24 -4
- package/lib/typescript/src/TabRouter.d.ts.map +1 -1
- package/lib/typescript/src/createParamsFromAction.d.ts +13 -0
- package/lib/typescript/src/createParamsFromAction.d.ts.map +1 -0
- package/lib/typescript/src/createRouteFromAction.d.ts +17 -0
- package/lib/typescript/src/createRouteFromAction.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +4 -4
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +1 -2
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/oss-attribution/attribution.txt +0 -0
- package/oss-attribution/licenseInfos.json +1 -0
- package/package.json +80 -1
- package/src/BaseRouter.tsx +11 -6
- package/src/CommonActions.tsx +147 -56
- package/src/DrawerRouter.tsx +15 -13
- package/src/StackRouter.tsx +437 -199
- package/src/TabRouter.tsx +192 -53
- package/src/createParamsFromAction.tsx +22 -0
- package/src/createRouteFromAction.tsx +24 -0
- package/src/index.tsx +4 -4
- package/src/types.tsx +5 -5
- package/SystemBundles/b274ab157641de9520fe27a8e8049450e176a8ce2fedd3283fcb46c038bc6247.bundle +0 -3497
- package/SystemBundles/b274ab157641de9520fe27a8e8049450e176a8ce2fedd3283fcb46c038bc6247.map +0 -987
- package/SystemModules/amzn__react-navigation__routers-7.modules.txt +0 -21
- package/SystemModules/amzn__react-navigation__routers-7.private.modules.txt +0 -12
- package/THIRD_PARTY_NOTICES.txt +0 -24
- package/lib/commonjs/BaseRouter.js +0 -61
- package/lib/commonjs/BaseRouter.js.map +0 -1
- package/lib/commonjs/CommonActions.js +0 -53
- package/lib/commonjs/CommonActions.js.map +0 -1
- package/lib/commonjs/DrawerRouter.js +0 -154
- package/lib/commonjs/DrawerRouter.js.map +0 -1
- package/lib/commonjs/StackRouter.js +0 -310
- package/lib/commonjs/StackRouter.js.map +0 -1
- package/lib/commonjs/TabRouter.js +0 -253
- package/lib/commonjs/TabRouter.js.map +0 -1
- package/lib/commonjs/index.js +0 -80
- package/lib/commonjs/index.js.map +0 -1
- package/lib/commonjs/types.js +0 -6
- package/lib/commonjs/types.js.map +0 -1
package/src/StackRouter.tsx
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { nanoid } from 'nanoid/non-secure';
|
|
2
2
|
|
|
3
|
-
import BaseRouter from './BaseRouter';
|
|
3
|
+
import { BaseRouter } from './BaseRouter';
|
|
4
|
+
import { createParamsFromAction } from './createParamsFromAction';
|
|
5
|
+
import { createRouteFromAction } from './createRouteFromAction';
|
|
4
6
|
import type {
|
|
5
7
|
CommonNavigationAction,
|
|
6
8
|
DefaultRouterOptions,
|
|
9
|
+
NavigationRoute,
|
|
7
10
|
NavigationState,
|
|
8
11
|
ParamListBase,
|
|
9
12
|
Route,
|
|
@@ -13,7 +16,7 @@ import type {
|
|
|
13
16
|
export type StackActionType =
|
|
14
17
|
| {
|
|
15
18
|
type: 'REPLACE';
|
|
16
|
-
payload: { name: string;
|
|
19
|
+
payload: { name: string; params?: object };
|
|
17
20
|
source?: string;
|
|
18
21
|
target?: string;
|
|
19
22
|
}
|
|
@@ -33,6 +36,16 @@ export type StackActionType =
|
|
|
33
36
|
type: 'POP_TO_TOP';
|
|
34
37
|
source?: string;
|
|
35
38
|
target?: string;
|
|
39
|
+
}
|
|
40
|
+
| {
|
|
41
|
+
type: 'POP_TO';
|
|
42
|
+
payload: {
|
|
43
|
+
name: string;
|
|
44
|
+
params?: object;
|
|
45
|
+
merge?: boolean;
|
|
46
|
+
};
|
|
47
|
+
source?: string;
|
|
48
|
+
target?: string;
|
|
36
49
|
};
|
|
37
50
|
|
|
38
51
|
export type StackRouterOptions = DefaultRouterOptions;
|
|
@@ -43,31 +56,39 @@ export type StackNavigationState<ParamList extends ParamListBase> =
|
|
|
43
56
|
* Type of the router, in this case, it's stack.
|
|
44
57
|
*/
|
|
45
58
|
type: 'stack';
|
|
59
|
+
/**
|
|
60
|
+
* List of routes, which are supposed to be preloaded before navigating to.
|
|
61
|
+
*/
|
|
62
|
+
preloadedRoutes: NavigationRoute<ParamList, keyof ParamList>[];
|
|
46
63
|
};
|
|
47
64
|
|
|
48
65
|
export type StackActionHelpers<ParamList extends ParamListBase> = {
|
|
49
66
|
/**
|
|
50
67
|
* Replace the current route with a new one.
|
|
51
68
|
*
|
|
52
|
-
* @param
|
|
69
|
+
* @param screen Name of the new route that will replace the current one.
|
|
53
70
|
* @param [params] Params object for the new route.
|
|
54
71
|
*/
|
|
55
72
|
replace<RouteName extends keyof ParamList>(
|
|
56
|
-
...args:
|
|
57
|
-
?
|
|
58
|
-
|
|
73
|
+
...args: RouteName extends unknown
|
|
74
|
+
? undefined extends ParamList[RouteName]
|
|
75
|
+
? [screen: RouteName, params?: ParamList[RouteName]]
|
|
76
|
+
: [screen: RouteName, params: ParamList[RouteName]]
|
|
77
|
+
: never
|
|
59
78
|
): void;
|
|
60
79
|
|
|
61
80
|
/**
|
|
62
81
|
* Push a new screen onto the stack.
|
|
63
82
|
*
|
|
64
|
-
* @param
|
|
83
|
+
* @param screen Name of the route to push onto the stack.
|
|
65
84
|
* @param [params] Params object for the route.
|
|
66
85
|
*/
|
|
67
86
|
push<RouteName extends keyof ParamList>(
|
|
68
|
-
...args:
|
|
69
|
-
?
|
|
70
|
-
|
|
87
|
+
...args: RouteName extends unknown
|
|
88
|
+
? undefined extends ParamList[RouteName]
|
|
89
|
+
? [screen: RouteName, params?: ParamList[RouteName]]
|
|
90
|
+
: [screen: RouteName, params: ParamList[RouteName]]
|
|
91
|
+
: never
|
|
71
92
|
): void;
|
|
72
93
|
|
|
73
94
|
/**
|
|
@@ -79,24 +100,73 @@ export type StackActionHelpers<ParamList extends ParamListBase> = {
|
|
|
79
100
|
* Pop to the first route in the stack, dismissing all other screens.
|
|
80
101
|
*/
|
|
81
102
|
popToTop(): void;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Pop any screens to go back to the specified screen.
|
|
106
|
+
* If the specified screen doesn't exist, it'll be added to the stack.
|
|
107
|
+
*
|
|
108
|
+
* @param screen Name of the route to pop to.
|
|
109
|
+
* @param [params] Params object for the route.
|
|
110
|
+
* @param [options.merge] Whether to merge the params onto the route. Defaults to `false`.
|
|
111
|
+
*/
|
|
112
|
+
popTo<RouteName extends keyof ParamList>(
|
|
113
|
+
...args: RouteName extends unknown
|
|
114
|
+
? undefined extends ParamList[RouteName]
|
|
115
|
+
? [
|
|
116
|
+
screen: RouteName,
|
|
117
|
+
params?: ParamList[RouteName],
|
|
118
|
+
options?: { merge?: boolean },
|
|
119
|
+
]
|
|
120
|
+
: [
|
|
121
|
+
screen: RouteName,
|
|
122
|
+
params: ParamList[RouteName],
|
|
123
|
+
options?: { merge?: boolean },
|
|
124
|
+
]
|
|
125
|
+
: never
|
|
126
|
+
): void;
|
|
82
127
|
};
|
|
83
128
|
|
|
84
129
|
export const StackActions = {
|
|
85
|
-
replace(name: string, params?: object)
|
|
86
|
-
return {
|
|
130
|
+
replace(name: string, params?: object) {
|
|
131
|
+
return {
|
|
132
|
+
type: 'REPLACE',
|
|
133
|
+
payload: { name, params },
|
|
134
|
+
} as const satisfies StackActionType;
|
|
87
135
|
},
|
|
88
|
-
push(name: string, params?: object)
|
|
89
|
-
return {
|
|
136
|
+
push(name: string, params?: object) {
|
|
137
|
+
return {
|
|
138
|
+
type: 'PUSH',
|
|
139
|
+
payload: { name, params },
|
|
140
|
+
} as const satisfies StackActionType;
|
|
90
141
|
},
|
|
91
|
-
pop(count: number = 1)
|
|
92
|
-
return {
|
|
142
|
+
pop(count: number = 1) {
|
|
143
|
+
return {
|
|
144
|
+
type: 'POP',
|
|
145
|
+
payload: { count },
|
|
146
|
+
} as const satisfies StackActionType;
|
|
93
147
|
},
|
|
94
|
-
popToTop()
|
|
95
|
-
return { type: 'POP_TO_TOP' };
|
|
148
|
+
popToTop() {
|
|
149
|
+
return { type: 'POP_TO_TOP' } as const satisfies StackActionType;
|
|
150
|
+
},
|
|
151
|
+
popTo(name: string, params?: object, options?: { merge?: boolean }) {
|
|
152
|
+
if (typeof options === 'boolean') {
|
|
153
|
+
console.warn(
|
|
154
|
+
`Passing a boolean as the third argument to 'popTo' is deprecated. Pass '{ merge: true }' instead.`
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return {
|
|
159
|
+
type: 'POP_TO',
|
|
160
|
+
payload: {
|
|
161
|
+
name,
|
|
162
|
+
params,
|
|
163
|
+
merge: typeof options === 'boolean' ? options : options?.merge,
|
|
164
|
+
},
|
|
165
|
+
} as const satisfies StackActionType;
|
|
96
166
|
},
|
|
97
167
|
};
|
|
98
168
|
|
|
99
|
-
export
|
|
169
|
+
export function StackRouter(options: StackRouterOptions) {
|
|
100
170
|
const router: Router<
|
|
101
171
|
StackNavigationState<ParamListBase>,
|
|
102
172
|
CommonNavigationAction | StackActionType
|
|
@@ -118,6 +188,7 @@ export default function StackRouter(options: StackRouterOptions) {
|
|
|
118
188
|
key: `stack-${nanoid()}`,
|
|
119
189
|
index: 0,
|
|
120
190
|
routeNames,
|
|
191
|
+
preloadedRoutes: [],
|
|
121
192
|
routes: [
|
|
122
193
|
{
|
|
123
194
|
key: `${initialRouteName}-${nanoid()}`,
|
|
@@ -129,7 +200,7 @@ export default function StackRouter(options: StackRouterOptions) {
|
|
|
129
200
|
},
|
|
130
201
|
|
|
131
202
|
getRehydratedState(partialState, { routeNames, routeParamList }) {
|
|
132
|
-
|
|
203
|
+
const state = partialState;
|
|
133
204
|
|
|
134
205
|
if (state.stale === false) {
|
|
135
206
|
return state;
|
|
@@ -137,20 +208,35 @@ export default function StackRouter(options: StackRouterOptions) {
|
|
|
137
208
|
|
|
138
209
|
const routes = state.routes
|
|
139
210
|
.filter((route) => routeNames.includes(route.name))
|
|
140
|
-
.map(
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
211
|
+
.map((route) => ({
|
|
212
|
+
...route,
|
|
213
|
+
key: route.key || `${route.name}-${nanoid()}`,
|
|
214
|
+
params:
|
|
215
|
+
routeParamList[route.name] !== undefined
|
|
216
|
+
? {
|
|
217
|
+
...routeParamList[route.name],
|
|
218
|
+
...route.params,
|
|
219
|
+
}
|
|
220
|
+
: route.params,
|
|
221
|
+
}));
|
|
222
|
+
|
|
223
|
+
const preloadedRoutes =
|
|
224
|
+
state.preloadedRoutes
|
|
225
|
+
?.filter((route) => routeNames.includes(route.name))
|
|
226
|
+
.map(
|
|
227
|
+
(route) =>
|
|
228
|
+
({
|
|
229
|
+
...route,
|
|
230
|
+
key: route.key || `${route.name}-${nanoid()}`,
|
|
231
|
+
params:
|
|
232
|
+
routeParamList[route.name] !== undefined
|
|
233
|
+
? {
|
|
234
|
+
...routeParamList[route.name],
|
|
235
|
+
...route.params,
|
|
236
|
+
}
|
|
237
|
+
: route.params,
|
|
238
|
+
}) as Route<string>
|
|
239
|
+
) ?? [];
|
|
154
240
|
|
|
155
241
|
if (routes.length === 0) {
|
|
156
242
|
const initialRouteName =
|
|
@@ -172,6 +258,7 @@ export default function StackRouter(options: StackRouterOptions) {
|
|
|
172
258
|
index: routes.length - 1,
|
|
173
259
|
routeNames,
|
|
174
260
|
routes,
|
|
261
|
+
preloadedRoutes,
|
|
175
262
|
};
|
|
176
263
|
},
|
|
177
264
|
|
|
@@ -226,105 +313,244 @@ export default function StackRouter(options: StackRouterOptions) {
|
|
|
226
313
|
|
|
227
314
|
switch (action.type) {
|
|
228
315
|
case 'REPLACE': {
|
|
229
|
-
const
|
|
316
|
+
const currentIndex =
|
|
230
317
|
action.target === state.key && action.source
|
|
231
318
|
? state.routes.findIndex((r) => r.key === action.source)
|
|
232
319
|
: state.index;
|
|
233
320
|
|
|
234
|
-
if (
|
|
321
|
+
if (currentIndex === -1) {
|
|
235
322
|
return null;
|
|
236
323
|
}
|
|
237
324
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
if (!state.routeNames.includes(name)) {
|
|
325
|
+
if (!state.routeNames.includes(action.payload.name)) {
|
|
241
326
|
return null;
|
|
242
327
|
}
|
|
243
328
|
|
|
329
|
+
const getId = options.routeGetIdList[action.payload.name];
|
|
330
|
+
const id = getId?.({ params: action.payload.params });
|
|
331
|
+
|
|
332
|
+
// Re-use preloaded route if available
|
|
333
|
+
let route = state.preloadedRoutes.find(
|
|
334
|
+
(route) =>
|
|
335
|
+
route.name === action.payload.name &&
|
|
336
|
+
id === getId?.({ params: route.params })
|
|
337
|
+
);
|
|
338
|
+
|
|
339
|
+
if (!route) {
|
|
340
|
+
route = createRouteFromAction({ action, routeParamList });
|
|
341
|
+
}
|
|
342
|
+
|
|
244
343
|
return {
|
|
245
344
|
...state,
|
|
246
|
-
routes: state.routes.map((
|
|
247
|
-
i ===
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
params:
|
|
252
|
-
routeParamList[name] !== undefined
|
|
253
|
-
? {
|
|
254
|
-
...routeParamList[name],
|
|
255
|
-
...params,
|
|
256
|
-
}
|
|
257
|
-
: params,
|
|
258
|
-
}
|
|
259
|
-
: route
|
|
345
|
+
routes: state.routes.map((r, i) =>
|
|
346
|
+
i === currentIndex ? route : r
|
|
347
|
+
),
|
|
348
|
+
preloadedRoutes: state.preloadedRoutes.filter(
|
|
349
|
+
(r) => r.key !== route.key
|
|
260
350
|
),
|
|
261
351
|
};
|
|
262
352
|
}
|
|
263
353
|
|
|
264
354
|
case 'PUSH':
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
const route = id
|
|
270
|
-
? state.routes.find(
|
|
271
|
-
(route) =>
|
|
272
|
-
route.name === action.payload.name &&
|
|
273
|
-
id === getId?.({ params: route.params })
|
|
274
|
-
)
|
|
275
|
-
: undefined;
|
|
355
|
+
case 'NAVIGATE': {
|
|
356
|
+
if (!state.routeNames.includes(action.payload.name)) {
|
|
357
|
+
return null;
|
|
358
|
+
}
|
|
276
359
|
|
|
277
|
-
|
|
360
|
+
const getId = options.routeGetIdList[action.payload.name];
|
|
361
|
+
const id = getId?.({ params: action.payload.params });
|
|
278
362
|
|
|
279
|
-
|
|
363
|
+
let route: Route<string> | undefined;
|
|
364
|
+
|
|
365
|
+
if (id !== undefined) {
|
|
366
|
+
route = state.routes.findLast(
|
|
367
|
+
(route) =>
|
|
368
|
+
route.name === action.payload.name &&
|
|
369
|
+
id === getId?.({ params: route.params })
|
|
370
|
+
);
|
|
371
|
+
} else if (action.type === 'NAVIGATE') {
|
|
372
|
+
const currentRoute = state.routes[state.index];
|
|
373
|
+
|
|
374
|
+
// If the route matches the current one, then navigate to it
|
|
375
|
+
if (action.payload.name === currentRoute.name) {
|
|
376
|
+
route = currentRoute;
|
|
377
|
+
} else if (action.payload.pop) {
|
|
378
|
+
route = state.routes.findLast(
|
|
379
|
+
(route) => route.name === action.payload.name
|
|
380
|
+
);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
if (!route) {
|
|
385
|
+
route = state.preloadedRoutes.find(
|
|
386
|
+
(route) =>
|
|
387
|
+
route.name === action.payload.name &&
|
|
388
|
+
id === getId?.({ params: route.params })
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
let params;
|
|
393
|
+
|
|
394
|
+
if (action.type === 'NAVIGATE' && action.payload.merge && route) {
|
|
395
|
+
params =
|
|
396
|
+
action.payload.params !== undefined ||
|
|
397
|
+
routeParamList[action.payload.name] !== undefined
|
|
398
|
+
? {
|
|
399
|
+
...routeParamList[action.payload.name],
|
|
400
|
+
...route.params,
|
|
401
|
+
...action.payload.params,
|
|
402
|
+
}
|
|
403
|
+
: route.params;
|
|
404
|
+
} else {
|
|
405
|
+
params = createParamsFromAction({ action, routeParamList });
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
let routes: Route<string>[];
|
|
409
|
+
|
|
410
|
+
if (route) {
|
|
411
|
+
if (action.type === 'NAVIGATE' && action.payload.pop) {
|
|
412
|
+
routes = [];
|
|
413
|
+
|
|
414
|
+
// Get all routes until the matching one
|
|
415
|
+
for (const r of state.routes) {
|
|
416
|
+
if (r.key === route.key) {
|
|
417
|
+
routes.push({
|
|
418
|
+
...route,
|
|
419
|
+
path:
|
|
420
|
+
action.payload.path !== undefined
|
|
421
|
+
? action.payload.path
|
|
422
|
+
: route.path,
|
|
423
|
+
params,
|
|
424
|
+
});
|
|
425
|
+
break;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
routes.push(r);
|
|
429
|
+
}
|
|
430
|
+
} else {
|
|
280
431
|
routes = state.routes.filter((r) => r.key !== route.key);
|
|
281
432
|
routes.push({
|
|
282
433
|
...route,
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
: action.payload.params,
|
|
434
|
+
path:
|
|
435
|
+
action.type === 'NAVIGATE' &&
|
|
436
|
+
action.payload.path !== undefined
|
|
437
|
+
? action.payload.path
|
|
438
|
+
: route.path,
|
|
439
|
+
params,
|
|
290
440
|
});
|
|
291
|
-
} else {
|
|
292
|
-
routes = [
|
|
293
|
-
...state.routes,
|
|
294
|
-
{
|
|
295
|
-
key: `${action.payload.name}-${nanoid()}`,
|
|
296
|
-
name: action.payload.name,
|
|
297
|
-
params:
|
|
298
|
-
routeParamList[action.payload.name] !== undefined
|
|
299
|
-
? {
|
|
300
|
-
...routeParamList[action.payload.name],
|
|
301
|
-
...action.payload.params,
|
|
302
|
-
}
|
|
303
|
-
: action.payload.params,
|
|
304
|
-
},
|
|
305
|
-
];
|
|
306
441
|
}
|
|
442
|
+
} else {
|
|
443
|
+
routes = [
|
|
444
|
+
...state.routes,
|
|
445
|
+
{
|
|
446
|
+
key: `${action.payload.name}-${nanoid()}`,
|
|
447
|
+
name: action.payload.name,
|
|
448
|
+
path:
|
|
449
|
+
action.type === 'NAVIGATE' ? action.payload.path : undefined,
|
|
450
|
+
params,
|
|
451
|
+
},
|
|
452
|
+
];
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
return {
|
|
456
|
+
...state,
|
|
457
|
+
index: routes.length - 1,
|
|
458
|
+
preloadedRoutes: state.preloadedRoutes.filter(
|
|
459
|
+
(route) => routes[routes.length - 1].key !== route.key
|
|
460
|
+
),
|
|
461
|
+
routes,
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
case 'NAVIGATE_DEPRECATED': {
|
|
466
|
+
if (!state.routeNames.includes(action.payload.name)) {
|
|
467
|
+
return null;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
if (
|
|
471
|
+
state.preloadedRoutes.find(
|
|
472
|
+
(route) =>
|
|
473
|
+
route.name === action.payload.name &&
|
|
474
|
+
id === getId?.({ params: route.params })
|
|
475
|
+
)
|
|
476
|
+
) {
|
|
477
|
+
return null;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
// If the route already exists, navigate to that
|
|
481
|
+
let index = -1;
|
|
482
|
+
|
|
483
|
+
const getId = options.routeGetIdList[action.payload.name];
|
|
484
|
+
const id = getId?.({ params: action.payload.params });
|
|
485
|
+
|
|
486
|
+
if (id !== undefined) {
|
|
487
|
+
index = state.routes.findIndex(
|
|
488
|
+
(route) =>
|
|
489
|
+
route.name === action.payload.name &&
|
|
490
|
+
id === getId?.({ params: route.params })
|
|
491
|
+
);
|
|
492
|
+
} else if (state.routes[state.index].name === action.payload.name) {
|
|
493
|
+
index = state.index;
|
|
494
|
+
} else {
|
|
495
|
+
index = state.routes.findLastIndex(
|
|
496
|
+
(route) => route.name === action.payload.name
|
|
497
|
+
);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
if (index === -1) {
|
|
501
|
+
const routes = [
|
|
502
|
+
...state.routes,
|
|
503
|
+
createRouteFromAction({ action, routeParamList }),
|
|
504
|
+
];
|
|
307
505
|
|
|
308
506
|
return {
|
|
309
507
|
...state,
|
|
310
|
-
index: routes.length - 1,
|
|
311
508
|
routes,
|
|
509
|
+
index: routes.length - 1,
|
|
312
510
|
};
|
|
313
511
|
}
|
|
314
512
|
|
|
315
|
-
|
|
513
|
+
const route = state.routes[index];
|
|
514
|
+
|
|
515
|
+
let params;
|
|
516
|
+
|
|
517
|
+
if (action.payload.merge) {
|
|
518
|
+
params =
|
|
519
|
+
action.payload.params !== undefined ||
|
|
520
|
+
routeParamList[route.name] !== undefined
|
|
521
|
+
? {
|
|
522
|
+
...routeParamList[route.name],
|
|
523
|
+
...route.params,
|
|
524
|
+
...action.payload.params,
|
|
525
|
+
}
|
|
526
|
+
: route.params;
|
|
527
|
+
} else {
|
|
528
|
+
params = createParamsFromAction({ action, routeParamList });
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
return {
|
|
532
|
+
...state,
|
|
533
|
+
index,
|
|
534
|
+
routes: [
|
|
535
|
+
...state.routes.slice(0, index),
|
|
536
|
+
params !== route.params
|
|
537
|
+
? { ...route, params }
|
|
538
|
+
: state.routes[index],
|
|
539
|
+
],
|
|
540
|
+
};
|
|
541
|
+
}
|
|
316
542
|
|
|
317
543
|
case 'POP': {
|
|
318
|
-
const
|
|
544
|
+
const currentIndex =
|
|
319
545
|
action.target === state.key && action.source
|
|
320
546
|
? state.routes.findIndex((r) => r.key === action.source)
|
|
321
547
|
: state.index;
|
|
322
548
|
|
|
323
|
-
if (
|
|
324
|
-
const count = Math.max(
|
|
549
|
+
if (currentIndex > 0) {
|
|
550
|
+
const count = Math.max(currentIndex - action.payload.count + 1, 1);
|
|
325
551
|
const routes = state.routes
|
|
326
552
|
.slice(0, count)
|
|
327
|
-
.concat(state.routes.slice(
|
|
553
|
+
.concat(state.routes.slice(currentIndex + 1));
|
|
328
554
|
|
|
329
555
|
return {
|
|
330
556
|
...state,
|
|
@@ -346,126 +572,97 @@ export default function StackRouter(options: StackRouterOptions) {
|
|
|
346
572
|
options
|
|
347
573
|
);
|
|
348
574
|
|
|
349
|
-
case '
|
|
350
|
-
|
|
351
|
-
action.
|
|
352
|
-
|
|
353
|
-
|
|
575
|
+
case 'POP_TO': {
|
|
576
|
+
const currentIndex =
|
|
577
|
+
action.target === state.key && action.source
|
|
578
|
+
? state.routes.findLastIndex((r) => r.key === action.source)
|
|
579
|
+
: state.index;
|
|
580
|
+
|
|
581
|
+
if (currentIndex === -1) {
|
|
354
582
|
return null;
|
|
355
583
|
}
|
|
356
584
|
|
|
357
|
-
if (
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
const getId =
|
|
362
|
-
// `getId` and `key` can't be used together
|
|
363
|
-
action.payload.key === undefined &&
|
|
364
|
-
action.payload.name !== undefined
|
|
365
|
-
? options.routeGetIdList[action.payload.name]
|
|
366
|
-
: undefined;
|
|
367
|
-
const id = getId?.({ params: action.payload.params });
|
|
368
|
-
|
|
369
|
-
if (id) {
|
|
370
|
-
index = state.routes.findIndex(
|
|
371
|
-
(route) =>
|
|
372
|
-
route.name === action.payload.name &&
|
|
373
|
-
id === getId?.({ params: route.params })
|
|
374
|
-
);
|
|
375
|
-
} else if (
|
|
376
|
-
(state.routes[state.index].name === action.payload.name &&
|
|
377
|
-
action.payload.key === undefined) ||
|
|
378
|
-
state.routes[state.index].key === action.payload.key
|
|
379
|
-
) {
|
|
380
|
-
index = state.index;
|
|
381
|
-
} else {
|
|
382
|
-
for (let i = state.routes.length - 1; i >= 0; i--) {
|
|
383
|
-
if (
|
|
384
|
-
(state.routes[i].name === action.payload.name &&
|
|
385
|
-
action.payload.key === undefined) ||
|
|
386
|
-
state.routes[i].key === action.payload.key
|
|
387
|
-
) {
|
|
388
|
-
index = i;
|
|
389
|
-
break;
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
}
|
|
585
|
+
if (!state.routeNames.includes(action.payload.name)) {
|
|
586
|
+
return null;
|
|
587
|
+
}
|
|
393
588
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
action.payload.key &&
|
|
397
|
-
action.payload.name === undefined
|
|
398
|
-
) {
|
|
399
|
-
return null;
|
|
400
|
-
}
|
|
589
|
+
// If the route already exists, navigate to it
|
|
590
|
+
let index = -1;
|
|
401
591
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
...state.routes,
|
|
405
|
-
{
|
|
406
|
-
key:
|
|
407
|
-
action.payload.key ?? `${action.payload.name}-${nanoid()}`,
|
|
408
|
-
name: action.payload.name,
|
|
409
|
-
path: action.payload.path,
|
|
410
|
-
params:
|
|
411
|
-
routeParamList[action.payload.name] !== undefined
|
|
412
|
-
? {
|
|
413
|
-
...routeParamList[action.payload.name],
|
|
414
|
-
...action.payload.params,
|
|
415
|
-
}
|
|
416
|
-
: action.payload.params,
|
|
417
|
-
},
|
|
418
|
-
];
|
|
419
|
-
|
|
420
|
-
return {
|
|
421
|
-
...state,
|
|
422
|
-
routes,
|
|
423
|
-
index: routes.length - 1,
|
|
424
|
-
};
|
|
425
|
-
}
|
|
592
|
+
const getId = options.routeGetIdList[action.payload.name];
|
|
593
|
+
const id = getId?.({ params: action.payload.params });
|
|
426
594
|
|
|
427
|
-
|
|
595
|
+
if (id !== undefined) {
|
|
596
|
+
index = state.routes.findIndex(
|
|
597
|
+
(route) =>
|
|
598
|
+
route.name === action.payload.name &&
|
|
599
|
+
id === getId?.({ params: route.params })
|
|
600
|
+
);
|
|
601
|
+
} else if (state.routes[currentIndex].name === action.payload.name) {
|
|
602
|
+
index = currentIndex;
|
|
603
|
+
} else {
|
|
604
|
+
for (let i = currentIndex; i >= 0; i--) {
|
|
605
|
+
if (state.routes[i].name === action.payload.name) {
|
|
606
|
+
index = i;
|
|
607
|
+
break;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
}
|
|
428
611
|
|
|
429
|
-
|
|
612
|
+
// If the route doesn't exist, remove the current route and add the new one
|
|
613
|
+
if (index === -1) {
|
|
614
|
+
// Re-use preloaded route if available
|
|
615
|
+
let route = state.preloadedRoutes.find(
|
|
616
|
+
(route) =>
|
|
617
|
+
route.name === action.payload.name &&
|
|
618
|
+
id === getId?.({ params: route.params })
|
|
619
|
+
);
|
|
430
620
|
|
|
431
|
-
if (
|
|
432
|
-
|
|
433
|
-
action.payload.params !== undefined ||
|
|
434
|
-
routeParamList[route.name] !== undefined
|
|
435
|
-
? {
|
|
436
|
-
...routeParamList[route.name],
|
|
437
|
-
...route.params,
|
|
438
|
-
...action.payload.params,
|
|
439
|
-
}
|
|
440
|
-
: route.params;
|
|
441
|
-
} else {
|
|
442
|
-
params =
|
|
443
|
-
routeParamList[route.name] !== undefined
|
|
444
|
-
? {
|
|
445
|
-
...routeParamList[route.name],
|
|
446
|
-
...action.payload.params,
|
|
447
|
-
}
|
|
448
|
-
: action.payload.params;
|
|
621
|
+
if (!route) {
|
|
622
|
+
route = createRouteFromAction({ action, routeParamList });
|
|
449
623
|
}
|
|
450
624
|
|
|
625
|
+
const routes = state.routes.slice(0, currentIndex).concat(route);
|
|
626
|
+
|
|
451
627
|
return {
|
|
452
628
|
...state,
|
|
453
|
-
index,
|
|
454
|
-
routes
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
? {
|
|
459
|
-
...route,
|
|
460
|
-
path: action.payload.path ?? route.path,
|
|
461
|
-
params,
|
|
462
|
-
}
|
|
463
|
-
: state.routes[index],
|
|
464
|
-
],
|
|
629
|
+
index: routes.length - 1,
|
|
630
|
+
routes,
|
|
631
|
+
preloadedRoutes: state.preloadedRoutes.filter(
|
|
632
|
+
(r) => r.key !== route.key
|
|
633
|
+
),
|
|
465
634
|
};
|
|
466
635
|
}
|
|
467
636
|
|
|
468
|
-
|
|
637
|
+
const route = state.routes[index];
|
|
638
|
+
|
|
639
|
+
let params;
|
|
640
|
+
|
|
641
|
+
if (action.payload.merge) {
|
|
642
|
+
params =
|
|
643
|
+
action.payload.params !== undefined ||
|
|
644
|
+
routeParamList[route.name] !== undefined
|
|
645
|
+
? {
|
|
646
|
+
...routeParamList[route.name],
|
|
647
|
+
...route.params,
|
|
648
|
+
...action.payload.params,
|
|
649
|
+
}
|
|
650
|
+
: route.params;
|
|
651
|
+
} else {
|
|
652
|
+
params = createParamsFromAction({ action, routeParamList });
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
return {
|
|
656
|
+
...state,
|
|
657
|
+
index,
|
|
658
|
+
routes: [
|
|
659
|
+
...state.routes.slice(0, index),
|
|
660
|
+
params !== route.params
|
|
661
|
+
? { ...route, params }
|
|
662
|
+
: state.routes[index],
|
|
663
|
+
],
|
|
664
|
+
};
|
|
665
|
+
}
|
|
469
666
|
|
|
470
667
|
case 'GO_BACK':
|
|
471
668
|
if (state.index > 0) {
|
|
@@ -483,6 +680,47 @@ export default function StackRouter(options: StackRouterOptions) {
|
|
|
483
680
|
|
|
484
681
|
return null;
|
|
485
682
|
|
|
683
|
+
case 'PRELOAD': {
|
|
684
|
+
const getId = options.routeGetIdList[action.payload.name];
|
|
685
|
+
const id = getId?.({ params: action.payload.params });
|
|
686
|
+
|
|
687
|
+
let route: Route<string> | undefined;
|
|
688
|
+
|
|
689
|
+
if (id !== undefined) {
|
|
690
|
+
route = state.routes.find(
|
|
691
|
+
(route) =>
|
|
692
|
+
route.name === action.payload.name &&
|
|
693
|
+
id === getId?.({ params: route.params })
|
|
694
|
+
);
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
if (route) {
|
|
698
|
+
return {
|
|
699
|
+
...state,
|
|
700
|
+
routes: state.routes.map((r) => {
|
|
701
|
+
if (r.key !== route?.key) {
|
|
702
|
+
return r;
|
|
703
|
+
}
|
|
704
|
+
return {
|
|
705
|
+
...r,
|
|
706
|
+
params: createParamsFromAction({ action, routeParamList }),
|
|
707
|
+
};
|
|
708
|
+
}),
|
|
709
|
+
};
|
|
710
|
+
} else {
|
|
711
|
+
return {
|
|
712
|
+
...state,
|
|
713
|
+
preloadedRoutes: state.preloadedRoutes
|
|
714
|
+
.filter(
|
|
715
|
+
(r) =>
|
|
716
|
+
r.name !== action.payload.name ||
|
|
717
|
+
id !== getId?.({ params: r.params })
|
|
718
|
+
)
|
|
719
|
+
.concat(createRouteFromAction({ action, routeParamList })),
|
|
720
|
+
};
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
|
|
486
724
|
default:
|
|
487
725
|
return BaseRouter.getStateForAction(state, action);
|
|
488
726
|
}
|