@react-navigation/core 8.0.0-alpha.25 → 8.0.0-alpha.27
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 +12 -6
- package/lib/module/BaseNavigationContainer.js.map +1 -1
- package/lib/module/ConsumedParamsContext.js.map +1 -1
- package/lib/module/DataLoading.js +29 -4
- package/lib/module/DataLoading.js.map +1 -1
- package/lib/module/NavigationIndependentTree.js +8 -4
- package/lib/module/NavigationIndependentTree.js.map +1 -1
- package/lib/module/SceneView.js +16 -39
- package/lib/module/SceneView.js.map +1 -1
- package/lib/module/StaticNavigation.js +4 -3
- package/lib/module/StaticNavigation.js.map +1 -1
- package/lib/module/findFocusedRoute.js +1 -1
- package/lib/module/findFocusedRoute.js.map +1 -1
- package/lib/module/getActionFromState.js +1 -2
- package/lib/module/getActionFromState.js.map +1 -1
- package/lib/module/getPathFromState.js +41 -26
- package/lib/module/getPathFromState.js.map +1 -1
- package/lib/module/getPatternParts.js +15 -2
- package/lib/module/getPatternParts.js.map +1 -1
- package/lib/module/getStateFromPath.js +45 -19
- package/lib/module/getStateFromPath.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/types.js.map +1 -1
- package/lib/module/useFocusEvents.js +6 -2
- package/lib/module/useFocusEvents.js.map +1 -1
- package/lib/module/useLazyValue.js.map +1 -1
- package/lib/module/useNavigationBuilder.js +8 -6
- package/lib/module/useNavigationBuilder.js.map +1 -1
- package/lib/module/useOnAction.js +6 -16
- package/lib/module/useOnAction.js.map +1 -1
- package/lib/module/useOnPreventRemove.js +1 -3
- package/lib/module/useOnPreventRemove.js.map +1 -1
- package/lib/module/useRouteCache.js +1 -3
- package/lib/module/useRouteCache.js.map +1 -1
- package/lib/module/useSyncState.js +3 -2
- package/lib/module/useSyncState.js.map +1 -1
- package/lib/typescript/src/BaseNavigationContainer.d.ts.map +1 -1
- package/lib/typescript/src/ConsumedParamsContext.d.ts +1 -6
- package/lib/typescript/src/ConsumedParamsContext.d.ts.map +1 -1
- package/lib/typescript/src/DataLoading.d.ts +1 -0
- package/lib/typescript/src/DataLoading.d.ts.map +1 -1
- package/lib/typescript/src/NavigationIndependentTree.d.ts.map +1 -1
- package/lib/typescript/src/SceneView.d.ts.map +1 -1
- package/lib/typescript/src/StaticNavigation.d.ts +39 -30
- package/lib/typescript/src/StaticNavigation.d.ts.map +1 -1
- package/lib/typescript/src/getPathFromState.d.ts.map +1 -1
- package/lib/typescript/src/getPatternParts.d.ts.map +1 -1
- package/lib/typescript/src/getStateFromPath.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +2 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +10 -7
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/useFocusEvents.d.ts.map +1 -1
- package/lib/typescript/src/useLazyValue.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationBuilder.d.ts.map +1 -1
- package/lib/typescript/src/useOnAction.d.ts.map +1 -1
- package/lib/typescript/src/useOnPreventRemove.d.ts.map +1 -1
- package/lib/typescript/src/useRouteCache.d.ts.map +1 -1
- package/lib/typescript/src/useSyncState.d.ts.map +1 -1
- package/lib/typescript/src/utilities.d.ts +10 -0
- package/lib/typescript/src/utilities.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/BaseNavigationContainer.tsx +13 -7
- package/src/ConsumedParamsContext.tsx +1 -6
- package/src/DataLoading.tsx +68 -4
- package/src/NavigationIndependentTree.tsx +8 -5
- package/src/SceneView.tsx +18 -52
- package/src/StaticNavigation.tsx +88 -64
- package/src/findFocusedRoute.tsx +1 -1
- package/src/getActionFromState.tsx +7 -3
- package/src/getPathFromState.tsx +59 -32
- package/src/getPatternParts.tsx +15 -2
- package/src/getStateFromPath.tsx +77 -17
- package/src/index.tsx +5 -0
- package/src/types.tsx +14 -7
- package/src/useDescriptors.tsx +1 -1
- package/src/useFocusEvents.tsx +7 -5
- package/src/useLazyValue.tsx +2 -2
- package/src/useNavigationBuilder.tsx +12 -7
- package/src/useOnAction.tsx +11 -40
- package/src/useOnPreventRemove.tsx +4 -3
- package/src/useRouteCache.tsx +1 -4
- package/src/useSyncState.tsx +3 -2
- package/src/utilities.tsx +19 -0
package/src/DataLoading.tsx
CHANGED
|
@@ -71,12 +71,33 @@ export function getLoaderForState(
|
|
|
71
71
|
tree: TreeForPathConfig,
|
|
72
72
|
state: PartialState<NavigationState> | NavigationState | undefined
|
|
73
73
|
): (() => Promise<void>) | undefined {
|
|
74
|
-
|
|
74
|
+
return getLoaderForStateChange(tree, state, undefined, undefined);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function getLoaderForStateChange(
|
|
78
|
+
tree: TreeForPathConfig,
|
|
79
|
+
state: PartialState<NavigationState> | NavigationState | undefined,
|
|
80
|
+
previousState: PartialState<NavigationState> | NavigationState | undefined,
|
|
81
|
+
consumedParams: WeakMap<object, true> | undefined
|
|
82
|
+
): (() => Promise<void>) | undefined {
|
|
83
|
+
const focusedRoute = state?.routes[state.index ?? state.routes.length - 1];
|
|
84
|
+
const previousFocusedRoute =
|
|
85
|
+
previousState?.routes[
|
|
86
|
+
previousState.index ?? previousState.routes.length - 1
|
|
87
|
+
];
|
|
75
88
|
|
|
76
89
|
if (!focusedRoute) {
|
|
77
90
|
return undefined;
|
|
78
91
|
}
|
|
79
92
|
|
|
93
|
+
const isNewlyFocused =
|
|
94
|
+
previousState === undefined ||
|
|
95
|
+
previousFocusedRoute == null ||
|
|
96
|
+
focusedRoute.name !== previousFocusedRoute.name ||
|
|
97
|
+
(focusedRoute.key != null &&
|
|
98
|
+
previousFocusedRoute.key != null &&
|
|
99
|
+
focusedRoute.key !== previousFocusedRoute.key);
|
|
100
|
+
|
|
80
101
|
const item = findScreenInConfig(tree.config, focusedRoute.name);
|
|
81
102
|
|
|
82
103
|
if (item == null) {
|
|
@@ -95,7 +116,11 @@ export function getLoaderForState(
|
|
|
95
116
|
|
|
96
117
|
const loaders: (() => Promise<void>)[] = [];
|
|
97
118
|
|
|
98
|
-
if (
|
|
119
|
+
if (
|
|
120
|
+
isNewlyFocused &&
|
|
121
|
+
'UNSTABLE_loader' in item &&
|
|
122
|
+
typeof item.UNSTABLE_loader === 'function'
|
|
123
|
+
) {
|
|
99
124
|
const loader = item.UNSTABLE_loader;
|
|
100
125
|
|
|
101
126
|
loaders.push(() =>
|
|
@@ -116,13 +141,52 @@ export function getLoaderForState(
|
|
|
116
141
|
if (nested) {
|
|
117
142
|
const initialRouteName = findInitialRouteName(nested.config);
|
|
118
143
|
|
|
119
|
-
|
|
144
|
+
const stateFromParams =
|
|
145
|
+
focusedRoute.params != null && consumedParams?.has(focusedRoute.params)
|
|
146
|
+
? undefined
|
|
147
|
+
: getStateFromRouteParams(params);
|
|
148
|
+
|
|
149
|
+
let childState =
|
|
150
|
+
previousState !== undefined && stateFromParams != null
|
|
151
|
+
? stateFromParams
|
|
152
|
+
: (focusedRoute.state ?? stateFromParams);
|
|
120
153
|
|
|
121
154
|
if (childState == null && initialRouteName != null) {
|
|
122
155
|
childState = { routes: [{ name: initialRouteName }] };
|
|
123
156
|
}
|
|
124
157
|
|
|
125
|
-
|
|
158
|
+
let previousChildState:
|
|
159
|
+
| PartialState<NavigationState>
|
|
160
|
+
| NavigationState
|
|
161
|
+
| undefined;
|
|
162
|
+
|
|
163
|
+
if (!isNewlyFocused) {
|
|
164
|
+
const previousRouteParams = previousFocusedRoute?.params;
|
|
165
|
+
const previousParams =
|
|
166
|
+
initialParams != null || previousRouteParams != null
|
|
167
|
+
? { ...initialParams, ...previousRouteParams }
|
|
168
|
+
: undefined;
|
|
169
|
+
const previousStateFromParams =
|
|
170
|
+
previousRouteParams != null && consumedParams?.has(previousRouteParams)
|
|
171
|
+
? undefined
|
|
172
|
+
: getStateFromRouteParams(previousParams);
|
|
173
|
+
|
|
174
|
+
previousChildState =
|
|
175
|
+
previousFocusedRoute?.state ?? previousStateFromParams;
|
|
176
|
+
|
|
177
|
+
if (previousChildState == null && initialRouteName != null) {
|
|
178
|
+
previousChildState = { routes: [{ name: initialRouteName }] };
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const childLoader = getLoaderForStateChange(
|
|
183
|
+
nested,
|
|
184
|
+
childState,
|
|
185
|
+
previousState === undefined
|
|
186
|
+
? undefined
|
|
187
|
+
: (previousChildState ?? { routes: [] }),
|
|
188
|
+
consumedParams
|
|
189
|
+
);
|
|
126
190
|
|
|
127
191
|
if (childLoader) {
|
|
128
192
|
loaders.push(childLoader);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
|
|
3
|
+
import { NavigationFocusedRouteStateContext } from './NavigationFocusedRouteStateContext';
|
|
3
4
|
import { NavigationIndependentTreeContext } from './NavigationIndependentTreeContext';
|
|
4
5
|
import {
|
|
5
6
|
NamedRouteContextListContext,
|
|
@@ -23,11 +24,13 @@ export function NavigationIndependentTree({
|
|
|
23
24
|
<NamedRouteContextListContext.Provider value={undefined}>
|
|
24
25
|
<NavigationRouteContext.Provider value={undefined}>
|
|
25
26
|
<NavigationContext.Provider value={undefined}>
|
|
26
|
-
<
|
|
27
|
-
<
|
|
28
|
-
{
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
<NavigationFocusedRouteStateContext.Provider value={undefined}>
|
|
28
|
+
<IsFocusedContext.Provider value={undefined}>
|
|
29
|
+
<NavigationIndependentTreeContext.Provider value={true}>
|
|
30
|
+
{children}
|
|
31
|
+
</NavigationIndependentTreeContext.Provider>
|
|
32
|
+
</IsFocusedContext.Provider>
|
|
33
|
+
</NavigationFocusedRouteStateContext.Provider>
|
|
31
34
|
</NavigationContext.Provider>
|
|
32
35
|
</NavigationRouteContext.Provider>
|
|
33
36
|
</NamedRouteContextListContext.Provider>
|
package/src/SceneView.tsx
CHANGED
|
@@ -6,7 +6,6 @@ import type {
|
|
|
6
6
|
} from '@react-navigation/routers';
|
|
7
7
|
import * as React from 'react';
|
|
8
8
|
|
|
9
|
-
import { ConsumedParamsContext } from './ConsumedParamsContext';
|
|
10
9
|
import { EnsureSingleNavigator } from './EnsureSingleNavigator';
|
|
11
10
|
import { isArrayEqual } from './isArrayEqual';
|
|
12
11
|
import {
|
|
@@ -105,37 +104,6 @@ export function SceneView<
|
|
|
105
104
|
|
|
106
105
|
const getIsInitial = React.useCallback(() => isInitialRef.current, []);
|
|
107
106
|
|
|
108
|
-
const [consumedParams, setConsumedParams] = React.useState<WeakMap<
|
|
109
|
-
object,
|
|
110
|
-
true
|
|
111
|
-
> | null>(null);
|
|
112
|
-
|
|
113
|
-
const consumedParamsContext = React.useMemo(
|
|
114
|
-
() => ({
|
|
115
|
-
isConsumed: (params: object) => {
|
|
116
|
-
if (consumedParams) {
|
|
117
|
-
return consumedParams.has(params);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
return false;
|
|
121
|
-
},
|
|
122
|
-
setConsumed: (params: object) => {
|
|
123
|
-
setConsumedParams((prev) => {
|
|
124
|
-
if (prev && prev.has(params)) {
|
|
125
|
-
return prev;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const map = new WeakMap<object, true>();
|
|
129
|
-
|
|
130
|
-
map.set(params, true);
|
|
131
|
-
|
|
132
|
-
return map;
|
|
133
|
-
});
|
|
134
|
-
},
|
|
135
|
-
}),
|
|
136
|
-
[consumedParams]
|
|
137
|
-
);
|
|
138
|
-
|
|
139
107
|
const parentFocusedRouteState = React.use(NavigationFocusedRouteStateContext);
|
|
140
108
|
|
|
141
109
|
const focusedRouteState = React.useMemo(() => {
|
|
@@ -205,25 +173,23 @@ export function SceneView<
|
|
|
205
173
|
: screen.component;
|
|
206
174
|
|
|
207
175
|
return (
|
|
208
|
-
<
|
|
209
|
-
<
|
|
210
|
-
<
|
|
211
|
-
<
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
</NavigationStateContext.Provider>
|
|
227
|
-
</ConsumedParamsContext.Provider>
|
|
176
|
+
<NavigationStateContext.Provider value={context}>
|
|
177
|
+
<NavigationFocusedRouteStateContext.Provider value={focusedRouteState}>
|
|
178
|
+
<EnsureSingleNavigator>
|
|
179
|
+
<StaticContainer
|
|
180
|
+
name={screen.name}
|
|
181
|
+
render={ScreenComponent || screen.children}
|
|
182
|
+
navigation={navigation}
|
|
183
|
+
route={route}
|
|
184
|
+
>
|
|
185
|
+
{ScreenComponent !== undefined ? (
|
|
186
|
+
<ScreenComponent navigation={navigation} route={route} />
|
|
187
|
+
) : screen.children !== undefined ? (
|
|
188
|
+
screen.children({ navigation, route })
|
|
189
|
+
) : null}
|
|
190
|
+
</StaticContainer>
|
|
191
|
+
</EnsureSingleNavigator>
|
|
192
|
+
</NavigationFocusedRouteStateContext.Provider>
|
|
193
|
+
</NavigationStateContext.Provider>
|
|
228
194
|
);
|
|
229
195
|
}
|
package/src/StaticNavigation.tsx
CHANGED
|
@@ -32,7 +32,9 @@ import type {
|
|
|
32
32
|
HasArguments,
|
|
33
33
|
InferParamsFromLinking,
|
|
34
34
|
KeysOf,
|
|
35
|
+
NoExcessCallbackReturn,
|
|
35
36
|
NoExcessObject,
|
|
37
|
+
NoExcessValue,
|
|
36
38
|
NotUndefinedObject,
|
|
37
39
|
StandardSchemaV1,
|
|
38
40
|
UnionToIntersection,
|
|
@@ -53,19 +55,23 @@ type ParamsForScreenComponent<T> = [T] extends [(...args: any[]) => any]
|
|
|
53
55
|
: undefined
|
|
54
56
|
: ScreenComponentParams<T>;
|
|
55
57
|
|
|
56
|
-
// If
|
|
57
|
-
//
|
|
58
|
+
// If the initial route's params include `undefined`, the nested navigator itself can be optional.
|
|
59
|
+
// If no initial route is specified, check if every nested route's params include `undefined`.
|
|
60
|
+
// Otherwise the nested navigator needs to be required.
|
|
58
61
|
type ParamsForNestedNavigator<
|
|
59
62
|
T extends { config: any },
|
|
60
63
|
ParamList extends {} = StaticParamList<T>,
|
|
61
64
|
Params = NavigatorScreenParams<ParamList>,
|
|
65
|
+
RouteNames extends keyof ParamList = T['config'] extends {
|
|
66
|
+
initialRouteName: infer RouteName extends keyof ParamList;
|
|
67
|
+
}
|
|
68
|
+
? RouteName
|
|
69
|
+
: keyof ParamList,
|
|
62
70
|
> = {
|
|
63
|
-
|
|
64
|
-
// If every route has optional params, the resulting union is `never`
|
|
65
|
-
[RouteName in keyof ParamList]-?: undefined extends ParamList[RouteName]
|
|
71
|
+
[RouteName in RouteNames]-?: undefined extends ParamList[RouteName]
|
|
66
72
|
? never
|
|
67
73
|
: RouteName;
|
|
68
|
-
}[
|
|
74
|
+
}[RouteNames] extends never
|
|
69
75
|
? Params | undefined
|
|
70
76
|
: Params;
|
|
71
77
|
|
|
@@ -132,6 +138,8 @@ type ParamListForScreens<Screens> = {
|
|
|
132
138
|
any,
|
|
133
139
|
any,
|
|
134
140
|
any,
|
|
141
|
+
any,
|
|
142
|
+
any,
|
|
135
143
|
any
|
|
136
144
|
>
|
|
137
145
|
? ParamsForConfig<Linking, Screen>
|
|
@@ -146,22 +154,22 @@ type ParamListForGroups<Groups> = Groups extends {
|
|
|
146
154
|
? ParamListForScreens<UnionToIntersection<Screens>>
|
|
147
155
|
: {};
|
|
148
156
|
|
|
149
|
-
type
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
157
|
+
type StaticRouteBase = Readonly<Omit<Route<string>, 'params'>>;
|
|
158
|
+
|
|
159
|
+
type StaticRoute<Params, P = AnyToUnknown<Params>> = StaticRouteBase &
|
|
160
|
+
(undefined extends Params
|
|
161
|
+
? {
|
|
162
|
+
/**
|
|
163
|
+
* Params for this route
|
|
164
|
+
*/
|
|
165
|
+
readonly params?: P extends object ? Readonly<P> : P;
|
|
166
|
+
}
|
|
167
|
+
: {
|
|
168
|
+
/**
|
|
169
|
+
* Params for this route
|
|
170
|
+
*/
|
|
171
|
+
readonly params: Readonly<P>;
|
|
172
|
+
});
|
|
165
173
|
|
|
166
174
|
type StaticScreenConfigLinkingAlias = {
|
|
167
175
|
/**
|
|
@@ -193,7 +201,7 @@ type StaticScreenConfigLinkingAlias = {
|
|
|
193
201
|
>;
|
|
194
202
|
/**
|
|
195
203
|
* An object mapping the param name to a function which converts the param value to a string.
|
|
196
|
-
* By default,
|
|
204
|
+
* By default, arrays and null are preserved for query params, and other values are converted using `String(value)`.
|
|
197
205
|
*
|
|
198
206
|
* @example
|
|
199
207
|
* ```js
|
|
@@ -246,15 +254,17 @@ export type StaticScreenConfigScreen =
|
|
|
246
254
|
| React.ComponentType<any>
|
|
247
255
|
| StaticNavigation<any>;
|
|
248
256
|
|
|
249
|
-
export
|
|
250
|
-
Linking extends StaticScreenConfigLinking,
|
|
251
|
-
Screen,
|
|
252
|
-
State extends NavigationState,
|
|
253
|
-
ScreenOptions extends {},
|
|
254
|
-
EventMap extends EventMapBase,
|
|
255
|
-
Navigation,
|
|
256
|
-
Params = ParamsForConfig<Linking, Screen>,
|
|
257
|
-
|
|
257
|
+
export interface StaticScreenConfig<
|
|
258
|
+
out Linking extends StaticScreenConfigLinking,
|
|
259
|
+
out Screen,
|
|
260
|
+
in out State extends NavigationState,
|
|
261
|
+
in out ScreenOptions extends {},
|
|
262
|
+
in out EventMap extends EventMapBase,
|
|
263
|
+
in out Navigation,
|
|
264
|
+
in out Params = ParamsForConfig<Linking, Screen>,
|
|
265
|
+
in out ProvidedOptions extends {} = {},
|
|
266
|
+
in out ProvidedListeners extends {} = {},
|
|
267
|
+
> {
|
|
258
268
|
/**
|
|
259
269
|
* Static navigation config or Component to render for the screen.
|
|
260
270
|
*/
|
|
@@ -291,7 +301,7 @@ export type StaticScreenConfig<
|
|
|
291
301
|
route: StaticRoute<Params>;
|
|
292
302
|
navigation: Navigation;
|
|
293
303
|
theme: Theme;
|
|
294
|
-
}) => ScreenOptions);
|
|
304
|
+
}) => NoExcessCallbackReturn<ProvidedOptions, ScreenOptions>);
|
|
295
305
|
|
|
296
306
|
/**
|
|
297
307
|
* Event listeners for this screen.
|
|
@@ -310,7 +320,10 @@ export type StaticScreenConfig<
|
|
|
310
320
|
| ((props: {
|
|
311
321
|
route: StaticRoute<Params>;
|
|
312
322
|
navigation: Navigation;
|
|
313
|
-
}) =>
|
|
323
|
+
}) => NoExcessCallbackReturn<
|
|
324
|
+
ProvidedListeners,
|
|
325
|
+
ScreenListeners<State, EventMap>
|
|
326
|
+
>);
|
|
314
327
|
|
|
315
328
|
/**
|
|
316
329
|
* Layout for this screen.
|
|
@@ -392,14 +405,13 @@ export type StaticScreenConfig<
|
|
|
392
405
|
name: string;
|
|
393
406
|
params: AnyToUnknown<Params>;
|
|
394
407
|
}) => Promise<void>;
|
|
395
|
-
}
|
|
408
|
+
}
|
|
396
409
|
|
|
397
410
|
export type StaticScreenFactory<in out Bag extends NavigatorTypeBagBase> = <
|
|
398
411
|
const Linking extends StaticScreenConfigLinking,
|
|
399
412
|
const Screen extends StaticScreenConfigScreen,
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
| ((...args: never[]) => unknown) = Bag['ScreenOptions'],
|
|
413
|
+
ProvidedOptions extends {} = {},
|
|
414
|
+
ProvidedListeners extends {} = {},
|
|
403
415
|
>(
|
|
404
416
|
config: StaticScreenConfig<
|
|
405
417
|
Linking,
|
|
@@ -407,11 +419,11 @@ export type StaticScreenFactory<in out Bag extends NavigatorTypeBagBase> = <
|
|
|
407
419
|
Bag['State'],
|
|
408
420
|
Bag['ScreenOptions'],
|
|
409
421
|
Bag['EventMap'],
|
|
410
|
-
Bag['NavigationList'][keyof Bag['ParamList']]
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
422
|
+
Bag['NavigationList'][keyof Bag['ParamList']],
|
|
423
|
+
ParamsForConfig<Linking, Screen>,
|
|
424
|
+
ProvidedOptions,
|
|
425
|
+
ProvidedListeners
|
|
426
|
+
>
|
|
415
427
|
) => StaticScreenConfig<
|
|
416
428
|
Linking,
|
|
417
429
|
Screen,
|
|
@@ -446,7 +458,9 @@ type StaticConfigScreens<
|
|
|
446
458
|
ScreenOptions,
|
|
447
459
|
EventMap,
|
|
448
460
|
NavigationList[RouteName],
|
|
449
|
-
any
|
|
461
|
+
any,
|
|
462
|
+
{},
|
|
463
|
+
{}
|
|
450
464
|
>;
|
|
451
465
|
};
|
|
452
466
|
|
|
@@ -529,23 +543,26 @@ export type StaticConfig<
|
|
|
529
543
|
}
|
|
530
544
|
);
|
|
531
545
|
|
|
532
|
-
type
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
screen: unknown;
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
? { options: NoExcessOptions<Screen['options'], ScreenOptions> }
|
|
543
|
-
: unknown;
|
|
546
|
+
type NoExcessScreen<
|
|
547
|
+
Screen,
|
|
548
|
+
ScreenOptions extends {},
|
|
549
|
+
Listeners extends {},
|
|
550
|
+
> = (Screen extends { screen: unknown; options: unknown }
|
|
551
|
+
? { options: NoExcessValue<Screen['options'], ScreenOptions> }
|
|
552
|
+
: unknown) &
|
|
553
|
+
(Screen extends { screen: unknown; listeners: unknown }
|
|
554
|
+
? { listeners: NoExcessValue<Screen['listeners'], Listeners> }
|
|
555
|
+
: unknown);
|
|
544
556
|
|
|
545
|
-
type NoExcessScreens<
|
|
557
|
+
type NoExcessScreens<
|
|
558
|
+
Screens,
|
|
559
|
+
ScreenOptions extends {},
|
|
560
|
+
Listeners extends {},
|
|
561
|
+
> = {
|
|
546
562
|
[RouteName in keyof Screens]: NoExcessScreen<
|
|
547
563
|
Screens[RouteName],
|
|
548
|
-
ScreenOptions
|
|
564
|
+
ScreenOptions,
|
|
565
|
+
Listeners
|
|
549
566
|
>;
|
|
550
567
|
};
|
|
551
568
|
|
|
@@ -553,6 +570,7 @@ type NoExcessGroups<
|
|
|
553
570
|
Groups,
|
|
554
571
|
Bag extends NavigatorTypeBagBase,
|
|
555
572
|
ScreenOptions extends {},
|
|
573
|
+
Listeners extends {},
|
|
556
574
|
> = {
|
|
557
575
|
[GroupName in keyof Groups]: NoExcessObject<
|
|
558
576
|
Groups[GroupName],
|
|
@@ -564,7 +582,7 @@ type NoExcessGroups<
|
|
|
564
582
|
NavigationListBase<ParamListBase>
|
|
565
583
|
>
|
|
566
584
|
> &
|
|
567
|
-
NoExcessStaticConfig<Groups[GroupName], Bag, ScreenOptions>;
|
|
585
|
+
NoExcessStaticConfig<Groups[GroupName], Bag, ScreenOptions, Listeners>;
|
|
568
586
|
};
|
|
569
587
|
|
|
570
588
|
// Each property is probed with `Config extends { key: infer X }` and the results are intersected.
|
|
@@ -574,19 +592,25 @@ export type NoExcessStaticConfig<
|
|
|
574
592
|
Config,
|
|
575
593
|
Bag extends NavigatorTypeBagBase,
|
|
576
594
|
ScreenOptions extends {} = Bag['ScreenOptions'],
|
|
595
|
+
Listeners extends {} = ScreenListeners<Bag['State'], Bag['EventMap']>,
|
|
577
596
|
> = (Config extends { screenOptions: infer ProvidedOptions }
|
|
578
597
|
? {
|
|
579
|
-
screenOptions:
|
|
598
|
+
screenOptions: NoExcessValue<ProvidedOptions, ScreenOptions>;
|
|
580
599
|
}
|
|
581
600
|
: unknown) &
|
|
601
|
+
(Config extends { screenListeners: infer ProvidedListeners }
|
|
602
|
+
? {
|
|
603
|
+
screenListeners: NoExcessValue<ProvidedListeners, Listeners>;
|
|
604
|
+
}
|
|
605
|
+
: unknown) &
|
|
582
606
|
(Config extends { screens: infer Screens }
|
|
583
607
|
? {
|
|
584
|
-
screens: NoExcessScreens<Screens, ScreenOptions>;
|
|
608
|
+
screens: NoExcessScreens<Screens, ScreenOptions, Listeners>;
|
|
585
609
|
}
|
|
586
610
|
: unknown) &
|
|
587
611
|
(Config extends { groups: infer Groups }
|
|
588
612
|
? {
|
|
589
|
-
groups: NoExcessGroups<Groups, Bag, ScreenOptions>;
|
|
613
|
+
groups: NoExcessGroups<Groups, Bag, ScreenOptions, Listeners>;
|
|
590
614
|
}
|
|
591
615
|
: unknown);
|
|
592
616
|
|
|
@@ -1138,8 +1162,8 @@ export function createPathConfigForStaticNavigation<ParamList extends {}>(
|
|
|
1138
1162
|
|
|
1139
1163
|
screenConfig.path = normalizePath(
|
|
1140
1164
|
key
|
|
1141
|
-
.replace(/([A-Z]
|
|
1142
|
-
.replace(
|
|
1165
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
1166
|
+
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1-$2')
|
|
1143
1167
|
.toLowerCase()
|
|
1144
1168
|
);
|
|
1145
1169
|
}
|
package/src/findFocusedRoute.tsx
CHANGED
|
@@ -14,7 +14,7 @@ export function findFocusedRoute(state: InitialState): Result {
|
|
|
14
14
|
|
|
15
15
|
while (current != null) {
|
|
16
16
|
const route: InitialState['routes'][number] | undefined =
|
|
17
|
-
current.routes[current.index ??
|
|
17
|
+
current.routes[current.index ?? current.routes.length - 1];
|
|
18
18
|
|
|
19
19
|
if (route?.state == null) {
|
|
20
20
|
return route;
|
|
@@ -195,11 +195,16 @@ export function getActionFromState(
|
|
|
195
195
|
};
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
-
const createNormalizedConfigItem = (
|
|
198
|
+
const createNormalizedConfigItem = (
|
|
199
|
+
config: PathConfig<object> | string
|
|
200
|
+
): ConfigItem =>
|
|
199
201
|
typeof config === 'object' && config != null
|
|
200
202
|
? {
|
|
201
203
|
initialRouteName:
|
|
202
|
-
'initialRouteName' in config
|
|
204
|
+
'initialRouteName' in config &&
|
|
205
|
+
typeof config.initialRouteName === 'string'
|
|
206
|
+
? config.initialRouteName
|
|
207
|
+
: undefined,
|
|
203
208
|
screens:
|
|
204
209
|
'screens' in config && config.screens != null
|
|
205
210
|
? createNormalizedConfigs(config.screens)
|
|
@@ -209,7 +214,6 @@ const createNormalizedConfigItem = (config: PathConfig<object> | string) =>
|
|
|
209
214
|
|
|
210
215
|
const createNormalizedConfigs = (options: PathConfigMap<object>) =>
|
|
211
216
|
Object.entries(options).reduce<Record<string, ConfigItem>>((acc, [k, v]) => {
|
|
212
|
-
// @ts-expect-error -we can't properly type this
|
|
213
217
|
acc[k] = createNormalizedConfigItem(v);
|
|
214
218
|
return acc;
|
|
215
219
|
}, {});
|