@react-navigation/core 8.0.0-alpha.19 → 8.0.0-alpha.20
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/BaseNavigationContainer.js +6 -2
- package/lib/module/BaseNavigationContainer.js.map +1 -1
- package/lib/module/StaticNavigation.js +72 -61
- package/lib/module/StaticNavigation.js.map +1 -1
- package/lib/module/findFocusedRoute.js +7 -4
- package/lib/module/findFocusedRoute.js.map +1 -1
- package/lib/module/getActionFromState.js +25 -12
- package/lib/module/getActionFromState.js.map +1 -1
- package/lib/module/getPathFromState.js +24 -9
- package/lib/module/getPathFromState.js.map +1 -1
- package/lib/module/getPatternParts.js +3 -0
- package/lib/module/getPatternParts.js.map +1 -1
- package/lib/module/getStateFromPath.js +164 -78
- package/lib/module/getStateFromPath.js.map +1 -1
- package/lib/module/index.js +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/types.js +8 -0
- package/lib/module/types.js.map +1 -1
- package/lib/module/useDescriptors.js +13 -6
- package/lib/module/useDescriptors.js.map +1 -1
- package/lib/module/useFocusEvents.js +5 -1
- package/lib/module/useFocusEvents.js.map +1 -1
- package/lib/module/useNavigation.js.map +1 -1
- package/lib/module/useNavigationBuilder.js +18 -5
- package/lib/module/useNavigationBuilder.js.map +1 -1
- package/lib/module/useNavigationCache.js +1 -1
- package/lib/module/useNavigationCache.js.map +1 -1
- package/lib/module/useNavigationState.js.map +1 -1
- package/lib/module/useOnAction.js +1 -1
- package/lib/module/useOnAction.js.map +1 -1
- package/lib/module/useRoute.js.map +1 -1
- package/lib/module/validatePathConfig.js +2 -1
- package/lib/module/validatePathConfig.js.map +1 -1
- package/lib/typescript/src/BaseNavigationContainer.d.ts +2 -2
- package/lib/typescript/src/BaseNavigationContainer.d.ts.map +1 -1
- package/lib/typescript/src/EnsureSingleNavigator.d.ts +1 -1
- package/lib/typescript/src/EnsureSingleNavigator.d.ts.map +1 -1
- package/lib/typescript/src/Group.d.ts +1 -1
- package/lib/typescript/src/Group.d.ts.map +1 -1
- package/lib/typescript/src/NavigationBuilderContext.d.ts +1 -1
- package/lib/typescript/src/NavigationBuilderContext.d.ts.map +1 -1
- package/lib/typescript/src/NavigationContainerRefContext.d.ts +1 -1
- package/lib/typescript/src/NavigationContainerRefContext.d.ts.map +1 -1
- package/lib/typescript/src/NavigationHelpersContext.d.ts +1 -1
- package/lib/typescript/src/NavigationHelpersContext.d.ts.map +1 -1
- package/lib/typescript/src/NavigationIndependentTree.d.ts +1 -1
- package/lib/typescript/src/NavigationIndependentTree.d.ts.map +1 -1
- package/lib/typescript/src/NavigationProvider.d.ts +6 -6
- package/lib/typescript/src/NavigationProvider.d.ts.map +1 -1
- package/lib/typescript/src/PreventRemoveProvider.d.ts +1 -1
- package/lib/typescript/src/PreventRemoveProvider.d.ts.map +1 -1
- package/lib/typescript/src/SceneView.d.ts +3 -2
- package/lib/typescript/src/SceneView.d.ts.map +1 -1
- package/lib/typescript/src/Screen.d.ts +1 -1
- package/lib/typescript/src/Screen.d.ts.map +1 -1
- package/lib/typescript/src/StaticNavigation.d.ts +68 -73
- package/lib/typescript/src/StaticNavigation.d.ts.map +1 -1
- package/lib/typescript/src/createNavigationContainerRef.d.ts +1 -1
- package/lib/typescript/src/createNavigationContainerRef.d.ts.map +1 -1
- package/lib/typescript/src/createNavigatorFactory.d.ts +3 -3
- package/lib/typescript/src/createNavigatorFactory.d.ts.map +1 -1
- package/lib/typescript/src/findFocusedRoute.d.ts.map +1 -1
- package/lib/typescript/src/getActionFromState.d.ts +1 -1
- package/lib/typescript/src/getActionFromState.d.ts.map +1 -1
- package/lib/typescript/src/getPathFromState.d.ts +1 -1
- package/lib/typescript/src/getPathFromState.d.ts.map +1 -1
- package/lib/typescript/src/getPatternParts.d.ts +1 -0
- package/lib/typescript/src/getPatternParts.d.ts.map +1 -1
- package/lib/typescript/src/getStateFromPath.d.ts +2 -2
- package/lib/typescript/src/getStateFromPath.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +34 -33
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/theming/ThemeContext.d.ts +1 -1
- package/lib/typescript/src/theming/ThemeContext.d.ts.map +1 -1
- package/lib/typescript/src/theming/ThemeProvider.d.ts +2 -2
- package/lib/typescript/src/theming/ThemeProvider.d.ts.map +1 -1
- package/lib/typescript/src/theming/useTheme.d.ts +1 -1
- package/lib/typescript/src/theming/useTheme.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +72 -37
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/useChildListeners.d.ts +3 -3
- package/lib/typescript/src/useChildListeners.d.ts.map +1 -1
- package/lib/typescript/src/useComponent.d.ts +1 -1
- package/lib/typescript/src/useComponent.d.ts.map +1 -1
- package/lib/typescript/src/useDescriptors.d.ts +5 -5
- package/lib/typescript/src/useDescriptors.d.ts.map +1 -1
- package/lib/typescript/src/useEventEmitter.d.ts +1 -1
- package/lib/typescript/src/useEventEmitter.d.ts.map +1 -1
- package/lib/typescript/src/useFocusEvents.d.ts +2 -2
- package/lib/typescript/src/useFocusEvents.d.ts.map +1 -1
- package/lib/typescript/src/useFocusedListenersChildrenAdapter.d.ts +2 -2
- package/lib/typescript/src/useFocusedListenersChildrenAdapter.d.ts.map +1 -1
- package/lib/typescript/src/useKeyedChildListeners.d.ts +3 -3
- package/lib/typescript/src/useKeyedChildListeners.d.ts.map +1 -1
- package/lib/typescript/src/useNavigation.d.ts +5 -3
- package/lib/typescript/src/useNavigation.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationBuilder.d.ts +7 -7
- package/lib/typescript/src/useNavigationBuilder.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationCache.d.ts +3 -3
- package/lib/typescript/src/useNavigationCache.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationContainerRef.d.ts +1 -1
- package/lib/typescript/src/useNavigationContainerRef.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationHelpers.d.ts +4 -4
- package/lib/typescript/src/useNavigationHelpers.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationState.d.ts +2 -2
- package/lib/typescript/src/useNavigationState.d.ts.map +1 -1
- package/lib/typescript/src/useOnAction.d.ts +3 -3
- package/lib/typescript/src/useOnAction.d.ts.map +1 -1
- package/lib/typescript/src/useOnGetState.d.ts +1 -1
- package/lib/typescript/src/useOnGetState.d.ts.map +1 -1
- package/lib/typescript/src/useOnPreventRemove.d.ts +3 -3
- package/lib/typescript/src/useOnPreventRemove.d.ts.map +1 -1
- package/lib/typescript/src/useOptionsGetters.d.ts +1 -1
- package/lib/typescript/src/useOptionsGetters.d.ts.map +1 -1
- package/lib/typescript/src/usePreventRemoveContext.d.ts +1 -1
- package/lib/typescript/src/useRoute.d.ts +2 -2
- package/lib/typescript/src/useRoute.d.ts.map +1 -1
- package/lib/typescript/src/useRouteCache.d.ts +2 -2
- package/lib/typescript/src/useRouteCache.d.ts.map +1 -1
- package/lib/typescript/src/useStateForPath.d.ts +1 -1
- package/lib/typescript/src/useStateForPath.d.ts.map +1 -1
- package/lib/typescript/src/utilities.d.ts +4 -3
- package/lib/typescript/src/utilities.d.ts.map +1 -1
- package/lib/typescript/src/validatePathConfig.d.ts.map +1 -1
- package/package.json +18 -17
- package/src/BaseNavigationContainer.tsx +7 -2
- package/src/StaticNavigation.tsx +220 -248
- package/src/findFocusedRoute.tsx +10 -5
- package/src/getActionFromState.tsx +43 -30
- package/src/getPathFromState.tsx +40 -20
- package/src/getPatternParts.tsx +8 -0
- package/src/getStateFromPath.tsx +244 -67
- package/src/index.tsx +39 -1
- package/src/types.tsx +167 -122
- package/src/useDescriptors.tsx +22 -10
- package/src/useFocusEvents.tsx +7 -1
- package/src/useNavigation.tsx +8 -4
- package/src/useNavigationBuilder.tsx +22 -7
- package/src/useNavigationCache.tsx +4 -4
- package/src/useNavigationState.tsx +3 -3
- package/src/useOnAction.tsx +1 -1
- package/src/useRoute.tsx +4 -2
- package/src/utilities.tsx +17 -11
- package/src/validatePathConfig.tsx +1 -0
package/src/StaticNavigation.tsx
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
NavigationState,
|
|
3
|
-
ParamListBase,
|
|
4
|
-
Route,
|
|
5
|
-
} from '@react-navigation/routers';
|
|
1
|
+
import type { NavigationState, ParamListBase } from '@react-navigation/routers';
|
|
6
2
|
import * as React from 'react';
|
|
7
3
|
import { isValidElementType } from 'react-is';
|
|
8
4
|
|
|
5
|
+
import {
|
|
6
|
+
combinePatternParts,
|
|
7
|
+
getPatternParts,
|
|
8
|
+
type PatternPart,
|
|
9
|
+
} from './getPatternParts';
|
|
9
10
|
import type {
|
|
10
11
|
DefaultNavigatorOptions,
|
|
11
12
|
EventMapBase,
|
|
@@ -31,50 +32,54 @@ import type {
|
|
|
31
32
|
ValidPathPattern,
|
|
32
33
|
} from './utilities';
|
|
33
34
|
|
|
35
|
+
type ScreenComponentParams<T> = [T] extends [
|
|
36
|
+
React.ComponentType<{ route: { params: infer Params } }>,
|
|
37
|
+
]
|
|
38
|
+
? Params
|
|
39
|
+
: undefined;
|
|
40
|
+
|
|
34
41
|
type ParamsForScreenComponent<T> = [T] extends [(...args: any[]) => any]
|
|
35
|
-
?
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
42
|
+
? // Don't infer params from a parameterless function component
|
|
43
|
+
// It'd infer `unknown` - but we want `undefined` if no params are accepted
|
|
44
|
+
HasArguments<T> extends true
|
|
45
|
+
? ScreenComponentParams<T>
|
|
39
46
|
: undefined
|
|
40
|
-
:
|
|
41
|
-
? Params
|
|
42
|
-
: undefined;
|
|
47
|
+
: ScreenComponentParams<T>;
|
|
43
48
|
|
|
44
49
|
// If every nested route's params include `undefined`, the nested navigator
|
|
45
50
|
// itself can be omitted. Otherwise, require `NavigatorScreenParams`.
|
|
46
51
|
type ParamsForNestedNavigator<
|
|
47
52
|
T extends { config: any },
|
|
48
53
|
ParamList extends {} = StaticParamList<T>,
|
|
54
|
+
Params = NavigatorScreenParams<ParamList>,
|
|
49
55
|
> = {
|
|
50
|
-
//
|
|
51
|
-
// If
|
|
56
|
+
// Map each route to `never` when params are optional, or name when params are required
|
|
57
|
+
// If every route has optional params, the resulting union is `never`
|
|
52
58
|
[RouteName in keyof ParamList]-?: undefined extends ParamList[RouteName]
|
|
53
59
|
? never
|
|
54
60
|
: RouteName;
|
|
55
61
|
}[keyof ParamList] extends never
|
|
56
|
-
?
|
|
57
|
-
:
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
: ParamsForScreenComponent<T>;
|
|
67
|
-
|
|
68
|
-
// `screen` can be a union when users build their screens map from a
|
|
69
|
-
// `Record<K, V>`. A naked `T extends ...` conditional would distribute over
|
|
70
|
-
// every screen in that union, creating a large params union for each route.
|
|
71
|
-
// Wrapping `T` in a tuple checks the union as a whole and avoids that fanout.
|
|
72
|
-
type ParamsForScreenInner<T> = [T] extends [{ config: any }]
|
|
62
|
+
? Params | undefined
|
|
63
|
+
: Params;
|
|
64
|
+
|
|
65
|
+
// If the screens were constructed from a `Record<K, V>`,
|
|
66
|
+
// the screen value (`T`) may be a union.
|
|
67
|
+
// A naked `T extends ...` conditional would distribute over every screen in the union,
|
|
68
|
+
// creating a large params union per route.
|
|
69
|
+
// Wrapping `T` in a tuple checks the union as a whole instead of distributing,
|
|
70
|
+
// https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#distributive-conditional-types
|
|
71
|
+
type ParamsForScreen<T> = [T] extends [{ config: any }]
|
|
73
72
|
? ParamsForNestedNavigator<T>
|
|
74
73
|
: [T] extends [React.ComponentType<any>]
|
|
75
74
|
? ParamsForScreenComponent<T>
|
|
76
75
|
: undefined;
|
|
77
76
|
|
|
77
|
+
// Unlike `ParamsForScreen`, we want to distribute for `Record<string, Component | StaticNavigation>`
|
|
78
|
+
// This creates union like:
|
|
79
|
+
// `C extends C ? ParamsForScreen<C> : never) | (S extends S ? ParamsForScreen<S> : never)`
|
|
80
|
+
// `= ParamsForScreen<C> | ParamsForScreen<S>`
|
|
81
|
+
type ParamsForScreenEntry<T> = T extends T ? ParamsForScreen<T> : never;
|
|
82
|
+
|
|
78
83
|
// Only infer params from linking if it's a pattern (i.e., contains ':')
|
|
79
84
|
// or if parse is present for query params.
|
|
80
85
|
// This avoids inferring non-literals like 'string' without parse.
|
|
@@ -85,30 +90,25 @@ type ShouldInferFromLinking<Linking> = Linking extends
|
|
|
85
90
|
? true
|
|
86
91
|
: false;
|
|
87
92
|
|
|
88
|
-
type MergeLinkingAndScreenParams<LinkingParams, ScreenParams> =
|
|
89
|
-
undefined extends ScreenParams
|
|
90
|
-
? FlatType<LinkingParams>
|
|
91
|
-
: FlatType<LinkingParams & ScreenParams>;
|
|
92
|
-
|
|
93
93
|
/**
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
* -
|
|
97
|
-
*
|
|
94
|
+
* Params type derived from both linking and screen.
|
|
95
|
+
*
|
|
96
|
+
* - Linking has no extractable params (no ':' in path, no `parse`): returns
|
|
97
|
+
* screen params alone.
|
|
98
|
+
* - Linking has params + screen is a nested navigator: intersects path params
|
|
99
|
+
* with the navigator's screen params.
|
|
100
|
+
* - Linking has params + screen is a component without route params: returns
|
|
101
|
+
* path params alone (avoids `LP & undefined = never`).
|
|
102
|
+
* - Linking has params + screen has route params: intersects them.
|
|
98
103
|
*/
|
|
99
|
-
type ParamsForConfig<Linking, Screen
|
|
100
|
-
Linking
|
|
101
|
-
Screen,
|
|
102
|
-
ParamsForScreenInner<Screen>
|
|
103
|
-
>;
|
|
104
|
-
|
|
105
|
-
type ParamsForConfigInternal<Linking, Screen, SP> = undefined extends Linking
|
|
106
|
-
? SP
|
|
107
|
-
: ShouldInferFromLinking<Linking> extends true
|
|
104
|
+
type ParamsForConfig<Linking, Screen, Params = ParamsForScreen<Screen>> =
|
|
105
|
+
ShouldInferFromLinking<Linking> extends true
|
|
108
106
|
? [Screen] extends [{ config: any }]
|
|
109
|
-
? FlatType<InferParamsFromLinking<Linking>> &
|
|
110
|
-
:
|
|
111
|
-
|
|
107
|
+
? FlatType<InferParamsFromLinking<Linking>> & Params
|
|
108
|
+
: undefined extends Params
|
|
109
|
+
? FlatType<InferParamsFromLinking<Linking>>
|
|
110
|
+
: FlatType<InferParamsFromLinking<Linking> & Params>
|
|
111
|
+
: Params;
|
|
112
112
|
|
|
113
113
|
type ParamListForScreens<Screens> = {
|
|
114
114
|
[Key in KeysOf<Screens>]: Screens[Key] extends StaticScreenConfig<
|
|
@@ -117,10 +117,11 @@ type ParamListForScreens<Screens> = {
|
|
|
117
117
|
any,
|
|
118
118
|
any,
|
|
119
119
|
any,
|
|
120
|
+
any,
|
|
120
121
|
any
|
|
121
122
|
>
|
|
122
123
|
? ParamsForConfig<Linking, Screen>
|
|
123
|
-
:
|
|
124
|
+
: ParamsForScreenEntry<Screens[Key]>;
|
|
124
125
|
};
|
|
125
126
|
|
|
126
127
|
type ParamListForGroups<
|
|
@@ -139,25 +140,25 @@ type ParamListForGroups<
|
|
|
139
140
|
? ParamListForScreens<UnionToIntersection<Screens>>
|
|
140
141
|
: {};
|
|
141
142
|
|
|
142
|
-
type RouteType<Params
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
143
|
+
type RouteType<Params, P = AnyToUnknown<Params>> = Readonly<
|
|
144
|
+
{
|
|
145
|
+
key: string;
|
|
146
|
+
name: string;
|
|
147
|
+
path?: string | undefined;
|
|
148
|
+
history?: { type: 'params'; params: object }[] | undefined;
|
|
149
|
+
} & (undefined extends Params
|
|
150
|
+
? {
|
|
151
|
+
/**
|
|
152
|
+
* Params for this route
|
|
153
|
+
*/
|
|
154
|
+
params?: P;
|
|
155
|
+
}
|
|
156
|
+
: {
|
|
157
|
+
/**
|
|
158
|
+
* Params for this route
|
|
159
|
+
*/
|
|
160
|
+
params: P;
|
|
161
|
+
})
|
|
161
162
|
>;
|
|
162
163
|
|
|
163
164
|
type StaticScreenConfigLinkingAlias = {
|
|
@@ -200,6 +201,21 @@ type StaticScreenConfigLinkingAlias = {
|
|
|
200
201
|
* ```
|
|
201
202
|
*/
|
|
202
203
|
stringify?: Record<string, (value: unknown) => string>;
|
|
204
|
+
/**
|
|
205
|
+
* Whether this path can resolve to multiple routes.
|
|
206
|
+
* Both routes should specify `shared: true` for this to work.
|
|
207
|
+
*
|
|
208
|
+
* When automatic path generation is enabled,
|
|
209
|
+
* screens using the same path pattern and the same screen component
|
|
210
|
+
* or navigator will be automatically marked as shared.
|
|
211
|
+
* Explicitly specifying the option overrides the automatic detection.
|
|
212
|
+
*
|
|
213
|
+
* This is useful when same screen used in multiple navigators,
|
|
214
|
+
* e.g. tabs with stacks containing profile screen in each stack.
|
|
215
|
+
*
|
|
216
|
+
* The path defined first will be the canonical path.
|
|
217
|
+
*/
|
|
218
|
+
shared?: boolean;
|
|
203
219
|
};
|
|
204
220
|
|
|
205
221
|
export type StaticScreenConfigLinking =
|
|
@@ -397,11 +413,10 @@ type StaticConfigScreens<
|
|
|
397
413
|
in out NavigationList extends NavigationListBase<ParamList>,
|
|
398
414
|
> = {
|
|
399
415
|
[RouteName in keyof ParamList]:
|
|
400
|
-
|
|
|
401
|
-
| StaticNavigation<any>
|
|
416
|
+
| StaticScreenConfigScreen
|
|
402
417
|
| StaticScreenConfig<
|
|
403
418
|
StaticScreenConfigLinking,
|
|
404
|
-
|
|
419
|
+
StaticScreenConfigScreen,
|
|
405
420
|
State,
|
|
406
421
|
ScreenOptions,
|
|
407
422
|
EventMap,
|
|
@@ -425,27 +440,6 @@ type StaticConfigGroup<
|
|
|
425
440
|
* This can be useful for conditional rendering of group of screens.
|
|
426
441
|
*/
|
|
427
442
|
if?: () => boolean;
|
|
428
|
-
/**
|
|
429
|
-
* Linking config for the screens in the group.
|
|
430
|
-
* This can be a string to specify the path, or an object following properties:
|
|
431
|
-
* - `path`
|
|
432
|
-
* - `stringify`
|
|
433
|
-
* - `parse`
|
|
434
|
-
*
|
|
435
|
-
* The path specified will be prepended to the paths of the screens in the group.
|
|
436
|
-
* The `parse` and `stringify` properties will be merged.
|
|
437
|
-
*
|
|
438
|
-
* @example
|
|
439
|
-
* ```js
|
|
440
|
-
* linking: {
|
|
441
|
-
* path: 'users/:id',
|
|
442
|
-
* parse: {
|
|
443
|
-
* id: (id) => parseInt(id, 10),
|
|
444
|
-
* }
|
|
445
|
-
* },
|
|
446
|
-
* ```
|
|
447
|
-
*/
|
|
448
|
-
linking?: LinkingForGroup;
|
|
449
443
|
/**
|
|
450
444
|
* Static navigation config or Component to render for the screen.
|
|
451
445
|
*/
|
|
@@ -475,6 +469,22 @@ type StaticConfigInternal<
|
|
|
475
469
|
EventMap extends EventMapBase,
|
|
476
470
|
NavigationList extends NavigationListBase<ParamList>,
|
|
477
471
|
Navigator extends React.ComponentType<any>,
|
|
472
|
+
Screens = StaticConfigScreens<
|
|
473
|
+
ParamList,
|
|
474
|
+
State,
|
|
475
|
+
ScreenOptions,
|
|
476
|
+
EventMap,
|
|
477
|
+
NavigationList
|
|
478
|
+
>,
|
|
479
|
+
Groups = {
|
|
480
|
+
[key: string]: StaticConfigGroup<
|
|
481
|
+
ParamList,
|
|
482
|
+
State,
|
|
483
|
+
ScreenOptions,
|
|
484
|
+
EventMap,
|
|
485
|
+
NavigationList
|
|
486
|
+
>;
|
|
487
|
+
},
|
|
478
488
|
> = Omit<
|
|
479
489
|
Omit<
|
|
480
490
|
React.ComponentProps<Navigator>,
|
|
@@ -494,49 +504,21 @@ type StaticConfigInternal<
|
|
|
494
504
|
/**
|
|
495
505
|
* Screens to render in the navigator and their configuration.
|
|
496
506
|
*/
|
|
497
|
-
screens:
|
|
498
|
-
ParamList,
|
|
499
|
-
State,
|
|
500
|
-
ScreenOptions,
|
|
501
|
-
EventMap,
|
|
502
|
-
NavigationList
|
|
503
|
-
>;
|
|
507
|
+
screens: Screens;
|
|
504
508
|
/**
|
|
505
509
|
* Groups of screens to render in the navigator and their configuration.
|
|
506
510
|
*/
|
|
507
|
-
groups?:
|
|
508
|
-
[key: string]: StaticConfigGroup<
|
|
509
|
-
ParamList,
|
|
510
|
-
State,
|
|
511
|
-
ScreenOptions,
|
|
512
|
-
EventMap,
|
|
513
|
-
NavigationList
|
|
514
|
-
>;
|
|
515
|
-
};
|
|
511
|
+
groups?: Groups;
|
|
516
512
|
}
|
|
517
513
|
| {
|
|
518
514
|
/**
|
|
519
515
|
* Screens to render in the navigator and their configuration.
|
|
520
516
|
*/
|
|
521
|
-
screens?:
|
|
522
|
-
ParamList,
|
|
523
|
-
State,
|
|
524
|
-
ScreenOptions,
|
|
525
|
-
EventMap,
|
|
526
|
-
NavigationList
|
|
527
|
-
>;
|
|
517
|
+
screens?: Screens;
|
|
528
518
|
/**
|
|
529
519
|
* Groups of screens to render in the navigator and their configuration.
|
|
530
520
|
*/
|
|
531
|
-
groups:
|
|
532
|
-
[key: string]: StaticConfigGroup<
|
|
533
|
-
ParamList,
|
|
534
|
-
State,
|
|
535
|
-
ScreenOptions,
|
|
536
|
-
EventMap,
|
|
537
|
-
NavigationList
|
|
538
|
-
>;
|
|
539
|
-
};
|
|
521
|
+
groups: Groups;
|
|
540
522
|
}
|
|
541
523
|
);
|
|
542
524
|
|
|
@@ -754,10 +736,6 @@ export function createComponentForStaticConfig<
|
|
|
754
736
|
return NavigatorComponent;
|
|
755
737
|
}
|
|
756
738
|
|
|
757
|
-
type LinkingForGroup =
|
|
758
|
-
| Pick<PathConfig<any>, 'path' | 'stringify' | 'parse'>
|
|
759
|
-
| string;
|
|
760
|
-
|
|
761
739
|
type TreeForPathConfig = {
|
|
762
740
|
config: ConfigForPathConfig;
|
|
763
741
|
};
|
|
@@ -765,12 +743,7 @@ type TreeForPathConfig = {
|
|
|
765
743
|
type ConfigForPathConfig = {
|
|
766
744
|
initialRouteName?: string;
|
|
767
745
|
screens?: Record<string, ScreenForPathConfig>;
|
|
768
|
-
groups?: {
|
|
769
|
-
[key: string]: {
|
|
770
|
-
linking?: LinkingForGroup;
|
|
771
|
-
screens: Record<string, ScreenForPathConfig>;
|
|
772
|
-
};
|
|
773
|
-
};
|
|
746
|
+
groups?: Record<string, { screens: Record<string, ScreenForPathConfig> }>;
|
|
774
747
|
};
|
|
775
748
|
|
|
776
749
|
type LinkingForPathConfig =
|
|
@@ -783,14 +756,95 @@ type LinkingForPathConfig =
|
|
|
783
756
|
| null
|
|
784
757
|
| undefined;
|
|
785
758
|
|
|
759
|
+
type ScreenValueForPathConfig = React.ComponentType<{}> | TreeForPathConfig;
|
|
760
|
+
|
|
786
761
|
type ScreenForPathConfig =
|
|
787
|
-
|
|
|
788
|
-
| TreeForPathConfig
|
|
762
|
+
| ScreenValueForPathConfig
|
|
789
763
|
| {
|
|
790
|
-
screen:
|
|
764
|
+
screen: ScreenValueForPathConfig;
|
|
791
765
|
linking?: LinkingForPathConfig;
|
|
792
766
|
};
|
|
793
767
|
|
|
768
|
+
type PathConfigMapForStaticNavigation = Record<
|
|
769
|
+
string,
|
|
770
|
+
string | PathConfigForStaticNavigation | undefined
|
|
771
|
+
>;
|
|
772
|
+
|
|
773
|
+
type PathConfigForStaticNavigation = Omit<
|
|
774
|
+
PathConfig<ParamListBase>,
|
|
775
|
+
'screens'
|
|
776
|
+
> & {
|
|
777
|
+
initialRouteName?: string | undefined;
|
|
778
|
+
screens?: PathConfigMapForStaticNavigation | undefined;
|
|
779
|
+
};
|
|
780
|
+
|
|
781
|
+
// Mark screens that resolve to the same pattern and same component or navigator
|
|
782
|
+
const markSharedPathConfigs = (
|
|
783
|
+
screens: PathConfigMapForStaticNavigation,
|
|
784
|
+
sources: WeakMap<PathConfigForStaticNavigation, ScreenValueForPathConfig>,
|
|
785
|
+
blocked: WeakSet<PathConfigForStaticNavigation>
|
|
786
|
+
) => {
|
|
787
|
+
const candidates = new Map<string, PathConfigForStaticNavigation[]>();
|
|
788
|
+
|
|
789
|
+
const collect = (
|
|
790
|
+
screens: PathConfigMapForStaticNavigation,
|
|
791
|
+
parentParts: PatternPart[],
|
|
792
|
+
disabled: boolean
|
|
793
|
+
) => {
|
|
794
|
+
for (const config of Object.values(screens)) {
|
|
795
|
+
if (config == null || typeof config === 'string') {
|
|
796
|
+
continue;
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
const parts =
|
|
800
|
+
typeof config.path === 'string'
|
|
801
|
+
? combinePatternParts(
|
|
802
|
+
parentParts,
|
|
803
|
+
getPatternParts(config.path),
|
|
804
|
+
config.exact
|
|
805
|
+
)
|
|
806
|
+
: parentParts;
|
|
807
|
+
|
|
808
|
+
if (sources.has(config) && typeof config.path === 'string') {
|
|
809
|
+
if (disabled) {
|
|
810
|
+
blocked.add(config);
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
const pattern = parts.map((part) => part.segment).join('/');
|
|
814
|
+
const entries = candidates.get(pattern) ?? [];
|
|
815
|
+
|
|
816
|
+
entries.push(config);
|
|
817
|
+
candidates.set(pattern, entries);
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
if (config.screens) {
|
|
821
|
+
collect(config.screens, parts, disabled || config.shared === false);
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
};
|
|
825
|
+
|
|
826
|
+
collect(screens, [], false);
|
|
827
|
+
|
|
828
|
+
for (const entries of candidates.values()) {
|
|
829
|
+
for (const entry of entries) {
|
|
830
|
+
const source = sources.get(entry);
|
|
831
|
+
|
|
832
|
+
if (
|
|
833
|
+
entry.shared === undefined &&
|
|
834
|
+
!blocked.has(entry) &&
|
|
835
|
+
entries.some(
|
|
836
|
+
(candidate) =>
|
|
837
|
+
candidate !== entry &&
|
|
838
|
+
!blocked.has(candidate) &&
|
|
839
|
+
sources.get(candidate) === source
|
|
840
|
+
)
|
|
841
|
+
) {
|
|
842
|
+
entry.shared = true;
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
};
|
|
847
|
+
|
|
794
848
|
/**
|
|
795
849
|
* Create a path config object from a static navigation config for deep linking.
|
|
796
850
|
*
|
|
@@ -821,6 +875,12 @@ export function createPathConfigForStaticNavigation<ParamList extends {}>(
|
|
|
821
875
|
let initialScreenConfig: PathConfig<{}> | undefined;
|
|
822
876
|
let hasEmptyPath = false;
|
|
823
877
|
|
|
878
|
+
const blocked = new WeakSet<PathConfigForStaticNavigation>();
|
|
879
|
+
const sources = new WeakMap<
|
|
880
|
+
PathConfigForStaticNavigation,
|
|
881
|
+
ScreenValueForPathConfig
|
|
882
|
+
>();
|
|
883
|
+
|
|
824
884
|
const createPathConfigForTree = (
|
|
825
885
|
t: TreeForPathConfig,
|
|
826
886
|
o: { initialRouteName?: string | undefined } | undefined,
|
|
@@ -847,7 +907,6 @@ export function createPathConfigForStaticNavigation<ParamList extends {}>(
|
|
|
847
907
|
|
|
848
908
|
const createPathConfigForScreens = (
|
|
849
909
|
screens: Record<string, ScreenForPathConfig>,
|
|
850
|
-
groupLinking: LinkingForGroup | undefined,
|
|
851
910
|
initialRouteName: string | undefined
|
|
852
911
|
) => {
|
|
853
912
|
return Object.fromEntries(
|
|
@@ -866,26 +925,15 @@ export function createPathConfigForStaticNavigation<ParamList extends {}>(
|
|
|
866
925
|
return 0;
|
|
867
926
|
})
|
|
868
927
|
.map(([key, item]) => {
|
|
869
|
-
const screenConfig:
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
const normalizePath = (path: string, exact?: boolean) => {
|
|
876
|
-
const normalizePart = (part: string) =>
|
|
877
|
-
part.replace(/^\/+|\/+$/g, '');
|
|
878
|
-
|
|
879
|
-
if (exact) {
|
|
880
|
-
return normalizePart(path);
|
|
881
|
-
}
|
|
928
|
+
const screenConfig: PathConfigForStaticNavigation = {};
|
|
929
|
+
|
|
930
|
+
sources.set(
|
|
931
|
+
screenConfig,
|
|
932
|
+
typeof item === 'object' && 'screen' in item ? item.screen : item
|
|
933
|
+
);
|
|
882
934
|
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
.map(normalizePart)
|
|
886
|
-
.filter(Boolean)
|
|
887
|
-
.join('/');
|
|
888
|
-
};
|
|
935
|
+
const normalizePath = (path: string) =>
|
|
936
|
+
path.replace(/^\/+|\/+$/g, '');
|
|
889
937
|
|
|
890
938
|
if ('linking' in item && item.linking !== undefined) {
|
|
891
939
|
if (typeof item.linking === 'string') {
|
|
@@ -894,7 +942,7 @@ export function createPathConfigForStaticNavigation<ParamList extends {}>(
|
|
|
894
942
|
item.linking != null &&
|
|
895
943
|
typeof item.linking === 'object'
|
|
896
944
|
) {
|
|
897
|
-
Object.assign(screenConfig, item.linking);
|
|
945
|
+
Object.assign(screenConfig, { ...item.linking });
|
|
898
946
|
}
|
|
899
947
|
}
|
|
900
948
|
|
|
@@ -905,10 +953,7 @@ export function createPathConfigForStaticNavigation<ParamList extends {}>(
|
|
|
905
953
|
}
|
|
906
954
|
|
|
907
955
|
if (typeof screenConfig.path === 'string') {
|
|
908
|
-
screenConfig.path = normalizePath(
|
|
909
|
-
screenConfig.path,
|
|
910
|
-
screenConfig.exact
|
|
911
|
-
);
|
|
956
|
+
screenConfig.path = normalizePath(screenConfig.path);
|
|
912
957
|
}
|
|
913
958
|
|
|
914
959
|
if (screenConfig.alias != null) {
|
|
@@ -917,29 +962,9 @@ export function createPathConfigForStaticNavigation<ParamList extends {}>(
|
|
|
917
962
|
return normalizePath(alias);
|
|
918
963
|
}
|
|
919
964
|
|
|
920
|
-
const groupParse =
|
|
921
|
-
typeof groupLinking === 'string'
|
|
922
|
-
? undefined
|
|
923
|
-
: groupLinking?.parse;
|
|
924
|
-
const hasGroupParams =
|
|
925
|
-
groupParse != null &&
|
|
926
|
-
Object.keys(groupParse).some((name) =>
|
|
927
|
-
alias.path
|
|
928
|
-
.split('/')
|
|
929
|
-
.some((part) => part.startsWith(`:${name}`))
|
|
930
|
-
);
|
|
931
|
-
|
|
932
965
|
return {
|
|
933
966
|
...alias,
|
|
934
|
-
|
|
935
|
-
? {
|
|
936
|
-
parse: {
|
|
937
|
-
...groupParse,
|
|
938
|
-
...alias.parse,
|
|
939
|
-
},
|
|
940
|
-
}
|
|
941
|
-
: {}),
|
|
942
|
-
path: normalizePath(alias.path, alias.exact),
|
|
967
|
+
path: normalizePath(alias.path),
|
|
943
968
|
};
|
|
944
969
|
});
|
|
945
970
|
}
|
|
@@ -950,11 +975,6 @@ export function createPathConfigForStaticNavigation<ParamList extends {}>(
|
|
|
950
975
|
'screens' in screenConfig && screenConfig.screens != null;
|
|
951
976
|
const hasDisabledLinking =
|
|
952
977
|
'linking' in item && item.linking === null;
|
|
953
|
-
const hasNestedStaticConfig =
|
|
954
|
-
'config' in item ||
|
|
955
|
-
('screen' in item &&
|
|
956
|
-
'config' in item.screen &&
|
|
957
|
-
(item.screen.config.screens || item.screen.config.groups));
|
|
958
978
|
const childOptions =
|
|
959
979
|
'initialRouteName' in screenConfig &&
|
|
960
980
|
typeof screenConfig.initialRouteName === 'string'
|
|
@@ -973,15 +993,6 @@ export function createPathConfigForStaticNavigation<ParamList extends {}>(
|
|
|
973
993
|
);
|
|
974
994
|
}
|
|
975
995
|
|
|
976
|
-
if (
|
|
977
|
-
hasNestedStaticConfig &&
|
|
978
|
-
screenConfig.path == null &&
|
|
979
|
-
groupPath != null &&
|
|
980
|
-
!hasDisabledLinking
|
|
981
|
-
) {
|
|
982
|
-
screenConfig.path = normalizePath('');
|
|
983
|
-
}
|
|
984
|
-
|
|
985
996
|
const skipInitialDetectionInChild =
|
|
986
997
|
skipInitialDetection ||
|
|
987
998
|
(screenConfig.path != null && screenConfig.path !== '');
|
|
@@ -1016,7 +1027,6 @@ export function createPathConfigForStaticNavigation<ParamList extends {}>(
|
|
|
1016
1027
|
}
|
|
1017
1028
|
|
|
1018
1029
|
if (screens) {
|
|
1019
|
-
// @ts-expect-error - we can't type this properly
|
|
1020
1030
|
screenConfig.screens = screens;
|
|
1021
1031
|
}
|
|
1022
1032
|
|
|
@@ -1049,7 +1059,6 @@ export function createPathConfigForStaticNavigation<ParamList extends {}>(
|
|
|
1049
1059
|
}
|
|
1050
1060
|
} else {
|
|
1051
1061
|
if (
|
|
1052
|
-
!groupPath &&
|
|
1053
1062
|
!skipInitialDetection &&
|
|
1054
1063
|
allowAutoEmptyPath &&
|
|
1055
1064
|
(initialRouteName == null || key === initialRouteName) &&
|
|
@@ -1068,54 +1077,13 @@ export function createPathConfigForStaticNavigation<ParamList extends {}>(
|
|
|
1068
1077
|
}
|
|
1069
1078
|
}
|
|
1070
1079
|
|
|
1071
|
-
const groupOptionKeys =
|
|
1072
|
-
typeof groupLinking === 'string'
|
|
1073
|
-
? []
|
|
1074
|
-
: Object.keys({
|
|
1075
|
-
...groupLinking?.parse,
|
|
1076
|
-
...groupLinking?.stringify,
|
|
1077
|
-
});
|
|
1078
|
-
const hasAliasWithGroupParams =
|
|
1079
|
-
groupOptionKeys.length > 0 &&
|
|
1080
|
-
screenConfig.alias?.some((alias) => {
|
|
1081
|
-
if (typeof alias !== 'string') {
|
|
1082
|
-
return false;
|
|
1083
|
-
}
|
|
1084
|
-
|
|
1085
|
-
return groupOptionKeys.some((name) =>
|
|
1086
|
-
alias.split('/').some((part) => part.startsWith(`:${name}`))
|
|
1087
|
-
);
|
|
1088
|
-
});
|
|
1089
|
-
const shouldUseGroupOptions =
|
|
1090
|
-
typeof groupLinking !== 'string' &&
|
|
1091
|
-
groupLinking != null &&
|
|
1092
|
-
screenConfig.path != null &&
|
|
1093
|
-
screenConfig.path !== '' &&
|
|
1094
|
-
(!screenConfig.exact || hasAliasWithGroupParams);
|
|
1095
|
-
|
|
1096
|
-
if (shouldUseGroupOptions) {
|
|
1097
|
-
if (groupLinking.parse != null) {
|
|
1098
|
-
screenConfig.parse = {
|
|
1099
|
-
...groupLinking.parse,
|
|
1100
|
-
...screenConfig.parse,
|
|
1101
|
-
};
|
|
1102
|
-
}
|
|
1103
|
-
|
|
1104
|
-
if (groupLinking.stringify != null && !screenConfig.exact) {
|
|
1105
|
-
screenConfig.stringify = {
|
|
1106
|
-
...groupLinking.stringify,
|
|
1107
|
-
...screenConfig.stringify,
|
|
1108
|
-
};
|
|
1109
|
-
}
|
|
1110
|
-
}
|
|
1111
|
-
|
|
1112
1080
|
return [key, screenConfig] as const;
|
|
1113
1081
|
})
|
|
1114
1082
|
.filter(([, screen]) => Object.keys(screen).length > 0)
|
|
1115
1083
|
);
|
|
1116
1084
|
};
|
|
1117
1085
|
|
|
1118
|
-
const screens = {};
|
|
1086
|
+
const screens: PathConfigMapForStaticNavigation = {};
|
|
1119
1087
|
|
|
1120
1088
|
// Loop through the config to find screens and groups
|
|
1121
1089
|
// So we add the screens and groups in the same order as they are defined
|
|
@@ -1125,7 +1093,6 @@ export function createPathConfigForStaticNavigation<ParamList extends {}>(
|
|
|
1125
1093
|
screens,
|
|
1126
1094
|
createPathConfigForScreens(
|
|
1127
1095
|
t.config.screens,
|
|
1128
|
-
undefined,
|
|
1129
1096
|
o?.initialRouteName ?? t.config.initialRouteName
|
|
1130
1097
|
)
|
|
1131
1098
|
);
|
|
@@ -1137,7 +1104,6 @@ export function createPathConfigForStaticNavigation<ParamList extends {}>(
|
|
|
1137
1104
|
screens,
|
|
1138
1105
|
createPathConfigForScreens(
|
|
1139
1106
|
group.screens,
|
|
1140
|
-
group.linking,
|
|
1141
1107
|
o?.initialRouteName ?? t.config.initialRouteName
|
|
1142
1108
|
)
|
|
1143
1109
|
);
|
|
@@ -1158,5 +1124,11 @@ export function createPathConfigForStaticNavigation<ParamList extends {}>(
|
|
|
1158
1124
|
initialScreenConfig.path = '';
|
|
1159
1125
|
}
|
|
1160
1126
|
|
|
1161
|
-
|
|
1127
|
+
if (!screens) {
|
|
1128
|
+
return undefined;
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
markSharedPathConfigs(screens, sources, blocked);
|
|
1132
|
+
|
|
1133
|
+
return screens as PathConfigMap<ParamList>;
|
|
1162
1134
|
}
|