@react-navigation/core 7.14.0 → 8.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/module/BaseNavigationContainer.js +4 -9
- package/lib/module/BaseNavigationContainer.js.map +1 -1
- package/lib/module/NavigationIndependentTree.js +12 -7
- package/lib/module/NavigationIndependentTree.js.map +1 -1
- package/lib/module/NavigationProvider.js +49 -0
- package/lib/module/NavigationProvider.js.map +1 -0
- package/lib/module/PreventRemoveProvider.js +1 -1
- package/lib/module/PreventRemoveProvider.js.map +1 -1
- package/lib/module/SceneView.js.map +1 -1
- package/lib/module/StaticNavigation.js +32 -21
- package/lib/module/StaticNavigation.js.map +1 -1
- package/lib/module/createNavigationContainerRef.js.map +1 -1
- package/lib/module/getActionFromState.js +3 -2
- package/lib/module/getActionFromState.js.map +1 -1
- package/lib/module/getPathFromState.js +1 -1
- package/lib/module/getPathFromState.js.map +1 -1
- package/lib/module/getStateFromPath.js +3 -3
- package/lib/module/getStateFromPath.js.map +1 -1
- package/lib/module/index.js +1 -2
- package/lib/module/index.js.map +1 -1
- package/lib/module/theming/ThemeContext.js.map +1 -1
- package/lib/module/theming/ThemeProvider.js.map +1 -1
- package/lib/module/theming/useTheme.js +1 -1
- package/lib/module/theming/useTheme.js.map +1 -1
- package/lib/module/types.js +41 -0
- package/lib/module/types.js.map +1 -1
- package/lib/module/useChildListeners.js +2 -4
- package/lib/module/useChildListeners.js.map +1 -1
- package/lib/module/useDescriptors.js +5 -9
- package/lib/module/useDescriptors.js.map +1 -1
- package/lib/module/useEventEmitter.js +9 -20
- package/lib/module/useEventEmitter.js.map +1 -1
- package/lib/module/useFocusEvents.js +1 -1
- package/lib/module/useFocusEvents.js.map +1 -1
- package/lib/module/useNavigation.js +31 -8
- package/lib/module/useNavigation.js.map +1 -1
- package/lib/module/useNavigationBuilder.js +10 -12
- package/lib/module/useNavigationBuilder.js.map +1 -1
- package/lib/module/useNavigationCache.js +18 -11
- package/lib/module/useNavigationCache.js.map +1 -1
- package/lib/module/useNavigationHelpers.js +2 -14
- package/lib/module/useNavigationHelpers.js.map +1 -1
- package/lib/module/useNavigationState.js +42 -9
- package/lib/module/useNavigationState.js.map +1 -1
- package/lib/module/useOnAction.js +2 -7
- package/lib/module/useOnAction.js.map +1 -1
- package/lib/module/useOnGetState.js +1 -1
- package/lib/module/useOnGetState.js.map +1 -1
- package/lib/module/useOnPreventRemove.js +1 -1
- package/lib/module/useOnPreventRemove.js.map +1 -1
- package/lib/module/useRoute.js +23 -5
- package/lib/module/useRoute.js.map +1 -1
- package/lib/module/useScheduleUpdate.js +1 -2
- package/lib/module/useScheduleUpdate.js.map +1 -1
- package/lib/module/useSyncState.js +25 -9
- package/lib/module/useSyncState.js.map +1 -1
- package/lib/module/utilities.js +2 -0
- package/lib/module/utilities.js.map +1 -0
- package/lib/typescript/src/BaseNavigationContainer.d.ts.map +1 -1
- package/lib/typescript/src/NavigationIndependentTree.d.ts.map +1 -1
- package/lib/typescript/src/NavigationProvider.d.ts +44 -0
- package/lib/typescript/src/NavigationProvider.d.ts.map +1 -0
- package/lib/typescript/src/SceneView.d.ts +1 -1
- package/lib/typescript/src/SceneView.d.ts.map +1 -1
- package/lib/typescript/src/StaticNavigation.d.ts +231 -80
- package/lib/typescript/src/StaticNavigation.d.ts.map +1 -1
- package/lib/typescript/src/createNavigationContainerRef.d.ts +2 -2
- package/lib/typescript/src/createNavigationContainerRef.d.ts.map +1 -1
- package/lib/typescript/src/getStateFromPath.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +2 -3
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/theming/ThemeContext.d.ts +2 -1
- package/lib/typescript/src/theming/ThemeContext.d.ts.map +1 -1
- package/lib/typescript/src/theming/ThemeProvider.d.ts +2 -1
- 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 +188 -133
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/useChildListeners.d.ts.map +1 -1
- package/lib/typescript/src/useDescriptors.d.ts +27 -109
- package/lib/typescript/src/useDescriptors.d.ts.map +1 -1
- package/lib/typescript/src/useEventEmitter.d.ts.map +1 -1
- package/lib/typescript/src/useNavigation.d.ts +7 -5
- package/lib/typescript/src/useNavigation.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationBuilder.d.ts +25 -114
- package/lib/typescript/src/useNavigationBuilder.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationCache.d.ts +8 -22
- package/lib/typescript/src/useNavigationCache.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationContainerRef.d.ts +2 -2
- package/lib/typescript/src/useNavigationContainerRef.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationHelpers.d.ts +3 -11
- package/lib/typescript/src/useNavigationHelpers.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationState.d.ts +10 -3
- package/lib/typescript/src/useNavigationState.d.ts.map +1 -1
- package/lib/typescript/src/useOnAction.d.ts.map +1 -1
- package/lib/typescript/src/useRoute.d.ts +8 -2
- package/lib/typescript/src/useRoute.d.ts.map +1 -1
- package/lib/typescript/src/useRouteCache.d.ts +12 -3
- package/lib/typescript/src/useRouteCache.d.ts.map +1 -1
- package/lib/typescript/src/useScheduleUpdate.d.ts.map +1 -1
- package/lib/typescript/src/useSyncState.d.ts.map +1 -1
- package/lib/typescript/src/utilities.d.ts +99 -0
- package/lib/typescript/src/utilities.d.ts.map +1 -0
- package/package.json +7 -7
- package/src/BaseNavigationContainer.tsx +3 -9
- package/src/NavigationIndependentTree.tsx +17 -9
- package/src/NavigationProvider.tsx +64 -0
- package/src/PreventRemoveProvider.tsx +1 -1
- package/src/SceneView.tsx +1 -7
- package/src/StaticNavigation.tsx +372 -134
- package/src/createNavigationContainerRef.tsx +2 -1
- package/src/getActionFromState.tsx +4 -2
- package/src/getPathFromState.tsx +6 -5
- package/src/getStateFromPath.tsx +11 -11
- package/src/index.tsx +8 -4
- package/src/theming/ThemeContext.tsx +3 -3
- package/src/theming/ThemeProvider.tsx +2 -1
- package/src/theming/useTheme.tsx +1 -1
- package/src/types.tsx +392 -243
- package/src/useChildListeners.tsx +3 -2
- package/src/useDescriptors.tsx +11 -17
- package/src/useEventEmitter.tsx +14 -31
- package/src/useFocusEvents.tsx +1 -1
- package/src/useNavigation.tsx +57 -14
- package/src/useNavigationBuilder.tsx +10 -13
- package/src/useNavigationCache.tsx +40 -18
- package/src/useNavigationContainerRef.tsx +2 -2
- package/src/useNavigationHelpers.tsx +2 -19
- package/src/useNavigationState.tsx +90 -19
- package/src/useOnAction.tsx +1 -12
- package/src/useOnGetState.tsx +1 -1
- package/src/useOnPreventRemove.tsx +1 -1
- package/src/useRoute.tsx +52 -7
- package/src/useScheduleUpdate.tsx +1 -2
- package/src/useSyncState.tsx +28 -13
- package/src/utilities.tsx +122 -0
- package/lib/module/DeprecatedNavigationInChildContext.js +0 -9
- package/lib/module/DeprecatedNavigationInChildContext.js.map +0 -1
- package/lib/module/NavigationContext.js +0 -8
- package/lib/module/NavigationContext.js.map +0 -1
- package/lib/module/NavigationRouteContext.js +0 -9
- package/lib/module/NavigationRouteContext.js.map +0 -1
- package/lib/module/useClientLayoutEffect.js +0 -9
- package/lib/module/useClientLayoutEffect.js.map +0 -1
- package/lib/typescript/src/DeprecatedNavigationInChildContext.d.ts +0 -6
- package/lib/typescript/src/DeprecatedNavigationInChildContext.d.ts.map +0 -1
- package/lib/typescript/src/NavigationContext.d.ts +0 -8
- package/lib/typescript/src/NavigationContext.d.ts.map +0 -1
- package/lib/typescript/src/NavigationRouteContext.d.ts +0 -7
- package/lib/typescript/src/NavigationRouteContext.d.ts.map +0 -1
- package/lib/typescript/src/useClientLayoutEffect.d.ts +0 -6
- package/lib/typescript/src/useClientLayoutEffect.d.ts.map +0 -1
- package/src/DeprecatedNavigationInChildContext.tsx +0 -6
- package/src/NavigationContext.tsx +0 -11
- package/src/NavigationRouteContext.tsx +0 -9
- package/src/useClientLayoutEffect.tsx +0 -10
package/src/StaticNavigation.tsx
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
NavigationState,
|
|
3
|
+
ParamListBase,
|
|
4
|
+
Route,
|
|
5
|
+
} from '@react-navigation/routers';
|
|
2
6
|
import * as React from 'react';
|
|
3
7
|
import { isValidElementType } from 'react-is';
|
|
4
8
|
|
|
@@ -9,100 +13,313 @@ import type {
|
|
|
9
13
|
NavigatorScreenParams,
|
|
10
14
|
NavigatorTypeBagBase,
|
|
11
15
|
PathConfig,
|
|
12
|
-
|
|
13
|
-
RouteConfigProps,
|
|
16
|
+
PathConfigMap,
|
|
14
17
|
RouteGroupConfig,
|
|
18
|
+
ScreenListeners,
|
|
19
|
+
Theme,
|
|
15
20
|
} from './types';
|
|
16
21
|
import { useRoute } from './useRoute';
|
|
22
|
+
import type {
|
|
23
|
+
AnyToUnknown,
|
|
24
|
+
ExtractParamStrings,
|
|
25
|
+
ExtractParamsType,
|
|
26
|
+
FlatType,
|
|
27
|
+
HasArguments,
|
|
28
|
+
InferParse,
|
|
29
|
+
InferPath,
|
|
30
|
+
KeysOf,
|
|
31
|
+
UnionToIntersection,
|
|
32
|
+
ValidPathPattern,
|
|
33
|
+
} from './utilities';
|
|
34
|
+
|
|
35
|
+
type ParamsForScreenComponent<T> = T extends (...args: any[]) => any
|
|
36
|
+
? HasArguments<T> extends true
|
|
37
|
+
? T extends React.ComponentType<{ route: { params: infer Params } }>
|
|
38
|
+
? Params
|
|
39
|
+
: undefined
|
|
40
|
+
: undefined
|
|
41
|
+
: T extends React.ComponentType<{ route: { params: infer Params } }>
|
|
42
|
+
? Params
|
|
43
|
+
: undefined;
|
|
17
44
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
45
|
+
type ParamsForScreen<T> =
|
|
46
|
+
// Nested navigator in screen property
|
|
47
|
+
T extends { screen: StaticNavigation<any, any, any> }
|
|
48
|
+
? NavigatorScreenParams<StaticParamList<T['screen']>> | undefined
|
|
49
|
+
: // Direct nested navigator
|
|
50
|
+
T extends StaticNavigation<any, any, any>
|
|
51
|
+
? NavigatorScreenParams<StaticParamList<T>> | undefined
|
|
52
|
+
: T extends {
|
|
53
|
+
screen: React.ComponentType<any>;
|
|
54
|
+
}
|
|
55
|
+
? ParamsForScreenComponent<T['screen']>
|
|
56
|
+
: ParamsForScreenComponent<T>;
|
|
57
|
+
|
|
58
|
+
type ParamsForLinking<Linking> = Linking extends { path: string }
|
|
59
|
+
? ExtractParamsType<
|
|
60
|
+
ExtractParamStrings<InferPath<Linking>>,
|
|
61
|
+
InferParse<Linking>
|
|
62
|
+
>
|
|
63
|
+
: Linking extends string
|
|
64
|
+
? ExtractParamsType<ExtractParamStrings<Linking>, undefined>
|
|
65
|
+
: undefined;
|
|
29
66
|
|
|
30
67
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
68
|
+
* Inferred params type based on both linking config and screen.
|
|
69
|
+
* - When linking is undefined: infers params from screen
|
|
70
|
+
* - When screen is a nested navigator: merges path params with navigator screen params
|
|
71
|
+
* - Otherwise: merges path params with screen component params
|
|
33
72
|
*/
|
|
34
|
-
type
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
? P
|
|
48
|
-
: undefined;
|
|
49
|
-
|
|
50
|
-
type ParamsForScreen<T> = T extends { screen: StaticNavigation<any, any, any> }
|
|
51
|
-
? NavigatorScreenParams<StaticParamList<T['screen']>> | undefined
|
|
52
|
-
: T extends StaticNavigation<any, any, any>
|
|
53
|
-
? NavigatorScreenParams<StaticParamList<T>> | undefined
|
|
54
|
-
: UnknownToUndefined<ParamsForScreenComponent<T>>;
|
|
73
|
+
type ParamsForConfig<Linking, Screen> = undefined extends Linking
|
|
74
|
+
? ParamsForScreen<Screen>
|
|
75
|
+
: // Only infer params from linking if it's a pattern (i.e., contains ':')
|
|
76
|
+
// This avoids inferring non-literals like 'string'
|
|
77
|
+
Linking extends ValidPathPattern | { path: ValidPathPattern }
|
|
78
|
+
? Screen extends StaticNavigation<any, any, any>
|
|
79
|
+
? FlatType<ParamsForLinking<Linking>> & ParamsForScreen<Screen>
|
|
80
|
+
: // Don't combine if `undefined`, otherwise it'll result in `never`
|
|
81
|
+
undefined extends ParamsForScreen<Screen>
|
|
82
|
+
? // Only flatten when not a navigator to keep it legible
|
|
83
|
+
FlatType<ParamsForLinking<Linking>>
|
|
84
|
+
: FlatType<ParamsForLinking<Linking> & ParamsForScreen<Screen>>
|
|
85
|
+
: ParamsForScreen<Screen>;
|
|
55
86
|
|
|
56
87
|
type ParamListForScreens<Screens> = {
|
|
57
|
-
[Key in KeysOf<Screens>]:
|
|
88
|
+
[Key in KeysOf<Screens>]: Screens[Key] extends StaticScreenConfig<
|
|
89
|
+
infer Linking,
|
|
90
|
+
infer Screen,
|
|
91
|
+
any,
|
|
92
|
+
any,
|
|
93
|
+
any,
|
|
94
|
+
any
|
|
95
|
+
>
|
|
96
|
+
? ParamsForConfig<Linking, Screen>
|
|
97
|
+
: ParamsForScreen<Screens[Key]>;
|
|
58
98
|
};
|
|
59
99
|
|
|
60
100
|
type ParamListForGroups<
|
|
61
101
|
Groups extends
|
|
62
102
|
| Readonly<{
|
|
63
103
|
[key: string]: {
|
|
64
|
-
screens:
|
|
65
|
-
ParamListBase,
|
|
66
|
-
NavigationState,
|
|
67
|
-
{},
|
|
68
|
-
EventMapBase,
|
|
69
|
-
any
|
|
70
|
-
>;
|
|
104
|
+
screens: {};
|
|
71
105
|
};
|
|
72
106
|
}>
|
|
73
107
|
| undefined,
|
|
74
108
|
> = Groups extends {
|
|
75
109
|
[key: string]: {
|
|
76
|
-
screens:
|
|
77
|
-
ParamListBase,
|
|
78
|
-
NavigationState,
|
|
79
|
-
{},
|
|
80
|
-
EventMapBase,
|
|
81
|
-
any
|
|
82
|
-
>;
|
|
110
|
+
screens: infer Screens;
|
|
83
111
|
};
|
|
84
112
|
}
|
|
85
|
-
? ParamListForScreens<UnionToIntersection<
|
|
113
|
+
? ParamListForScreens<UnionToIntersection<Screens>>
|
|
86
114
|
: {};
|
|
87
115
|
|
|
88
|
-
type
|
|
89
|
-
|
|
90
|
-
|
|
116
|
+
type RouteType<Params> = Readonly<
|
|
117
|
+
FlatType<
|
|
118
|
+
Omit<Route<string, AnyToUnknown<Params>>, 'params'> &
|
|
119
|
+
Readonly<
|
|
120
|
+
undefined extends Params
|
|
121
|
+
? {
|
|
122
|
+
/**
|
|
123
|
+
* Params for this route
|
|
124
|
+
*/
|
|
125
|
+
params?: AnyToUnknown<Params>;
|
|
126
|
+
}
|
|
127
|
+
: {
|
|
128
|
+
/**
|
|
129
|
+
* Params for this route
|
|
130
|
+
*/
|
|
131
|
+
params: AnyToUnknown<Params>;
|
|
132
|
+
}
|
|
133
|
+
>
|
|
134
|
+
>
|
|
135
|
+
>;
|
|
136
|
+
|
|
137
|
+
type StaticScreenConfigLinkingAlias = {
|
|
138
|
+
/**
|
|
139
|
+
* Path string to match against.
|
|
140
|
+
* e.g. `/users/:id` will match `/users/1` and extract `id` param as `1`.
|
|
141
|
+
*/
|
|
142
|
+
path: string;
|
|
143
|
+
/**
|
|
144
|
+
* Whether the path should be consider parent paths or use the exact path.
|
|
145
|
+
* By default, paths are relating to the path config on the parent screen.
|
|
146
|
+
* If `exact` is set to `true`, the parent path configuration is not used.
|
|
147
|
+
*/
|
|
148
|
+
exact?: boolean;
|
|
149
|
+
/**
|
|
150
|
+
* An object mapping the param name to a function which parses the param value.
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* ```js
|
|
154
|
+
* parse: {
|
|
155
|
+
* id: Number,
|
|
156
|
+
* date: (value) => new Date(value)
|
|
157
|
+
* }
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
parse?: Record<string, (value: string) => unknown>;
|
|
161
|
+
/**
|
|
162
|
+
* An object mapping the param name to a function which converts the param value to a string.
|
|
163
|
+
* By default, all params are converted to strings using `String(value)`.
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* ```js
|
|
167
|
+
* stringify: {
|
|
168
|
+
* date: (value) => value.toISOString()
|
|
169
|
+
* }
|
|
170
|
+
* ```
|
|
171
|
+
*/
|
|
172
|
+
stringify?: Record<string, (value: unknown) => string>;
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
export type StaticScreenConfigLinking =
|
|
176
|
+
| string
|
|
177
|
+
| (StaticScreenConfigLinkingAlias & {
|
|
178
|
+
/**
|
|
179
|
+
* Additional path alias that will be matched to the same screen.
|
|
180
|
+
*/
|
|
181
|
+
alias?: (string | StaticScreenConfigLinkingAlias)[];
|
|
182
|
+
})
|
|
183
|
+
| undefined;
|
|
184
|
+
|
|
185
|
+
export type StaticScreenConfigScreen =
|
|
186
|
+
| React.ComponentType<any>
|
|
187
|
+
| StaticNavigation<any, any, any>;
|
|
188
|
+
|
|
189
|
+
export type StaticScreenConfig<
|
|
190
|
+
Linking extends StaticScreenConfigLinking,
|
|
191
|
+
Screen,
|
|
91
192
|
State extends NavigationState,
|
|
92
193
|
ScreenOptions extends {},
|
|
93
194
|
EventMap extends EventMapBase,
|
|
94
195
|
Navigation,
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
196
|
+
Params = ParamsForConfig<Linking, Screen>,
|
|
197
|
+
> = {
|
|
198
|
+
/**
|
|
199
|
+
* Static navigation config or Component to render for the screen.
|
|
200
|
+
*/
|
|
201
|
+
screen: Screen;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Callback to determine whether the screen should be rendered or not.
|
|
205
|
+
* This can be useful for conditional rendering of screens,
|
|
206
|
+
*
|
|
207
|
+
* e.g. - if you want to render a different screen for logged in users.
|
|
208
|
+
*
|
|
209
|
+
* You can use a custom hook to use custom logic to determine the return value.
|
|
210
|
+
*
|
|
211
|
+
* @example
|
|
212
|
+
* ```js
|
|
213
|
+
* if: useIsLoggedIn
|
|
214
|
+
* ```
|
|
215
|
+
*/
|
|
216
|
+
if?: () => boolean;
|
|
104
217
|
|
|
105
|
-
|
|
218
|
+
/**
|
|
219
|
+
* Navigator options for this screen.
|
|
220
|
+
*
|
|
221
|
+
* @example
|
|
222
|
+
* ```js
|
|
223
|
+
* options: {
|
|
224
|
+
* title: 'My Screen',
|
|
225
|
+
* }
|
|
226
|
+
* ```
|
|
227
|
+
*/
|
|
228
|
+
options?:
|
|
229
|
+
| ScreenOptions
|
|
230
|
+
| ((props: {
|
|
231
|
+
route: RouteType<Params>;
|
|
232
|
+
navigation: Navigation;
|
|
233
|
+
theme: Theme;
|
|
234
|
+
}) => ScreenOptions);
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Event listeners for this screen.
|
|
238
|
+
*
|
|
239
|
+
* @example
|
|
240
|
+
* ```js
|
|
241
|
+
* listeners: {
|
|
242
|
+
* blur: (event) => {
|
|
243
|
+
* ...
|
|
244
|
+
* },
|
|
245
|
+
* }
|
|
246
|
+
* ```
|
|
247
|
+
*/
|
|
248
|
+
listeners?:
|
|
249
|
+
| ScreenListeners<State, EventMap>
|
|
250
|
+
| ((props: {
|
|
251
|
+
route: RouteType<Params>;
|
|
252
|
+
navigation: Navigation;
|
|
253
|
+
}) => ScreenListeners<State, EventMap>);
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Layout for this screen.
|
|
257
|
+
*
|
|
258
|
+
* @example
|
|
259
|
+
* ```js
|
|
260
|
+
* layout: ({ children, route, options, navigation, theme }) => {
|
|
261
|
+
* return (
|
|
262
|
+
* <MyWrapper>
|
|
263
|
+
* {children}
|
|
264
|
+
* </MyWrapper>
|
|
265
|
+
* );
|
|
266
|
+
* }
|
|
267
|
+
* ```
|
|
268
|
+
*
|
|
269
|
+
*/
|
|
270
|
+
layout?: (props: {
|
|
271
|
+
route: RouteType<Params>;
|
|
272
|
+
options: ScreenOptions;
|
|
273
|
+
navigation: Navigation;
|
|
274
|
+
theme: Theme;
|
|
275
|
+
children: React.ReactElement;
|
|
276
|
+
}) => React.ReactElement;
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Initial params object for the route.
|
|
280
|
+
*
|
|
281
|
+
* @example
|
|
282
|
+
* ```js
|
|
283
|
+
* initialParams: {
|
|
284
|
+
* someParam: 'someValue'
|
|
285
|
+
* }
|
|
286
|
+
* ```
|
|
287
|
+
*/
|
|
288
|
+
initialParams?: AnyToUnknown<Params extends object ? Partial<Params> : never>;
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Function to return an unique ID for this screen.
|
|
292
|
+
*
|
|
293
|
+
* @example
|
|
294
|
+
* ```js
|
|
295
|
+
* getId: ({ params }) => params?.userId,
|
|
296
|
+
* ```
|
|
297
|
+
*/
|
|
298
|
+
getId?: (props: { params: AnyToUnknown<Params> }) => string | undefined;
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Linking config for the screen.
|
|
302
|
+
* This can be a string to specify the path, or an object with more options.
|
|
303
|
+
*
|
|
304
|
+
* @example
|
|
305
|
+
* ```js
|
|
306
|
+
* linking: {
|
|
307
|
+
* path: 'profile/:userId',
|
|
308
|
+
* parse: {
|
|
309
|
+
* userId: Number,
|
|
310
|
+
* },
|
|
311
|
+
* },
|
|
312
|
+
* ```
|
|
313
|
+
*/
|
|
314
|
+
linking?: Linking;
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Optional key for this screen.
|
|
318
|
+
*/
|
|
319
|
+
navigationKey?: string;
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
type StaticConfigScreens<
|
|
106
323
|
ParamList extends ParamListBase,
|
|
107
324
|
State extends NavigationState,
|
|
108
325
|
ScreenOptions extends {},
|
|
@@ -112,51 +329,23 @@ export type StaticConfigScreens<
|
|
|
112
329
|
[RouteName in keyof ParamList]:
|
|
113
330
|
| React.ComponentType<any>
|
|
114
331
|
| StaticNavigation<any, any, any>
|
|
115
|
-
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
* e.g. - if you want to render a different screen for logged in users.
|
|
130
|
-
*
|
|
131
|
-
* You can use a custom hook to use custom logic to determine the return value.
|
|
132
|
-
*
|
|
133
|
-
* @example
|
|
134
|
-
* ```js
|
|
135
|
-
* if: useIsLoggedIn
|
|
136
|
-
* ```
|
|
137
|
-
*/
|
|
138
|
-
if?: () => boolean;
|
|
139
|
-
/**
|
|
140
|
-
* Linking config for the screen.
|
|
141
|
-
* This can be a string to specify the path, or an object with more options.
|
|
142
|
-
*
|
|
143
|
-
* @example
|
|
144
|
-
* ```js
|
|
145
|
-
* linking: {
|
|
146
|
-
* path: 'profile/:id',
|
|
147
|
-
* exact: true,
|
|
148
|
-
* },
|
|
149
|
-
* ```
|
|
150
|
-
*/
|
|
151
|
-
linking?: PathConfig<ParamList> | string;
|
|
152
|
-
/**
|
|
153
|
-
* Static navigation config or Component to render for the screen.
|
|
154
|
-
*/
|
|
155
|
-
screen: StaticNavigation<any, any, any> | React.ComponentType<any>;
|
|
156
|
-
});
|
|
332
|
+
| StaticScreenConfig<
|
|
333
|
+
| {
|
|
334
|
+
path: string;
|
|
335
|
+
parse?: Record<string, (value: string) => any>;
|
|
336
|
+
}
|
|
337
|
+
| string
|
|
338
|
+
| undefined,
|
|
339
|
+
StaticNavigation<any, any, any> | React.ComponentType<any>,
|
|
340
|
+
State,
|
|
341
|
+
ScreenOptions,
|
|
342
|
+
EventMap,
|
|
343
|
+
NavigationList[RouteName],
|
|
344
|
+
any
|
|
345
|
+
>;
|
|
157
346
|
};
|
|
158
347
|
|
|
159
|
-
|
|
348
|
+
type StaticConfigGroup<
|
|
160
349
|
ParamList extends ParamListBase,
|
|
161
350
|
State extends NavigationState,
|
|
162
351
|
ScreenOptions extends {},
|
|
@@ -171,6 +360,27 @@ export type StaticConfigGroup<
|
|
|
171
360
|
* This can be useful for conditional rendering of group of screens.
|
|
172
361
|
*/
|
|
173
362
|
if?: () => boolean;
|
|
363
|
+
/**
|
|
364
|
+
* Linking config for the screens in the group.
|
|
365
|
+
* This can be a string to specify the path, or an object following properties:
|
|
366
|
+
* - `path`
|
|
367
|
+
* - `stringify`
|
|
368
|
+
* - `parse`
|
|
369
|
+
*
|
|
370
|
+
* The path specified will be prepended to the paths of the screens in the group.
|
|
371
|
+
* The `parse` and `stringify` properties will be merged.
|
|
372
|
+
*
|
|
373
|
+
* @example
|
|
374
|
+
* ```js
|
|
375
|
+
* linking: {
|
|
376
|
+
* path: 'users/:id',
|
|
377
|
+
* parse: {
|
|
378
|
+
* id: (id) => parseInt(id, 10),
|
|
379
|
+
* }
|
|
380
|
+
* },
|
|
381
|
+
* ```
|
|
382
|
+
*/
|
|
383
|
+
linking?: LinkingForGroup;
|
|
174
384
|
/**
|
|
175
385
|
* Static navigation config or Component to render for the screen.
|
|
176
386
|
*/
|
|
@@ -186,7 +396,6 @@ export type StaticConfigGroup<
|
|
|
186
396
|
export type StaticConfig<Bag extends NavigatorTypeBagBase> =
|
|
187
397
|
StaticConfigInternal<
|
|
188
398
|
Bag['ParamList'],
|
|
189
|
-
Bag['NavigatorID'],
|
|
190
399
|
Bag['State'],
|
|
191
400
|
Bag['ScreenOptions'],
|
|
192
401
|
Bag['EventMap'],
|
|
@@ -196,7 +405,6 @@ export type StaticConfig<Bag extends NavigatorTypeBagBase> =
|
|
|
196
405
|
|
|
197
406
|
type StaticConfigInternal<
|
|
198
407
|
ParamList extends ParamListBase,
|
|
199
|
-
NavigatorID extends string | undefined,
|
|
200
408
|
State extends NavigationState,
|
|
201
409
|
ScreenOptions extends {},
|
|
202
410
|
EventMap extends EventMapBase,
|
|
@@ -207,7 +415,6 @@ type StaticConfigInternal<
|
|
|
207
415
|
React.ComponentProps<Navigator>,
|
|
208
416
|
keyof DefaultNavigatorOptions<
|
|
209
417
|
ParamListBase,
|
|
210
|
-
string | undefined,
|
|
211
418
|
NavigationState,
|
|
212
419
|
{},
|
|
213
420
|
EventMapBase,
|
|
@@ -216,7 +423,6 @@ type StaticConfigInternal<
|
|
|
216
423
|
> &
|
|
217
424
|
DefaultNavigatorOptions<
|
|
218
425
|
ParamList,
|
|
219
|
-
NavigatorID,
|
|
220
426
|
State,
|
|
221
427
|
ScreenOptions,
|
|
222
428
|
EventMap,
|
|
@@ -290,14 +496,7 @@ export type StaticScreenProps<T extends Record<string, unknown> | undefined> = {
|
|
|
290
496
|
*/
|
|
291
497
|
export type StaticParamList<
|
|
292
498
|
T extends {
|
|
293
|
-
readonly config:
|
|
294
|
-
readonly screens?: Record<string, any>;
|
|
295
|
-
readonly groups?: {
|
|
296
|
-
[key: string]: {
|
|
297
|
-
screens: Record<string, any>;
|
|
298
|
-
};
|
|
299
|
-
};
|
|
300
|
-
};
|
|
499
|
+
readonly config: any;
|
|
301
500
|
},
|
|
302
501
|
> = FlatType<
|
|
303
502
|
ParamListForScreens<T['config']['screens']> &
|
|
@@ -449,6 +648,10 @@ export function createComponentForStaticNavigation(
|
|
|
449
648
|
return NavigatorComponent;
|
|
450
649
|
}
|
|
451
650
|
|
|
651
|
+
type LinkingForGroup =
|
|
652
|
+
| Pick<PathConfig<any>, 'path' | 'stringify' | 'parse'>
|
|
653
|
+
| string;
|
|
654
|
+
|
|
452
655
|
type TreeForPathConfig = {
|
|
453
656
|
config: {
|
|
454
657
|
initialRouteName?: string;
|
|
@@ -461,6 +664,7 @@ type TreeForPathConfig = {
|
|
|
461
664
|
>;
|
|
462
665
|
groups?: {
|
|
463
666
|
[key: string]: {
|
|
667
|
+
linking?: LinkingForGroup;
|
|
464
668
|
screens: StaticConfigScreens<
|
|
465
669
|
ParamListBase,
|
|
466
670
|
NavigationState,
|
|
@@ -498,9 +702,9 @@ export function createPathConfigForStaticNavigation(
|
|
|
498
702
|
initialRouteName?: string;
|
|
499
703
|
},
|
|
500
704
|
auto?: boolean
|
|
501
|
-
) {
|
|
705
|
+
): PathConfigMap<ParamListBase> | undefined {
|
|
502
706
|
let initialScreenHasPath: boolean = false;
|
|
503
|
-
let initialScreenConfig: PathConfig<
|
|
707
|
+
let initialScreenConfig: PathConfig<{}> | undefined;
|
|
504
708
|
|
|
505
709
|
const createPathConfigForTree = (
|
|
506
710
|
t: TreeForPathConfig,
|
|
@@ -517,6 +721,7 @@ export function createPathConfigForStaticNavigation(
|
|
|
517
721
|
EventMapBase,
|
|
518
722
|
Record<string, unknown>
|
|
519
723
|
>,
|
|
724
|
+
groupLinking: LinkingForGroup | undefined,
|
|
520
725
|
initialRouteName: string | undefined
|
|
521
726
|
) => {
|
|
522
727
|
return Object.fromEntries(
|
|
@@ -535,7 +740,17 @@ export function createPathConfigForStaticNavigation(
|
|
|
535
740
|
return 0;
|
|
536
741
|
})
|
|
537
742
|
.map(([key, item]) => {
|
|
538
|
-
const screenConfig: PathConfig<
|
|
743
|
+
const screenConfig: PathConfig<{}> = {};
|
|
744
|
+
const groupPath =
|
|
745
|
+
typeof groupLinking === 'string'
|
|
746
|
+
? groupLinking
|
|
747
|
+
: groupLinking?.path;
|
|
748
|
+
|
|
749
|
+
const normalizePath = (path: string) => {
|
|
750
|
+
return `${groupPath ?? ''}/${path}`
|
|
751
|
+
.replace(/^\//, '') // Remove extra leading slash
|
|
752
|
+
.replace(/\/$/, ''); // Remove extra trailing slash
|
|
753
|
+
};
|
|
539
754
|
|
|
540
755
|
if ('linking' in item) {
|
|
541
756
|
if (typeof item.linking === 'string') {
|
|
@@ -543,14 +758,28 @@ export function createPathConfigForStaticNavigation(
|
|
|
543
758
|
} else {
|
|
544
759
|
Object.assign(screenConfig, item.linking);
|
|
545
760
|
}
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
if (typeof groupLinking !== 'string') {
|
|
764
|
+
if (groupLinking?.parse != null) {
|
|
765
|
+
screenConfig.parse = {
|
|
766
|
+
...groupLinking.parse,
|
|
767
|
+
...screenConfig.parse,
|
|
768
|
+
};
|
|
769
|
+
}
|
|
546
770
|
|
|
547
|
-
if (
|
|
548
|
-
screenConfig.
|
|
549
|
-
.
|
|
550
|
-
.
|
|
771
|
+
if (groupLinking?.stringify != null) {
|
|
772
|
+
screenConfig.stringify = {
|
|
773
|
+
...groupLinking.stringify,
|
|
774
|
+
...screenConfig.stringify,
|
|
775
|
+
};
|
|
551
776
|
}
|
|
552
777
|
}
|
|
553
778
|
|
|
779
|
+
if (typeof screenConfig.path === 'string') {
|
|
780
|
+
screenConfig.path = normalizePath(screenConfig.path);
|
|
781
|
+
}
|
|
782
|
+
|
|
554
783
|
let screens;
|
|
555
784
|
|
|
556
785
|
const skipInitialDetectionInChild =
|
|
@@ -576,12 +805,13 @@ export function createPathConfigForStaticNavigation(
|
|
|
576
805
|
}
|
|
577
806
|
|
|
578
807
|
if (screens) {
|
|
808
|
+
// @ts-expect-error - we can't type this properly
|
|
579
809
|
screenConfig.screens = screens;
|
|
580
810
|
}
|
|
581
811
|
|
|
582
812
|
if (
|
|
583
813
|
auto &&
|
|
584
|
-
!screenConfig.screens &&
|
|
814
|
+
!('screens' in screenConfig && screenConfig.screens) &&
|
|
585
815
|
// Skip generating path for screens that specify linking config as `undefined` or `null` explicitly
|
|
586
816
|
!('linking' in item && item.linking == null)
|
|
587
817
|
) {
|
|
@@ -596,14 +826,20 @@ export function createPathConfigForStaticNavigation(
|
|
|
596
826
|
}
|
|
597
827
|
}
|
|
598
828
|
} else {
|
|
599
|
-
if (
|
|
829
|
+
if (
|
|
830
|
+
!groupPath &&
|
|
831
|
+
!skipInitialDetection &&
|
|
832
|
+
initialScreenConfig == null
|
|
833
|
+
) {
|
|
600
834
|
initialScreenConfig = screenConfig;
|
|
601
835
|
}
|
|
602
836
|
|
|
603
|
-
screenConfig.path =
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
837
|
+
screenConfig.path = normalizePath(
|
|
838
|
+
key
|
|
839
|
+
.replace(/([A-Z]+)/g, '-$1')
|
|
840
|
+
.replace(/^-/, '')
|
|
841
|
+
.toLowerCase()
|
|
842
|
+
);
|
|
607
843
|
}
|
|
608
844
|
}
|
|
609
845
|
|
|
@@ -623,6 +859,7 @@ export function createPathConfigForStaticNavigation(
|
|
|
623
859
|
screens,
|
|
624
860
|
createPathConfigForScreens(
|
|
625
861
|
t.config.screens,
|
|
862
|
+
undefined,
|
|
626
863
|
o?.initialRouteName ?? t.config.initialRouteName
|
|
627
864
|
)
|
|
628
865
|
);
|
|
@@ -634,6 +871,7 @@ export function createPathConfigForStaticNavigation(
|
|
|
634
871
|
screens,
|
|
635
872
|
createPathConfigForScreens(
|
|
636
873
|
group.screens,
|
|
874
|
+
group.linking,
|
|
637
875
|
o?.initialRouteName ?? t.config.initialRouteName
|
|
638
876
|
)
|
|
639
877
|
);
|
|
@@ -4,13 +4,14 @@ import type {
|
|
|
4
4
|
NavigationContainerEventMap,
|
|
5
5
|
NavigationContainerRef,
|
|
6
6
|
NavigationContainerRefWithCurrent,
|
|
7
|
+
RootParamList,
|
|
7
8
|
} from './types';
|
|
8
9
|
|
|
9
10
|
export const NOT_INITIALIZED_ERROR =
|
|
10
11
|
"The 'navigation' object hasn't been initialized yet. This might happen if you don't have a navigator mounted, or if the navigator hasn't finished mounting. See https://reactnavigation.org/docs/navigating-without-navigation-prop#handling-initialization for more details.";
|
|
11
12
|
|
|
12
13
|
export function createNavigationContainerRef<
|
|
13
|
-
ParamList extends {} =
|
|
14
|
+
ParamList extends {} = RootParamList,
|
|
14
15
|
>(): NavigationContainerRefWithCurrent<ParamList> {
|
|
15
16
|
const methods = [
|
|
16
17
|
...Object.keys(CommonActions),
|