@react-navigation/core 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/BaseNavigationContainer.js +20 -9
- package/lib/module/BaseNavigationContainer.js.map +1 -1
- package/lib/module/ConsumedParamsContext.js +5 -0
- package/lib/module/ConsumedParamsContext.js.map +1 -0
- package/lib/module/NavigationBuilderContext.js +1 -0
- package/lib/module/NavigationBuilderContext.js.map +1 -1
- package/lib/module/NavigationIndependentTree.js +8 -4
- package/lib/module/NavigationIndependentTree.js.map +1 -1
- package/lib/module/NavigationProvider.js +14 -3
- package/lib/module/NavigationProvider.js.map +1 -1
- package/lib/module/NavigationStateContext.js.map +1 -1
- package/lib/module/PreventRemoveProvider.js +3 -3
- package/lib/module/PreventRemoveProvider.js.map +1 -1
- package/lib/module/SceneView.js +46 -56
- package/lib/module/SceneView.js.map +1 -1
- package/lib/module/StaticNavigation.js +166 -46
- package/lib/module/StaticNavigation.js.map +1 -1
- package/lib/module/checkSerializable.js +11 -4
- package/lib/module/checkSerializable.js.map +1 -1
- package/lib/module/createNavigatorFactory.js +27 -5
- package/lib/module/createNavigatorFactory.js.map +1 -1
- package/lib/module/findFocusedRoute.js +7 -4
- package/lib/module/findFocusedRoute.js.map +1 -1
- package/lib/module/getActionFromState.js +40 -14
- package/lib/module/getActionFromState.js.map +1 -1
- package/lib/module/getPathFromState.js +48 -11
- 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 +353 -166
- package/lib/module/getStateFromPath.js.map +1 -1
- package/lib/module/getStateFromRouteParams.js +24 -0
- package/lib/module/getStateFromRouteParams.js.map +1 -0
- package/lib/module/index.js +3 -4
- package/lib/module/index.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 +15 -0
- package/lib/module/types.js.map +1 -1
- package/lib/module/useDescriptors.js +18 -9
- package/lib/module/useDescriptors.js.map +1 -1
- package/lib/module/useEventEmitter.js +43 -31
- package/lib/module/useEventEmitter.js.map +1 -1
- package/lib/module/useFocusEvents.js +6 -2
- package/lib/module/useFocusEvents.js.map +1 -1
- package/lib/module/useFocusedListenersChildrenAdapter.js +2 -2
- package/lib/module/useFocusedListenersChildrenAdapter.js.map +1 -1
- package/lib/module/useIsFocused.js +7 -12
- package/lib/module/useIsFocused.js.map +1 -1
- package/lib/module/useNavigation.js.map +1 -1
- package/lib/module/useNavigationBuilder.js +144 -86
- package/lib/module/useNavigationBuilder.js.map +1 -1
- package/lib/module/useNavigationCache.js +3 -3
- package/lib/module/useNavigationCache.js.map +1 -1
- package/lib/module/useNavigationHelpers.js +1 -1
- package/lib/module/useNavigationHelpers.js.map +1 -1
- package/lib/module/useNavigationIndependentTree.js +1 -1
- package/lib/module/useNavigationIndependentTree.js.map +1 -1
- package/lib/module/useNavigationState.js +6 -4
- package/lib/module/useNavigationState.js.map +1 -1
- package/lib/module/useOnAction.js +3 -3
- package/lib/module/useOnAction.js.map +1 -1
- package/lib/module/useOnGetState.js +6 -3
- package/lib/module/useOnGetState.js.map +1 -1
- package/lib/module/useOnPreventRemove.js +3 -3
- package/lib/module/useOnPreventRemove.js.map +1 -1
- package/lib/module/useOnRouteFocus.js +1 -1
- package/lib/module/useOnRouteFocus.js.map +1 -1
- package/lib/module/useOptionsGetters.js +7 -4
- package/lib/module/useOptionsGetters.js.map +1 -1
- package/lib/module/usePreventRemove.js +1 -1
- package/lib/module/usePreventRemove.js.map +1 -1
- package/lib/module/usePreventRemoveContext.js +1 -1
- package/lib/module/usePreventRemoveContext.js.map +1 -1
- package/lib/module/useRegisterNavigator.js +2 -2
- package/lib/module/useRegisterNavigator.js.map +1 -1
- package/lib/module/useRoute.js.map +1 -1
- package/lib/module/useRouteCache.js +2 -1
- package/lib/module/useRouteCache.js.map +1 -1
- package/lib/module/useScheduleUpdate.js +1 -1
- package/lib/module/useScheduleUpdate.js.map +1 -1
- package/lib/module/useStateForPath.js +1 -1
- package/lib/module/useStateForPath.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 +6 -3
- package/lib/typescript/src/BaseNavigationContainer.d.ts.map +1 -1
- package/lib/typescript/src/ConsumedParamsContext.d.ts +8 -0
- package/lib/typescript/src/ConsumedParamsContext.d.ts.map +1 -0
- 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 +12 -6
- 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/NavigationFocusedRouteStateContext.d.ts +4 -4
- package/lib/typescript/src/NavigationFocusedRouteStateContext.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 +10 -10
- package/lib/typescript/src/NavigationProvider.d.ts.map +1 -1
- package/lib/typescript/src/NavigationStateContext.d.ts +3 -3
- package/lib/typescript/src/NavigationStateContext.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/StaticContainer.d.ts +1 -1
- package/lib/typescript/src/StaticContainer.d.ts.map +1 -1
- package/lib/typescript/src/StaticNavigation.d.ts +123 -92
- package/lib/typescript/src/StaticNavigation.d.ts.map +1 -1
- package/lib/typescript/src/checkSerializable.d.ts +5 -3
- package/lib/typescript/src/checkSerializable.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 +17 -5
- package/lib/typescript/src/createNavigatorFactory.d.ts.map +1 -1
- package/lib/typescript/src/findFocusedRoute.d.ts +3 -3
- package/lib/typescript/src/findFocusedRoute.d.ts.map +1 -1
- package/lib/typescript/src/getActionFromState.d.ts +4 -4
- package/lib/typescript/src/getActionFromState.d.ts.map +1 -1
- package/lib/typescript/src/getPathFromState.d.ts +3 -3
- 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 +5 -5
- package/lib/typescript/src/getStateFromPath.d.ts.map +1 -1
- package/lib/typescript/src/getStateFromRouteParams.d.ts +3 -0
- package/lib/typescript/src/getStateFromRouteParams.d.ts.map +1 -0
- 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 +215 -131
- 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 +7 -7
- 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/useIsFocused.d.ts +3 -0
- package/lib/typescript/src/useIsFocused.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 +4 -2
- package/lib/typescript/src/useNavigation.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationBuilder.d.ts +24 -24
- 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 +19 -19
- 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 +9 -9
- 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/useOnRouteFocus.d.ts +6 -6
- package/lib/typescript/src/useOnRouteFocus.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 +4 -4
- package/lib/typescript/src/useRouteCache.d.ts.map +1 -1
- package/lib/typescript/src/useScheduleUpdate.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 +45 -5
- package/lib/typescript/src/utilities.d.ts.map +1 -1
- package/lib/typescript/src/validatePathConfig.d.ts.map +1 -1
- package/package.json +23 -20
- package/src/BaseNavigationContainer.tsx +337 -326
- package/src/ConsumedParamsContext.tsx +10 -0
- package/src/NavigationBuilderContext.tsx +14 -8
- package/src/NavigationFocusedRouteStateContext.tsx +4 -4
- package/src/NavigationIndependentTree.tsx +8 -5
- package/src/NavigationProvider.tsx +17 -3
- package/src/NavigationStateContext.tsx +5 -6
- package/src/PreventRemoveProvider.tsx +3 -3
- package/src/SceneView.tsx +58 -56
- package/src/StaticNavigation.tsx +488 -250
- package/src/checkSerializable.tsx +22 -12
- package/src/createNavigatorFactory.tsx +83 -8
- package/src/findFocusedRoute.tsx +13 -8
- package/src/getActionFromState.tsx +68 -39
- package/src/getPathFromState.tsx +91 -27
- package/src/getPatternParts.tsx +8 -0
- package/src/getStateFromPath.tsx +555 -180
- package/src/getStateFromRouteParams.tsx +60 -0
- package/src/index.tsx +47 -5
- package/src/theming/useTheme.tsx +1 -1
- package/src/types.tsx +541 -338
- package/src/useDescriptors.tsx +27 -12
- package/src/useEventEmitter.tsx +45 -36
- package/src/useFocusEvents.tsx +8 -2
- package/src/useFocusedListenersChildrenAdapter.tsx +2 -2
- package/src/useIsFocused.tsx +14 -21
- package/src/useNavigation.tsx +5 -3
- package/src/useNavigationBuilder.tsx +220 -132
- package/src/useNavigationCache.tsx +6 -6
- package/src/useNavigationHelpers.tsx +1 -1
- package/src/useNavigationIndependentTree.tsx +1 -1
- package/src/useNavigationState.tsx +11 -7
- package/src/useOnAction.tsx +10 -10
- package/src/useOnGetState.tsx +5 -3
- package/src/useOnPreventRemove.tsx +3 -3
- package/src/useOnRouteFocus.tsx +10 -12
- package/src/useOptionsGetters.tsx +7 -4
- package/src/usePreventRemove.tsx +1 -1
- package/src/usePreventRemoveContext.tsx +1 -1
- package/src/useRegisterNavigator.tsx +2 -2
- package/src/useRoute.tsx +4 -2
- package/src/useRouteCache.tsx +2 -1
- package/src/useScheduleUpdate.tsx +1 -3
- package/src/useStateForPath.tsx +1 -1
- package/src/utilities.tsx +101 -5
- package/src/validatePathConfig.tsx +1 -0
- package/lib/module/CurrentRenderContext.js +0 -10
- package/lib/module/CurrentRenderContext.js.map +0 -1
- package/lib/module/useCurrentRender.js +0 -19
- package/lib/module/useCurrentRender.js.map +0 -1
- package/lib/typescript/src/CurrentRenderContext.d.ts +0 -9
- package/lib/typescript/src/CurrentRenderContext.d.ts.map +0 -1
- package/lib/typescript/src/useCurrentRender.d.ts +0 -14
- package/lib/typescript/src/useCurrentRender.d.ts.map +0 -1
- package/src/CurrentRenderContext.tsx +0 -9
- package/src/useCurrentRender.tsx +0 -31
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
o: { [key: string]: any },
|
|
3
|
-
seen: Set<any>,
|
|
4
|
-
location: (string | number)[]
|
|
5
|
-
):
|
|
1
|
+
type Result =
|
|
6
2
|
| { serializable: true }
|
|
7
3
|
| {
|
|
8
4
|
serializable: false;
|
|
9
5
|
location: (string | number)[];
|
|
10
6
|
reason: string;
|
|
11
|
-
}
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const checkSerializableWithoutCircularReference = (
|
|
10
|
+
o: { [key: string]: any },
|
|
11
|
+
seen: Set<any>,
|
|
12
|
+
location: (string | number)[]
|
|
13
|
+
): Result => {
|
|
12
14
|
if (
|
|
13
15
|
o === undefined ||
|
|
14
16
|
o === null ||
|
|
@@ -25,7 +27,7 @@ const checkSerializableWithoutCircularReference = (
|
|
|
25
27
|
) {
|
|
26
28
|
return {
|
|
27
29
|
serializable: false,
|
|
28
|
-
location,
|
|
30
|
+
location: location.slice(),
|
|
29
31
|
reason: typeof o === 'function' ? 'Function' : String(o),
|
|
30
32
|
};
|
|
31
33
|
}
|
|
@@ -34,7 +36,7 @@ const checkSerializableWithoutCircularReference = (
|
|
|
34
36
|
return {
|
|
35
37
|
serializable: false,
|
|
36
38
|
reason: 'Circular reference',
|
|
37
|
-
location,
|
|
39
|
+
location: location.slice(),
|
|
38
40
|
};
|
|
39
41
|
}
|
|
40
42
|
|
|
@@ -42,30 +44,38 @@ const checkSerializableWithoutCircularReference = (
|
|
|
42
44
|
|
|
43
45
|
if (Array.isArray(o)) {
|
|
44
46
|
for (let i = 0; i < o.length; i++) {
|
|
47
|
+
location.push(i);
|
|
45
48
|
const childResult = checkSerializableWithoutCircularReference(
|
|
46
49
|
o[i],
|
|
47
|
-
|
|
48
|
-
|
|
50
|
+
seen,
|
|
51
|
+
location
|
|
49
52
|
);
|
|
53
|
+
location.pop();
|
|
50
54
|
|
|
51
55
|
if (!childResult.serializable) {
|
|
56
|
+
seen.delete(o);
|
|
52
57
|
return childResult;
|
|
53
58
|
}
|
|
54
59
|
}
|
|
55
60
|
} else {
|
|
56
61
|
for (const key in o) {
|
|
62
|
+
location.push(key);
|
|
57
63
|
const childResult = checkSerializableWithoutCircularReference(
|
|
58
64
|
o[key],
|
|
59
|
-
|
|
60
|
-
|
|
65
|
+
seen,
|
|
66
|
+
location
|
|
61
67
|
);
|
|
68
|
+
location.pop();
|
|
62
69
|
|
|
63
70
|
if (!childResult.serializable) {
|
|
71
|
+
seen.delete(o);
|
|
64
72
|
return childResult;
|
|
65
73
|
}
|
|
66
74
|
}
|
|
67
75
|
}
|
|
68
76
|
|
|
77
|
+
seen.delete(o);
|
|
78
|
+
|
|
69
79
|
return { serializable: true };
|
|
70
80
|
};
|
|
71
81
|
|
|
@@ -1,23 +1,98 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import type { ParamListBase } from '@react-navigation/routers';
|
|
2
|
+
import * as React from 'react';
|
|
2
3
|
|
|
3
4
|
import { Group } from './Group';
|
|
4
5
|
import { Screen } from './Screen';
|
|
6
|
+
import {
|
|
7
|
+
createComponentForStaticConfig,
|
|
8
|
+
type StaticConfig,
|
|
9
|
+
type StaticParamList,
|
|
10
|
+
} from './StaticNavigation';
|
|
11
|
+
import type {
|
|
12
|
+
NavigatorTypeBagBase,
|
|
13
|
+
NavigatorTypeBagFor,
|
|
14
|
+
TypedNavigator,
|
|
15
|
+
} from './types';
|
|
16
|
+
import type { KeysOf } from './utilities';
|
|
17
|
+
|
|
18
|
+
export type TypedNavigatorFactory<in out TypeBag extends NavigatorTypeBagBase> =
|
|
19
|
+
{
|
|
20
|
+
<const ParamList extends ParamListBase>(): TypedNavigator<
|
|
21
|
+
NavigatorTypeBagFor<TypeBag, ParamList>,
|
|
22
|
+
undefined
|
|
23
|
+
>;
|
|
24
|
+
<
|
|
25
|
+
const Config extends StaticConfig<
|
|
26
|
+
NavigatorTypeBagFor<TypeBag, ParamListBase>
|
|
27
|
+
> &
|
|
28
|
+
// TS only checks for excess properties for non-generic object literal types.
|
|
29
|
+
// Since `Config` is generic, extra keys satisfy the constraint and slip through.
|
|
30
|
+
// So we force any key in `Config` that isn't a known key to have the type `never`,
|
|
31
|
+
// Thus causing an error for any extra key.
|
|
32
|
+
Record<
|
|
33
|
+
Exclude<
|
|
34
|
+
keyof Config,
|
|
35
|
+
KeysOf<StaticConfig<NavigatorTypeBagFor<TypeBag, ParamListBase>>>
|
|
36
|
+
>,
|
|
37
|
+
never
|
|
38
|
+
>,
|
|
39
|
+
>(
|
|
40
|
+
config: Config
|
|
41
|
+
): TypedNavigator<
|
|
42
|
+
NavigatorTypeBagFor<TypeBag, StaticParamList<{ config: Config }>>,
|
|
43
|
+
Config
|
|
44
|
+
>;
|
|
45
|
+
};
|
|
5
46
|
|
|
6
47
|
/**
|
|
7
|
-
* Higher order
|
|
8
|
-
*
|
|
48
|
+
* Higher order function to create a navigator factory
|
|
49
|
+
* A navigator factory creates a navigator:
|
|
50
|
+
* - `Navigator` and `Screen` pairs for dynamic configuration
|
|
51
|
+
* - Static navigator object for static configuration
|
|
9
52
|
*
|
|
10
53
|
* @param Navigator The navigator component to wrap.
|
|
11
|
-
* @returns Factory method to create a
|
|
54
|
+
* @returns Factory method to create a navigator
|
|
12
55
|
*/
|
|
13
|
-
export function createNavigatorFactory
|
|
56
|
+
export function createNavigatorFactory<TypeBag extends NavigatorTypeBagBase>(
|
|
57
|
+
Navigator: React.ComponentType<any>
|
|
58
|
+
): TypedNavigatorFactory<TypeBag> {
|
|
59
|
+
const displayName = Navigator.displayName ?? Navigator.name ?? 'Navigator';
|
|
60
|
+
|
|
14
61
|
function createNavigator(config?: any): any {
|
|
15
62
|
if (config != null) {
|
|
63
|
+
const NavigatorComponent = createComponentForStaticConfig(
|
|
64
|
+
{
|
|
65
|
+
Navigator,
|
|
66
|
+
Screen,
|
|
67
|
+
Group,
|
|
68
|
+
config,
|
|
69
|
+
},
|
|
70
|
+
displayName
|
|
71
|
+
);
|
|
72
|
+
|
|
16
73
|
return {
|
|
17
|
-
Navigator,
|
|
18
|
-
Screen,
|
|
19
|
-
Group,
|
|
20
74
|
config,
|
|
75
|
+
with(
|
|
76
|
+
DecoratorComponent: React.ComponentType<{
|
|
77
|
+
Navigator: React.ComponentType<any>;
|
|
78
|
+
}>
|
|
79
|
+
) {
|
|
80
|
+
const WithComponent = () => {
|
|
81
|
+
return React.createElement(DecoratorComponent, {
|
|
82
|
+
Navigator: NavigatorComponent,
|
|
83
|
+
});
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
WithComponent.displayName = `${displayName}With`;
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
config,
|
|
90
|
+
getComponent: () => WithComponent,
|
|
91
|
+
};
|
|
92
|
+
},
|
|
93
|
+
getComponent() {
|
|
94
|
+
return NavigatorComponent;
|
|
95
|
+
},
|
|
21
96
|
};
|
|
22
97
|
}
|
|
23
98
|
|
package/src/findFocusedRoute.tsx
CHANGED
|
@@ -2,21 +2,26 @@ import type { InitialState } from '@react-navigation/routers';
|
|
|
2
2
|
|
|
3
3
|
type Result =
|
|
4
4
|
| {
|
|
5
|
-
key?: string;
|
|
5
|
+
key?: string | undefined;
|
|
6
6
|
name: string;
|
|
7
|
-
params?: object;
|
|
8
|
-
path?: string;
|
|
7
|
+
params?: object | undefined;
|
|
8
|
+
path?: string | undefined;
|
|
9
9
|
}
|
|
10
10
|
| undefined;
|
|
11
11
|
|
|
12
12
|
export function findFocusedRoute(state: InitialState): Result {
|
|
13
13
|
let current: InitialState | undefined = state;
|
|
14
14
|
|
|
15
|
-
while (current
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
while (current != null) {
|
|
16
|
+
const route: InitialState['routes'][number] | undefined =
|
|
17
|
+
current.routes[current.index ?? 0];
|
|
18
|
+
|
|
19
|
+
if (route?.state == null) {
|
|
20
|
+
return route;
|
|
21
|
+
}
|
|
18
22
|
|
|
19
|
-
|
|
23
|
+
current = route.state;
|
|
24
|
+
}
|
|
20
25
|
|
|
21
|
-
return
|
|
26
|
+
return undefined;
|
|
22
27
|
}
|
|
@@ -2,20 +2,18 @@ import type {
|
|
|
2
2
|
CommonActions,
|
|
3
3
|
NavigationState,
|
|
4
4
|
ParamListBase,
|
|
5
|
-
PartialRoute,
|
|
6
5
|
PartialState,
|
|
7
|
-
Route,
|
|
8
6
|
} from '@react-navigation/routers';
|
|
9
7
|
|
|
10
8
|
import type { NavigatorScreenParams, PathConfig, PathConfigMap } from './types';
|
|
11
9
|
|
|
12
10
|
type ConfigItem = {
|
|
13
|
-
initialRouteName?: string;
|
|
14
|
-
screens?: Record<string, ConfigItem
|
|
11
|
+
initialRouteName?: string | undefined;
|
|
12
|
+
screens?: Record<string, ConfigItem> | undefined;
|
|
15
13
|
};
|
|
16
14
|
|
|
17
15
|
type Options = {
|
|
18
|
-
initialRouteName?: string;
|
|
16
|
+
initialRouteName?: string | undefined;
|
|
19
17
|
screens: PathConfigMap<object>;
|
|
20
18
|
};
|
|
21
19
|
|
|
@@ -23,19 +21,35 @@ type NavigateAction<State extends NavigationState> = {
|
|
|
23
21
|
type: 'NAVIGATE';
|
|
24
22
|
payload: {
|
|
25
23
|
name: string;
|
|
26
|
-
params?: NavigatorScreenParams<State
|
|
27
|
-
path?: string;
|
|
24
|
+
params?: NavigatorScreenParams<State> | undefined;
|
|
25
|
+
path?: string | undefined;
|
|
28
26
|
};
|
|
29
27
|
};
|
|
30
28
|
|
|
29
|
+
// Cache the normalized config across calls for the same `options` reference,
|
|
30
|
+
// so we don't re-walk the config tree on every action conversion.
|
|
31
|
+
const cachedNormalizedConfig = new WeakMap<Options, ConfigItem>();
|
|
32
|
+
|
|
31
33
|
export function getActionFromState(
|
|
32
34
|
state: PartialState<NavigationState>,
|
|
33
35
|
options?: Options
|
|
34
36
|
): NavigateAction<NavigationState> | CommonActions.Action | undefined {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
let normalizedConfig;
|
|
38
|
+
|
|
39
|
+
if (options) {
|
|
40
|
+
const cached = cachedNormalizedConfig.get(options);
|
|
41
|
+
|
|
42
|
+
if (cached) {
|
|
43
|
+
normalizedConfig = cached;
|
|
44
|
+
} else {
|
|
45
|
+
normalizedConfig = createNormalizedConfigItem(
|
|
46
|
+
options as PathConfig<object> | string
|
|
47
|
+
);
|
|
48
|
+
cachedNormalizedConfig.set(options, normalizedConfig as ConfigItem);
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
normalizedConfig = {};
|
|
52
|
+
}
|
|
39
53
|
|
|
40
54
|
const routes =
|
|
41
55
|
state.index != null ? state.routes.slice(0, state.index + 1) : state.routes;
|
|
@@ -44,13 +58,21 @@ export function getActionFromState(
|
|
|
44
58
|
return undefined;
|
|
45
59
|
}
|
|
46
60
|
|
|
61
|
+
const firstRoute = routes[0];
|
|
62
|
+
|
|
63
|
+
if (firstRoute == null) {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const secondRoute = routes[1];
|
|
68
|
+
|
|
47
69
|
if (
|
|
48
70
|
!(
|
|
49
|
-
(routes.length === 1 &&
|
|
71
|
+
(routes.length === 1 && firstRoute.key == null) ||
|
|
50
72
|
(routes.length === 2 &&
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
73
|
+
firstRoute.key == null &&
|
|
74
|
+
firstRoute.name === normalizedConfig?.initialRouteName &&
|
|
75
|
+
secondRoute?.key == null)
|
|
54
76
|
)
|
|
55
77
|
) {
|
|
56
78
|
return {
|
|
@@ -61,20 +83,20 @@ export function getActionFromState(
|
|
|
61
83
|
|
|
62
84
|
const route = state.routes[state.index ?? state.routes.length - 1];
|
|
63
85
|
|
|
64
|
-
|
|
65
|
-
|
|
86
|
+
if (route == null) {
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
let current: PartialState<NavigationState> | undefined = route.state;
|
|
91
|
+
let config: ConfigItem | undefined = normalizedConfig?.screens?.[route.name];
|
|
66
92
|
let params = { ...route.params } as NavigatorScreenParams<ParamListBase>;
|
|
67
93
|
|
|
68
|
-
const payload:
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
| undefined = route
|
|
76
|
-
? { name: route.name, path: route.path, params }
|
|
77
|
-
: undefined;
|
|
94
|
+
const payload: {
|
|
95
|
+
name: string;
|
|
96
|
+
params: NavigatorScreenParams<ParamListBase>;
|
|
97
|
+
path?: string | undefined;
|
|
98
|
+
pop?: boolean | undefined;
|
|
99
|
+
} = { name: route.name, path: route.path, params };
|
|
78
100
|
|
|
79
101
|
// If the screen contains a navigator, pop other screens to navigate to it
|
|
80
102
|
// This avoid pushing multiple instances of navigators onto a stack
|
|
@@ -90,7 +112,7 @@ export function getActionFromState(
|
|
|
90
112
|
// There are 2 ways we can detect if a screen contains a navigator:
|
|
91
113
|
// - The route contains nested state in `route.state`
|
|
92
114
|
// - Nested screens are defined in the config
|
|
93
|
-
if (
|
|
115
|
+
if (config?.screens && Object.keys(config.screens).length) {
|
|
94
116
|
payload.pop = true;
|
|
95
117
|
}
|
|
96
118
|
|
|
@@ -104,8 +126,19 @@ export function getActionFromState(
|
|
|
104
126
|
? current.routes.slice(0, current.index + 1)
|
|
105
127
|
: current.routes;
|
|
106
128
|
|
|
107
|
-
const route
|
|
108
|
-
|
|
129
|
+
const route = routes[routes.length - 1];
|
|
130
|
+
|
|
131
|
+
if (route == null) {
|
|
132
|
+
return undefined;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const firstRoute = routes[0];
|
|
136
|
+
|
|
137
|
+
if (firstRoute == null) {
|
|
138
|
+
return undefined;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const secondRoute = routes[1];
|
|
109
142
|
|
|
110
143
|
// Explicitly set to override existing value when merging params
|
|
111
144
|
Object.assign(params, {
|
|
@@ -115,14 +148,14 @@ export function getActionFromState(
|
|
|
115
148
|
state: undefined,
|
|
116
149
|
});
|
|
117
150
|
|
|
118
|
-
if (routes.length === 1 &&
|
|
151
|
+
if (routes.length === 1 && firstRoute.key == null) {
|
|
119
152
|
params.initial = true;
|
|
120
153
|
params.screen = route.name;
|
|
121
154
|
} else if (
|
|
122
155
|
routes.length === 2 &&
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
156
|
+
firstRoute.key == null &&
|
|
157
|
+
firstRoute.name === config?.initialRouteName &&
|
|
158
|
+
secondRoute?.key == null
|
|
126
159
|
) {
|
|
127
160
|
params.initial = false;
|
|
128
161
|
params.screen = route.name;
|
|
@@ -148,14 +181,10 @@ export function getActionFromState(
|
|
|
148
181
|
}
|
|
149
182
|
}
|
|
150
183
|
|
|
151
|
-
if (payload
|
|
184
|
+
if (payload.params.screen || payload.params.state) {
|
|
152
185
|
payload.pop = true;
|
|
153
186
|
}
|
|
154
187
|
|
|
155
|
-
if (!payload) {
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
188
|
// Try to construct payload for a `NAVIGATE` action from the state
|
|
160
189
|
// This lets us preserve the navigation state and not lose it
|
|
161
190
|
return {
|
package/src/getPathFromState.tsx
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
PartialState,
|
|
4
|
-
Route,
|
|
5
|
-
} from '@react-navigation/routers';
|
|
6
|
-
import * as queryString from 'query-string';
|
|
1
|
+
import type { NavigationState, PartialState } from '@react-navigation/routers';
|
|
2
|
+
import queryString from 'query-string';
|
|
7
3
|
|
|
8
4
|
import { getPatternParts, type PatternPart } from './getPatternParts';
|
|
5
|
+
import { getStateFromRouteParams } from './getStateFromRouteParams';
|
|
9
6
|
import type { PathConfig, PathConfigMap } from './types';
|
|
10
7
|
import { validatePathConfig } from './validatePathConfig';
|
|
11
8
|
|
|
12
9
|
type Options<ParamList extends {}> = {
|
|
13
|
-
path?: string;
|
|
14
|
-
initialRouteName?: string;
|
|
10
|
+
path?: string | undefined;
|
|
11
|
+
initialRouteName?: string | undefined;
|
|
15
12
|
screens: PathConfigMap<ParamList>;
|
|
16
13
|
};
|
|
17
14
|
|
|
@@ -20,17 +17,23 @@ type State = NavigationState | Omit<PartialState<NavigationState>, 'stale'>;
|
|
|
20
17
|
type StringifyConfig = Record<string, ((value: unknown) => string) | undefined>;
|
|
21
18
|
|
|
22
19
|
type ConfigItem = {
|
|
23
|
-
parts?: PatternPart[];
|
|
24
|
-
stringify?: StringifyConfig;
|
|
25
|
-
screens?: Record<string, ConfigItem
|
|
20
|
+
parts?: PatternPart[] | undefined;
|
|
21
|
+
stringify?: StringifyConfig | undefined;
|
|
22
|
+
screens?: Record<string, ConfigItem> | undefined;
|
|
26
23
|
};
|
|
27
24
|
|
|
28
|
-
const getActiveRoute = (
|
|
25
|
+
const getActiveRoute = (
|
|
26
|
+
state: State
|
|
27
|
+
): { name: string; params?: object | undefined } => {
|
|
29
28
|
const route =
|
|
30
29
|
typeof state.index === 'number'
|
|
31
30
|
? state.routes[state.index]
|
|
32
31
|
: state.routes[state.routes.length - 1];
|
|
33
32
|
|
|
33
|
+
if (route == null) {
|
|
34
|
+
throw new Error(`Couldn't find the active route.`);
|
|
35
|
+
}
|
|
36
|
+
|
|
34
37
|
if (route.state) {
|
|
35
38
|
return getActiveRoute(route.state);
|
|
36
39
|
}
|
|
@@ -57,6 +60,48 @@ const getNormalizedConfigs = (options?: Options<{}>) => {
|
|
|
57
60
|
return normalizedConfigs;
|
|
58
61
|
};
|
|
59
62
|
|
|
63
|
+
const getTransformedState = (
|
|
64
|
+
state: State,
|
|
65
|
+
configs: Record<string, ConfigItem> | undefined
|
|
66
|
+
): Omit<PartialState<NavigationState>, 'stale'> => {
|
|
67
|
+
const routes = state.routes.map(
|
|
68
|
+
(route): Omit<PartialState<NavigationState>, 'stale'>['routes'][number] => {
|
|
69
|
+
const config = configs?.[route.name];
|
|
70
|
+
|
|
71
|
+
if (
|
|
72
|
+
route.state ||
|
|
73
|
+
(config?.screens &&
|
|
74
|
+
route.params &&
|
|
75
|
+
(('screen' in route.params &&
|
|
76
|
+
typeof route.params.screen === 'string' &&
|
|
77
|
+
config.screens[route.params.screen]) ||
|
|
78
|
+
'state' in route.params))
|
|
79
|
+
) {
|
|
80
|
+
const nestedState: State | undefined =
|
|
81
|
+
route.state ?? getStateFromRouteParams(route.params);
|
|
82
|
+
|
|
83
|
+
if (nestedState) {
|
|
84
|
+
return {
|
|
85
|
+
...route,
|
|
86
|
+
state: getTransformedState(
|
|
87
|
+
nestedState,
|
|
88
|
+
configs?.[route.name]?.screens
|
|
89
|
+
),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// @ts-expect-error route.state is handled in previous condition
|
|
95
|
+
return route;
|
|
96
|
+
}
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
...state,
|
|
101
|
+
routes,
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
|
|
60
105
|
/**
|
|
61
106
|
* Utility to serialize a navigation state object to a path string.
|
|
62
107
|
*
|
|
@@ -101,37 +146,50 @@ export function getPathFromState<ParamList extends {}>(
|
|
|
101
146
|
}
|
|
102
147
|
|
|
103
148
|
const configs = getNormalizedConfigs(options);
|
|
149
|
+
const transformedState = getTransformedState(state, configs);
|
|
104
150
|
|
|
105
151
|
let path = '/';
|
|
106
|
-
let current: State | undefined =
|
|
152
|
+
let current: State | undefined = transformedState;
|
|
107
153
|
|
|
108
154
|
const allParams: Record<string, string> = {};
|
|
109
155
|
|
|
110
156
|
while (current) {
|
|
111
|
-
let index = typeof current.index === 'number' ? current.index : 0;
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
157
|
+
let index: number = typeof current.index === 'number' ? current.index : 0;
|
|
158
|
+
|
|
159
|
+
const initialRoute: State['routes'][number] | undefined =
|
|
160
|
+
current.routes[index];
|
|
161
|
+
|
|
162
|
+
if (initialRoute == null) {
|
|
163
|
+
throw new Error(`Couldn't find a route at index ${index}.`);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
let route: State['routes'][number] = initialRoute;
|
|
115
167
|
|
|
116
168
|
let parts: PatternPart[] | undefined;
|
|
117
169
|
|
|
118
170
|
let focusedParams: Record<string, string> | undefined;
|
|
119
171
|
let currentOptions = configs;
|
|
120
172
|
|
|
121
|
-
const focusedRoute = getActiveRoute(
|
|
173
|
+
const focusedRoute = getActiveRoute(transformedState);
|
|
122
174
|
|
|
123
175
|
// Keep all the route names that appeared during going deeper in config in case the pattern is resolved to undefined
|
|
124
176
|
const nestedRouteNames = [];
|
|
125
177
|
|
|
126
178
|
let hasNext = true;
|
|
127
179
|
|
|
128
|
-
while (
|
|
129
|
-
|
|
180
|
+
while (hasNext) {
|
|
181
|
+
const config = currentOptions[route.name];
|
|
182
|
+
|
|
183
|
+
if (config == null) {
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
parts = config.parts;
|
|
130
188
|
|
|
131
189
|
nestedRouteNames.push(route.name);
|
|
132
190
|
|
|
133
191
|
if (route.params) {
|
|
134
|
-
const options =
|
|
192
|
+
const options = config;
|
|
135
193
|
|
|
136
194
|
const currentParams = Object.fromEntries(
|
|
137
195
|
Object.entries(route.params)
|
|
@@ -181,7 +239,7 @@ export function getPathFromState<ParamList extends {}>(
|
|
|
181
239
|
}
|
|
182
240
|
|
|
183
241
|
// If there is no `screens` property or no nested state, we return pattern
|
|
184
|
-
if (!
|
|
242
|
+
if (!config.screens || route.state == null) {
|
|
185
243
|
hasNext = false;
|
|
186
244
|
} else {
|
|
187
245
|
index =
|
|
@@ -189,12 +247,18 @@ export function getPathFromState<ParamList extends {}>(
|
|
|
189
247
|
? route.state.index
|
|
190
248
|
: route.state.routes.length - 1;
|
|
191
249
|
|
|
192
|
-
const nextRoute
|
|
193
|
-
|
|
250
|
+
const nextRoute: State['routes'][number] | undefined =
|
|
251
|
+
route.state.routes[index];
|
|
252
|
+
|
|
253
|
+
if (nextRoute == null) {
|
|
254
|
+
throw new Error(`Couldn't find a route at index ${index}.`);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const nestedConfig = config.screens;
|
|
194
258
|
|
|
195
259
|
// if there is config for next route name, we go deeper
|
|
196
|
-
if (
|
|
197
|
-
route = nextRoute
|
|
260
|
+
if (nextRoute.name in nestedConfig) {
|
|
261
|
+
route = nextRoute;
|
|
198
262
|
currentOptions = nestedConfig;
|
|
199
263
|
} else {
|
|
200
264
|
// If not, there is no sense in going deeper in config
|
|
@@ -203,7 +267,7 @@ export function getPathFromState<ParamList extends {}>(
|
|
|
203
267
|
}
|
|
204
268
|
}
|
|
205
269
|
|
|
206
|
-
if (currentOptions[route.name]
|
|
270
|
+
if (currentOptions[route.name] != null) {
|
|
207
271
|
path += parts
|
|
208
272
|
?.map(({ segment, param, optional }) => {
|
|
209
273
|
// We don't know what to show for wildcard patterns
|
package/src/getPatternParts.tsx
CHANGED
|
@@ -124,3 +124,11 @@ export function getPatternParts(path: string): PatternPart[] {
|
|
|
124
124
|
|
|
125
125
|
return parts;
|
|
126
126
|
}
|
|
127
|
+
|
|
128
|
+
export function combinePatternParts<T extends PatternPart>(
|
|
129
|
+
parentParts: T[],
|
|
130
|
+
parts: T[],
|
|
131
|
+
exact = false
|
|
132
|
+
): T[] {
|
|
133
|
+
return exact ? parts : [...parentParts, ...parts];
|
|
134
|
+
}
|