@react-navigation/routers 8.0.0-alpha.2 → 8.0.0-alpha.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/module/BaseRouter.js +64 -61
- package/lib/module/BaseRouter.js.map +1 -1
- package/lib/module/CommonActions.js +9 -21
- package/lib/module/CommonActions.js.map +1 -1
- package/lib/module/DrawerRouter.js +15 -14
- package/lib/module/DrawerRouter.js.map +1 -1
- package/lib/module/StackRouter.js +287 -166
- package/lib/module/StackRouter.js.map +1 -1
- package/lib/module/SwitchRouter.js +426 -0
- package/lib/module/SwitchRouter.js.map +1 -0
- package/lib/module/TabRouter.js +14 -290
- package/lib/module/TabRouter.js.map +1 -1
- package/lib/typescript/src/BaseRouter.d.ts +10 -8
- package/lib/typescript/src/BaseRouter.d.ts.map +1 -1
- package/lib/typescript/src/CommonActions.d.ts +42 -39
- package/lib/typescript/src/CommonActions.d.ts.map +1 -1
- package/lib/typescript/src/DrawerRouter.d.ts +6 -5
- package/lib/typescript/src/DrawerRouter.d.ts.map +1 -1
- package/lib/typescript/src/StackRouter.d.ts +70 -24
- package/lib/typescript/src/StackRouter.d.ts.map +1 -1
- package/lib/typescript/src/SwitchRouter.d.ts +69 -0
- package/lib/typescript/src/SwitchRouter.d.ts.map +1 -0
- package/lib/typescript/src/TabRouter.d.ts +4 -24
- package/lib/typescript/src/TabRouter.d.ts.map +1 -1
- package/lib/typescript/src/createParamsFromAction.d.ts +2 -2
- package/lib/typescript/src/createParamsFromAction.d.ts.map +1 -1
- package/lib/typescript/src/createRouteFromAction.d.ts +2 -2
- package/lib/typescript/src/createRouteFromAction.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +9 -9
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +20 -30
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/package.json +8 -8
- package/src/BaseRouter.tsx +93 -80
- package/src/CommonActions.tsx +44 -66
- package/src/DrawerRouter.tsx +28 -22
- package/src/StackRouter.tsx +551 -238
- package/src/SwitchRouter.tsx +724 -0
- package/src/TabRouter.tsx +24 -463
- package/src/createParamsFromAction.tsx +1 -1
- package/src/createRouteFromAction.tsx +1 -1
- package/src/types.tsx +39 -41
package/src/TabRouter.tsx
CHANGED
|
@@ -1,44 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import {
|
|
2
|
+
type SwitchActionType as TabActionType,
|
|
3
|
+
SwitchRouter,
|
|
4
|
+
type SwitchRouterOptions as TabRouterOptions,
|
|
5
|
+
} from './SwitchRouter';
|
|
5
6
|
import type {
|
|
6
7
|
CommonNavigationAction,
|
|
7
|
-
DefaultRouterOptions,
|
|
8
8
|
NavigationState,
|
|
9
9
|
ParamListBase,
|
|
10
|
-
PartialState,
|
|
11
|
-
Route,
|
|
12
10
|
Router,
|
|
13
11
|
} from './types';
|
|
14
12
|
|
|
15
|
-
export type TabActionType
|
|
16
|
-
type: 'JUMP_TO';
|
|
17
|
-
payload: { name: string; params?: object };
|
|
18
|
-
source?: string;
|
|
19
|
-
target?: string;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export type BackBehavior =
|
|
23
|
-
| 'firstRoute'
|
|
24
|
-
| 'initialRoute'
|
|
25
|
-
| 'order'
|
|
26
|
-
| 'history'
|
|
27
|
-
| 'fullHistory'
|
|
28
|
-
| 'none';
|
|
29
|
-
|
|
30
|
-
export type TabRouterOptions = DefaultRouterOptions & {
|
|
31
|
-
/**
|
|
32
|
-
* Control how going back should behave
|
|
33
|
-
* - `firstRoute` - return to the first defined route
|
|
34
|
-
* - `initialRoute` - return to the route from `initialRouteName`
|
|
35
|
-
* - `order` - return to the route defined before the focused route
|
|
36
|
-
* - `history` - return to last visited route; if the same route is visited multiple times, the older entries are dropped from the history
|
|
37
|
-
* - `fullHistory` - return to last visited route; doesn't drop duplicate entries unlike `history` - matches behavior of web pages
|
|
38
|
-
* - `none` - do not handle going back
|
|
39
|
-
*/
|
|
40
|
-
backBehavior?: BackBehavior;
|
|
41
|
-
};
|
|
13
|
+
export type { TabActionType, TabRouterOptions };
|
|
42
14
|
|
|
43
15
|
export type TabNavigationState<ParamList extends ParamListBase> = Omit<
|
|
44
16
|
NavigationState<ParamList>,
|
|
@@ -74,8 +46,6 @@ export type TabActionHelpers<ParamList extends ParamListBase> = {
|
|
|
74
46
|
): void;
|
|
75
47
|
};
|
|
76
48
|
|
|
77
|
-
const TYPE_ROUTE = 'route' as const;
|
|
78
|
-
|
|
79
49
|
export const TabActions = {
|
|
80
50
|
jumpTo(name: string, params?: object) {
|
|
81
51
|
return {
|
|
@@ -85,452 +55,43 @@ export const TabActions = {
|
|
|
85
55
|
},
|
|
86
56
|
};
|
|
87
57
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
const
|
|
95
|
-
{
|
|
96
|
-
type: TYPE_ROUTE,
|
|
97
|
-
key: routes[index].key,
|
|
98
|
-
},
|
|
99
|
-
];
|
|
100
|
-
|
|
101
|
-
let initialRouteIndex;
|
|
102
|
-
|
|
103
|
-
switch (backBehavior) {
|
|
104
|
-
case 'order':
|
|
105
|
-
for (let i = index; i > 0; i--) {
|
|
106
|
-
history.unshift({
|
|
107
|
-
type: TYPE_ROUTE,
|
|
108
|
-
key: routes[i - 1].key,
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
break;
|
|
112
|
-
case 'firstRoute':
|
|
113
|
-
if (index !== 0) {
|
|
114
|
-
history.unshift({
|
|
115
|
-
type: TYPE_ROUTE,
|
|
116
|
-
key: routes[0].key,
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
break;
|
|
120
|
-
case 'initialRoute':
|
|
121
|
-
initialRouteIndex = routes.findIndex(
|
|
122
|
-
(route) => route.name === initialRouteName
|
|
123
|
-
);
|
|
124
|
-
initialRouteIndex = initialRouteIndex === -1 ? 0 : initialRouteIndex;
|
|
125
|
-
|
|
126
|
-
if (index !== initialRouteIndex) {
|
|
127
|
-
history.unshift({
|
|
128
|
-
type: TYPE_ROUTE,
|
|
129
|
-
key: routes[initialRouteIndex].key,
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
break;
|
|
133
|
-
case 'history':
|
|
134
|
-
case 'fullHistory':
|
|
135
|
-
// The history will fill up on navigation
|
|
136
|
-
break;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return history;
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
const changeIndex = (
|
|
143
|
-
state: TabNavigationState<ParamListBase>,
|
|
144
|
-
index: number,
|
|
145
|
-
backBehavior: BackBehavior,
|
|
146
|
-
initialRouteName: string | undefined
|
|
147
|
-
) => {
|
|
148
|
-
let history = state.history;
|
|
149
|
-
|
|
150
|
-
if (backBehavior === 'history' || backBehavior === 'fullHistory') {
|
|
151
|
-
const currentRoute = state.routes[index];
|
|
152
|
-
|
|
153
|
-
if (backBehavior === 'history') {
|
|
154
|
-
// Remove the existing key from the history to de-duplicate it
|
|
155
|
-
history = history.filter((it) =>
|
|
156
|
-
it.type === 'route' ? it.key !== currentRoute.key : false
|
|
157
|
-
);
|
|
158
|
-
} else if (backBehavior === 'fullHistory') {
|
|
159
|
-
const lastHistoryRouteItemIndex = history.findLastIndex(
|
|
160
|
-
(item) => item.type === 'route'
|
|
161
|
-
);
|
|
162
|
-
|
|
163
|
-
if (currentRoute.key === history[lastHistoryRouteItemIndex]?.key) {
|
|
164
|
-
// For full-history, only remove if it matches the last route
|
|
165
|
-
// Useful for drawer, if current route was in history, then drawer state changed
|
|
166
|
-
// Then we only need to move the route to the front
|
|
167
|
-
history = [
|
|
168
|
-
...history.slice(0, lastHistoryRouteItemIndex),
|
|
169
|
-
...history.slice(lastHistoryRouteItemIndex + 1),
|
|
170
|
-
];
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
history = history.concat({
|
|
175
|
-
type: TYPE_ROUTE,
|
|
176
|
-
key: currentRoute.key,
|
|
177
|
-
params: backBehavior === 'fullHistory' ? currentRoute.params : undefined,
|
|
178
|
-
});
|
|
179
|
-
} else {
|
|
180
|
-
history = getRouteHistory(
|
|
181
|
-
state.routes,
|
|
182
|
-
index,
|
|
183
|
-
backBehavior,
|
|
184
|
-
initialRouteName
|
|
185
|
-
);
|
|
186
|
-
}
|
|
58
|
+
export function TabRouter(
|
|
59
|
+
options: TabRouterOptions
|
|
60
|
+
): Router<
|
|
61
|
+
TabNavigationState<ParamListBase>,
|
|
62
|
+
TabActionType | CommonNavigationAction
|
|
63
|
+
> {
|
|
64
|
+
const router = SwitchRouter<'tab'>(options);
|
|
187
65
|
|
|
188
66
|
return {
|
|
189
|
-
...
|
|
190
|
-
index,
|
|
191
|
-
history,
|
|
192
|
-
};
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
export function TabRouter({
|
|
196
|
-
initialRouteName,
|
|
197
|
-
backBehavior = 'firstRoute',
|
|
198
|
-
}: TabRouterOptions) {
|
|
199
|
-
const router: Router<
|
|
200
|
-
TabNavigationState<ParamListBase>,
|
|
201
|
-
TabActionType | CommonNavigationAction
|
|
202
|
-
> = {
|
|
203
|
-
...BaseRouter,
|
|
67
|
+
...router,
|
|
204
68
|
|
|
205
69
|
type: 'tab',
|
|
206
70
|
|
|
207
|
-
getInitialState(
|
|
208
|
-
const
|
|
209
|
-
initialRouteName !== undefined && routeNames.includes(initialRouteName)
|
|
210
|
-
? routeNames.indexOf(initialRouteName)
|
|
211
|
-
: 0;
|
|
212
|
-
|
|
213
|
-
const routes = routeNames.map((name) => ({
|
|
214
|
-
name,
|
|
215
|
-
key: `${name}-${nanoid()}`,
|
|
216
|
-
params: routeParamList[name],
|
|
217
|
-
}));
|
|
218
|
-
|
|
219
|
-
const history = getRouteHistory(
|
|
220
|
-
routes,
|
|
221
|
-
index,
|
|
222
|
-
backBehavior,
|
|
223
|
-
initialRouteName
|
|
224
|
-
);
|
|
71
|
+
getInitialState(routerOptions) {
|
|
72
|
+
const state = router.getInitialState(routerOptions);
|
|
225
73
|
|
|
226
74
|
return {
|
|
227
|
-
|
|
75
|
+
...state,
|
|
228
76
|
type: 'tab',
|
|
229
|
-
key: `tab-${
|
|
230
|
-
index,
|
|
231
|
-
routeNames,
|
|
232
|
-
history,
|
|
233
|
-
routes,
|
|
234
|
-
preloadedRouteKeys: [],
|
|
77
|
+
key: `tab-${state.key}`,
|
|
235
78
|
};
|
|
236
79
|
},
|
|
237
80
|
|
|
238
|
-
getRehydratedState(partialState,
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
if (state.stale === false) {
|
|
242
|
-
return state;
|
|
81
|
+
getRehydratedState(partialState, routerOptions) {
|
|
82
|
+
if (partialState.stale === false) {
|
|
83
|
+
return partialState;
|
|
243
84
|
}
|
|
244
85
|
|
|
245
|
-
const
|
|
246
|
-
const route = (
|
|
247
|
-
state as PartialState<TabNavigationState<ParamListBase>>
|
|
248
|
-
).routes.find((r) => r.name === name);
|
|
249
|
-
|
|
250
|
-
return {
|
|
251
|
-
...route,
|
|
252
|
-
name,
|
|
253
|
-
key:
|
|
254
|
-
route && route.name === name && route.key
|
|
255
|
-
? route.key
|
|
256
|
-
: `${name}-${nanoid()}`,
|
|
257
|
-
params:
|
|
258
|
-
routeParamList[name] !== undefined
|
|
259
|
-
? {
|
|
260
|
-
...routeParamList[name],
|
|
261
|
-
...(route ? route.params : undefined),
|
|
262
|
-
}
|
|
263
|
-
: route
|
|
264
|
-
? route.params
|
|
265
|
-
: undefined,
|
|
266
|
-
} as Route<string>;
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
const index = Math.min(
|
|
270
|
-
Math.max(routeNames.indexOf(state.routes[state?.index ?? 0]?.name), 0),
|
|
271
|
-
routes.length - 1
|
|
272
|
-
);
|
|
273
|
-
|
|
274
|
-
const routeKeys = routes.map((route) => route.key);
|
|
275
|
-
|
|
276
|
-
const history =
|
|
277
|
-
state.history?.filter((it) => routeKeys.includes(it.key)) ?? [];
|
|
278
|
-
|
|
279
|
-
return changeIndex(
|
|
280
|
-
{
|
|
281
|
-
stale: false,
|
|
282
|
-
type: 'tab',
|
|
283
|
-
key: `tab-${nanoid()}`,
|
|
284
|
-
index,
|
|
285
|
-
routeNames,
|
|
286
|
-
history,
|
|
287
|
-
routes,
|
|
288
|
-
preloadedRouteKeys:
|
|
289
|
-
state.preloadedRouteKeys?.filter((key) =>
|
|
290
|
-
routeKeys.includes(key)
|
|
291
|
-
) ?? [],
|
|
292
|
-
},
|
|
293
|
-
index,
|
|
294
|
-
backBehavior,
|
|
295
|
-
initialRouteName
|
|
296
|
-
);
|
|
297
|
-
},
|
|
298
|
-
|
|
299
|
-
getStateForRouteNamesChange(
|
|
300
|
-
state,
|
|
301
|
-
{ routeNames, routeParamList, routeKeyChanges }
|
|
302
|
-
) {
|
|
303
|
-
const routes = routeNames.map(
|
|
304
|
-
(name) =>
|
|
305
|
-
state.routes.find(
|
|
306
|
-
(r) => r.name === name && !routeKeyChanges.includes(r.name)
|
|
307
|
-
) || {
|
|
308
|
-
name,
|
|
309
|
-
key: `${name}-${nanoid()}`,
|
|
310
|
-
params: routeParamList[name],
|
|
311
|
-
}
|
|
312
|
-
);
|
|
313
|
-
|
|
314
|
-
const index = Math.max(
|
|
315
|
-
0,
|
|
316
|
-
routeNames.indexOf(state.routes[state.index].name)
|
|
317
|
-
);
|
|
318
|
-
|
|
319
|
-
let history = state.history.filter(
|
|
320
|
-
// Type will always be 'route' for tabs, but could be different in a router extending this (e.g. drawer)
|
|
321
|
-
(it) => it.type !== 'route' || routes.find((r) => r.key === it.key)
|
|
322
|
-
);
|
|
323
|
-
|
|
324
|
-
if (!history.length) {
|
|
325
|
-
history = getRouteHistory(
|
|
326
|
-
routes,
|
|
327
|
-
index,
|
|
328
|
-
backBehavior,
|
|
329
|
-
initialRouteName
|
|
330
|
-
);
|
|
331
|
-
}
|
|
86
|
+
const state = router.getRehydratedState(partialState, routerOptions);
|
|
332
87
|
|
|
333
88
|
return {
|
|
334
89
|
...state,
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
routes,
|
|
338
|
-
index,
|
|
90
|
+
type: 'tab',
|
|
91
|
+
key: `tab-${state.key}`,
|
|
339
92
|
};
|
|
340
93
|
},
|
|
341
94
|
|
|
342
|
-
getStateForRouteFocus(state, key) {
|
|
343
|
-
const index = state.routes.findIndex((r) => r.key === key);
|
|
344
|
-
|
|
345
|
-
if (index === -1 || index === state.index) {
|
|
346
|
-
return state;
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
return changeIndex(state, index, backBehavior, initialRouteName);
|
|
350
|
-
},
|
|
351
|
-
|
|
352
|
-
getStateForAction(state, action, { routeParamList, routeGetIdList }) {
|
|
353
|
-
switch (action.type) {
|
|
354
|
-
case 'JUMP_TO':
|
|
355
|
-
case 'NAVIGATE': {
|
|
356
|
-
const index = state.routes.findIndex(
|
|
357
|
-
(route) => route.name === action.payload.name
|
|
358
|
-
);
|
|
359
|
-
|
|
360
|
-
if (index === -1) {
|
|
361
|
-
return null;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
const updatedState = changeIndex(
|
|
365
|
-
{
|
|
366
|
-
...state,
|
|
367
|
-
routes: state.routes.map((route) => {
|
|
368
|
-
if (route.name !== action.payload.name) {
|
|
369
|
-
return route;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
const getId = routeGetIdList[route.name];
|
|
373
|
-
|
|
374
|
-
const currentId = getId?.({ params: route.params });
|
|
375
|
-
const nextId = getId?.({ params: action.payload.params });
|
|
376
|
-
|
|
377
|
-
const key =
|
|
378
|
-
currentId === nextId
|
|
379
|
-
? route.key
|
|
380
|
-
: `${route.name}-${nanoid()}`;
|
|
381
|
-
|
|
382
|
-
let params;
|
|
383
|
-
|
|
384
|
-
if (
|
|
385
|
-
action.type === 'NAVIGATE' &&
|
|
386
|
-
action.payload.merge &&
|
|
387
|
-
currentId === nextId
|
|
388
|
-
) {
|
|
389
|
-
params =
|
|
390
|
-
action.payload.params !== undefined ||
|
|
391
|
-
routeParamList[route.name] !== undefined
|
|
392
|
-
? {
|
|
393
|
-
...routeParamList[route.name],
|
|
394
|
-
...route.params,
|
|
395
|
-
...action.payload.params,
|
|
396
|
-
}
|
|
397
|
-
: route.params;
|
|
398
|
-
} else {
|
|
399
|
-
params = createParamsFromAction({ action, routeParamList });
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
const path =
|
|
403
|
-
action.type === 'NAVIGATE' && action.payload.path != null
|
|
404
|
-
? action.payload.path
|
|
405
|
-
: route.path;
|
|
406
|
-
|
|
407
|
-
return params !== route.params || path !== route.path
|
|
408
|
-
? { ...route, key, path, params }
|
|
409
|
-
: route;
|
|
410
|
-
}),
|
|
411
|
-
},
|
|
412
|
-
index,
|
|
413
|
-
backBehavior,
|
|
414
|
-
initialRouteName
|
|
415
|
-
);
|
|
416
|
-
|
|
417
|
-
return {
|
|
418
|
-
...updatedState,
|
|
419
|
-
preloadedRouteKeys: updatedState.preloadedRouteKeys.filter(
|
|
420
|
-
(key) => key !== state.routes[updatedState.index].key
|
|
421
|
-
),
|
|
422
|
-
};
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
case 'GO_BACK': {
|
|
426
|
-
const focusedRoute = state.routes[state.index];
|
|
427
|
-
|
|
428
|
-
if (state.history.length === 1 && !focusedRoute.history?.length) {
|
|
429
|
-
return null;
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
const lastHistoryItem = state.history[state.history.length - 1];
|
|
433
|
-
|
|
434
|
-
if (
|
|
435
|
-
lastHistoryItem?.type === 'route' &&
|
|
436
|
-
focusedRoute.history?.length
|
|
437
|
-
) {
|
|
438
|
-
const routes = [...state.routes];
|
|
439
|
-
const history = [...focusedRoute.history];
|
|
440
|
-
const last = history.pop();
|
|
441
|
-
|
|
442
|
-
routes[state.index] = {
|
|
443
|
-
...focusedRoute,
|
|
444
|
-
params:
|
|
445
|
-
last?.type === 'params' ? last.params : focusedRoute.params,
|
|
446
|
-
history,
|
|
447
|
-
};
|
|
448
|
-
|
|
449
|
-
return {
|
|
450
|
-
...state,
|
|
451
|
-
routes,
|
|
452
|
-
};
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
const previousHistoryItem = state.history[state.history.length - 2];
|
|
456
|
-
const previousKey = previousHistoryItem?.key;
|
|
457
|
-
const index = state.routes.findLastIndex(
|
|
458
|
-
(route) => route.key === previousKey
|
|
459
|
-
);
|
|
460
|
-
|
|
461
|
-
if (index === -1) {
|
|
462
|
-
return null;
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
let routes = state.routes;
|
|
466
|
-
|
|
467
|
-
if (
|
|
468
|
-
backBehavior === 'fullHistory' &&
|
|
469
|
-
routes[index].params !== previousHistoryItem.params
|
|
470
|
-
) {
|
|
471
|
-
routes = [...state.routes];
|
|
472
|
-
routes[index] = {
|
|
473
|
-
...routes[index],
|
|
474
|
-
params: previousHistoryItem.params,
|
|
475
|
-
};
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
return {
|
|
479
|
-
...state,
|
|
480
|
-
routes,
|
|
481
|
-
preloadedRouteKeys: state.preloadedRouteKeys.filter(
|
|
482
|
-
(key) => key !== state.routes[index].key
|
|
483
|
-
),
|
|
484
|
-
history: state.history.slice(0, -1),
|
|
485
|
-
index,
|
|
486
|
-
};
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
case 'PRELOAD': {
|
|
490
|
-
const routeIndex = state.routes.findIndex(
|
|
491
|
-
(route) => route.name === action.payload.name
|
|
492
|
-
);
|
|
493
|
-
|
|
494
|
-
if (routeIndex === -1) {
|
|
495
|
-
return null;
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
const route = state.routes[routeIndex];
|
|
499
|
-
|
|
500
|
-
const getId = routeGetIdList[route.name];
|
|
501
|
-
|
|
502
|
-
const currentId = getId?.({ params: route.params });
|
|
503
|
-
const nextId = getId?.({ params: action.payload.params });
|
|
504
|
-
|
|
505
|
-
const key =
|
|
506
|
-
currentId === nextId ? route.key : `${route.name}-${nanoid()}`;
|
|
507
|
-
|
|
508
|
-
const params = createParamsFromAction({ action, routeParamList });
|
|
509
|
-
const newRoute =
|
|
510
|
-
params !== route.params ? { ...route, key, params } : route;
|
|
511
|
-
|
|
512
|
-
return {
|
|
513
|
-
...state,
|
|
514
|
-
preloadedRouteKeys: state.preloadedRouteKeys
|
|
515
|
-
.filter((key) => key !== route.key)
|
|
516
|
-
.concat(newRoute.key),
|
|
517
|
-
routes: state.routes.map((route, index) =>
|
|
518
|
-
index === routeIndex ? newRoute : route
|
|
519
|
-
),
|
|
520
|
-
history:
|
|
521
|
-
key === route.key
|
|
522
|
-
? state.history
|
|
523
|
-
: state.history.filter((record) => record.key !== route.key),
|
|
524
|
-
};
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
default:
|
|
528
|
-
return BaseRouter.getStateForAction(state, action);
|
|
529
|
-
}
|
|
530
|
-
},
|
|
531
|
-
|
|
532
95
|
actionCreators: TabActions,
|
|
533
96
|
};
|
|
534
|
-
|
|
535
|
-
return router;
|
|
536
97
|
}
|
package/src/types.tsx
CHANGED
|
@@ -6,7 +6,7 @@ export type NavigationRoute<
|
|
|
6
6
|
ParamList extends ParamListBase,
|
|
7
7
|
RouteName extends keyof ParamList,
|
|
8
8
|
> = Route<Extract<RouteName, string>, ParamList[RouteName]> & {
|
|
9
|
-
state?: NavigationState | PartialState<NavigationState
|
|
9
|
+
state?: NavigationState | PartialState<NavigationState> | undefined;
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
export type NavigationState<ParamList extends ParamListBase = ParamListBase> =
|
|
@@ -26,13 +26,13 @@ export type NavigationState<ParamList extends ParamListBase = ParamListBase> =
|
|
|
26
26
|
/**
|
|
27
27
|
* Alternative entries for history.
|
|
28
28
|
*/
|
|
29
|
-
history?: unknown[];
|
|
29
|
+
history?: unknown[] | undefined;
|
|
30
30
|
/**
|
|
31
31
|
* List of rendered routes.
|
|
32
32
|
*/
|
|
33
33
|
routes: NavigationRoute<ParamList, keyof ParamList>[];
|
|
34
34
|
/**
|
|
35
|
-
*
|
|
35
|
+
* The type of the state, i.e., whether it's for tab, stack, drawer etc.
|
|
36
36
|
* During rehydration, the state will be discarded if type doesn't match with router type.
|
|
37
37
|
* It can also be used to detect the type of the navigator we're dealing with.
|
|
38
38
|
*/
|
|
@@ -45,21 +45,23 @@ export type NavigationState<ParamList extends ParamListBase = ParamListBase> =
|
|
|
45
45
|
|
|
46
46
|
export type InitialState = Readonly<
|
|
47
47
|
Partial<Omit<NavigationState, 'stale' | 'routes'>> & {
|
|
48
|
-
routes: (Omit<Route<string>, 'key'> & {
|
|
48
|
+
routes: (Omit<Route<string>, 'key'> & {
|
|
49
|
+
state?: InitialState | undefined;
|
|
50
|
+
})[];
|
|
49
51
|
}
|
|
50
52
|
>;
|
|
51
53
|
|
|
52
54
|
export type PartialRoute<R extends Route<string>> = Omit<R, 'key'> & {
|
|
53
|
-
key?: string;
|
|
54
|
-
state?: PartialState<NavigationState
|
|
55
|
+
key?: string | undefined;
|
|
56
|
+
state?: NavigationState | PartialState<NavigationState> | undefined;
|
|
55
57
|
};
|
|
56
58
|
|
|
57
59
|
export type PartialState<State extends NavigationState> = Partial<
|
|
58
60
|
Omit<State, 'stale' | 'routes'>
|
|
59
61
|
> &
|
|
60
62
|
Readonly<{
|
|
61
|
-
stale?: true;
|
|
62
|
-
routes: PartialRoute<
|
|
63
|
+
stale?: true | undefined;
|
|
64
|
+
routes: PartialRoute<State['routes'][number]>[];
|
|
63
65
|
}>;
|
|
64
66
|
|
|
65
67
|
export type Route<
|
|
@@ -79,26 +81,31 @@ export type Route<
|
|
|
79
81
|
* Path associated with the route.
|
|
80
82
|
* Usually present when the screen was opened from a deep link.
|
|
81
83
|
*/
|
|
82
|
-
path?: string;
|
|
84
|
+
path?: string | undefined;
|
|
83
85
|
/**
|
|
84
86
|
* History of param changes for this route.
|
|
85
87
|
*/
|
|
86
|
-
history?:
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
88
|
+
history?:
|
|
89
|
+
| {
|
|
90
|
+
type: 'params';
|
|
91
|
+
params: undefined extends Params
|
|
92
|
+
? Readonly<Params> | undefined
|
|
93
|
+
: Readonly<Params>;
|
|
94
|
+
}[]
|
|
95
|
+
| undefined;
|
|
96
|
+
} & (undefined extends Params
|
|
97
|
+
? {
|
|
98
|
+
/**
|
|
99
|
+
* Params for this route
|
|
100
|
+
*/
|
|
101
|
+
params?: Readonly<Params> | undefined;
|
|
102
|
+
}
|
|
103
|
+
: {
|
|
104
|
+
/**
|
|
105
|
+
* Params for this route
|
|
106
|
+
*/
|
|
107
|
+
params: Readonly<Params>;
|
|
108
|
+
})
|
|
102
109
|
>;
|
|
103
110
|
|
|
104
111
|
export type ParamListBase = Record<string, object | undefined>;
|
|
@@ -111,15 +118,15 @@ export type NavigationAction = Readonly<{
|
|
|
111
118
|
/**
|
|
112
119
|
* Additional data for the action
|
|
113
120
|
*/
|
|
114
|
-
payload?: object;
|
|
121
|
+
payload?: object | undefined;
|
|
115
122
|
/**
|
|
116
123
|
* Key of the route which dispatched this action.
|
|
117
124
|
*/
|
|
118
|
-
source?: string;
|
|
125
|
+
source?: string | undefined;
|
|
119
126
|
/**
|
|
120
127
|
* Key of the navigator which should handle this action.
|
|
121
128
|
*/
|
|
122
|
-
target?: string;
|
|
129
|
+
target?: string | undefined;
|
|
123
130
|
}>;
|
|
124
131
|
|
|
125
132
|
export type ActionCreators<Action extends NavigationAction> = {
|
|
@@ -131,7 +138,7 @@ export type DefaultRouterOptions<RouteName extends string = string> = {
|
|
|
131
138
|
* Name of the route to focus by on initial render.
|
|
132
139
|
* If not specified, usually the first route is used.
|
|
133
140
|
*/
|
|
134
|
-
initialRouteName?: RouteName;
|
|
141
|
+
initialRouteName?: RouteName | undefined;
|
|
135
142
|
};
|
|
136
143
|
|
|
137
144
|
export type RouterFactory<
|
|
@@ -145,7 +152,9 @@ export type RouterConfigOptions = {
|
|
|
145
152
|
routeParamList: ParamListBase;
|
|
146
153
|
routeGetIdList: Record<
|
|
147
154
|
string,
|
|
148
|
-
| ((options: {
|
|
155
|
+
| ((options: {
|
|
156
|
+
params?: Record<string, any> | undefined;
|
|
157
|
+
}) => string | undefined)
|
|
149
158
|
| undefined
|
|
150
159
|
>;
|
|
151
160
|
};
|
|
@@ -228,17 +237,6 @@ export type Router<
|
|
|
228
237
|
*/
|
|
229
238
|
shouldActionChangeFocus(action: NavigationAction): boolean;
|
|
230
239
|
|
|
231
|
-
/**
|
|
232
|
-
* Get the list of routes from the navigation state.
|
|
233
|
-
*
|
|
234
|
-
* By default, `state.routes` is used.
|
|
235
|
-
* But in some cases (like `preloadedRoutes` in stack),
|
|
236
|
-
* the actual list of routes may be different.
|
|
237
|
-
*
|
|
238
|
-
* @param state Navigation state to get the routes from.
|
|
239
|
-
*/
|
|
240
|
-
getRoutesFromState?(state: State): Route<string>[];
|
|
241
|
-
|
|
242
240
|
/**
|
|
243
241
|
* Action creators for the router.
|
|
244
242
|
*/
|