@react-navigation/core 7.0.0-alpha.8 → 7.0.0-rc.0
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/commonjs/BaseNavigationContainer.js +18 -19
- package/lib/commonjs/BaseNavigationContainer.js.map +1 -1
- package/lib/commonjs/CurrentRenderContext.js +1 -1
- package/lib/commonjs/CurrentRenderContext.js.map +1 -1
- package/lib/commonjs/DeprecatedNavigationInChildContext.js +1 -1
- package/lib/commonjs/DeprecatedNavigationInChildContext.js.map +1 -1
- package/lib/commonjs/EnsureSingleNavigator.js +4 -5
- package/lib/commonjs/EnsureSingleNavigator.js.map +1 -1
- package/lib/commonjs/Group.js.map +1 -1
- package/lib/commonjs/NavigationBuilderContext.js +1 -1
- package/lib/commonjs/NavigationBuilderContext.js.map +1 -1
- package/lib/commonjs/NavigationContainerRefContext.js +1 -1
- package/lib/commonjs/NavigationContainerRefContext.js.map +1 -1
- package/lib/commonjs/NavigationContext.js +1 -1
- package/lib/commonjs/NavigationContext.js.map +1 -1
- package/lib/commonjs/NavigationHelpersContext.js +1 -1
- package/lib/commonjs/NavigationHelpersContext.js.map +1 -1
- package/lib/commonjs/NavigationIndependentTree.js +4 -5
- package/lib/commonjs/NavigationIndependentTree.js.map +1 -1
- package/lib/commonjs/NavigationIndependentTreeContext.js +1 -1
- package/lib/commonjs/NavigationIndependentTreeContext.js.map +1 -1
- package/lib/commonjs/NavigationRouteContext.js +1 -1
- package/lib/commonjs/NavigationRouteContext.js.map +1 -1
- package/lib/commonjs/NavigationStateContext.js +1 -1
- package/lib/commonjs/NavigationStateContext.js.map +1 -1
- package/lib/commonjs/PreventRemoveContext.js +1 -1
- package/lib/commonjs/PreventRemoveContext.js.map +1 -1
- package/lib/commonjs/PreventRemoveProvider.js +12 -17
- package/lib/commonjs/PreventRemoveProvider.js.map +1 -1
- package/lib/commonjs/SceneView.js +11 -12
- package/lib/commonjs/SceneView.js.map +1 -1
- package/lib/commonjs/Screen.js.map +1 -1
- package/lib/commonjs/StaticContainer.js +1 -1
- package/lib/commonjs/StaticContainer.js.map +1 -1
- package/lib/commonjs/StaticNavigation.js +85 -37
- package/lib/commonjs/StaticNavigation.js.map +1 -1
- package/lib/commonjs/UnhandledActionContext.js +1 -1
- package/lib/commonjs/UnhandledActionContext.js.map +1 -1
- package/lib/commonjs/checkDuplicateRouteNames.js.map +1 -1
- package/lib/commonjs/checkSerializable.js.map +1 -1
- package/lib/commonjs/createNavigationContainerRef.js +2 -6
- package/lib/commonjs/createNavigationContainerRef.js.map +1 -1
- package/lib/commonjs/createNavigatorFactory.js.map +1 -1
- package/lib/commonjs/deepFreeze.js +37 -0
- package/lib/commonjs/deepFreeze.js.map +1 -0
- package/lib/commonjs/findFocusedRoute.js.map +1 -1
- package/lib/commonjs/getActionFromState.js +1 -2
- package/lib/commonjs/getActionFromState.js.map +1 -1
- package/lib/commonjs/getFocusedRouteNameFromRoute.js.map +1 -1
- package/lib/commonjs/getPathFromState.js +8 -14
- package/lib/commonjs/getPathFromState.js.map +1 -1
- package/lib/commonjs/getStateFromPath.js +48 -20
- package/lib/commonjs/getStateFromPath.js.map +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/isArrayEqual.js.map +1 -1
- package/lib/commonjs/isRecordEqual.js.map +1 -1
- package/lib/commonjs/theming/ThemeContext.js +1 -1
- package/lib/commonjs/theming/ThemeContext.js.map +1 -1
- package/lib/commonjs/theming/ThemeProvider.js +5 -6
- package/lib/commonjs/theming/ThemeProvider.js.map +1 -1
- package/lib/commonjs/theming/useTheme.js +1 -1
- package/lib/commonjs/theming/useTheme.js.map +1 -1
- package/lib/commonjs/types.js.map +1 -1
- package/lib/commonjs/useChildListeners.js +1 -1
- package/lib/commonjs/useChildListeners.js.map +1 -1
- package/lib/commonjs/useComponent.js +8 -10
- package/lib/commonjs/useComponent.js.map +1 -1
- package/lib/commonjs/useCurrentRender.js +6 -7
- package/lib/commonjs/useCurrentRender.js.map +1 -1
- package/lib/commonjs/useDescriptors.js +16 -17
- package/lib/commonjs/useDescriptors.js.map +1 -1
- package/lib/commonjs/useEventEmitter.js +7 -8
- package/lib/commonjs/useEventEmitter.js.map +1 -1
- package/lib/commonjs/useFocusEffect.js +3 -3
- package/lib/commonjs/useFocusEffect.js.map +1 -1
- package/lib/commonjs/useFocusEvents.js +5 -6
- package/lib/commonjs/useFocusEvents.js.map +1 -1
- package/lib/commonjs/useFocusedListenersChildrenAdapter.js +5 -6
- package/lib/commonjs/useFocusedListenersChildrenAdapter.js.map +1 -1
- package/lib/commonjs/useIsFocused.js +1 -1
- package/lib/commonjs/useIsFocused.js.map +1 -1
- package/lib/commonjs/useIsomorphicLayoutEffect.js.map +1 -1
- package/lib/commonjs/useIsomorphicLayoutEffect.native.js.map +1 -1
- package/lib/commonjs/useKeyedChildListeners.js +1 -1
- package/lib/commonjs/useKeyedChildListeners.js.map +1 -1
- package/lib/commonjs/useLazyValue.js +17 -0
- package/lib/commonjs/useLazyValue.js.map +1 -0
- package/lib/commonjs/useNavigation.js +1 -1
- package/lib/commonjs/useNavigation.js.map +1 -1
- package/lib/commonjs/useNavigationBuilder.js +16 -8
- package/lib/commonjs/useNavigationBuilder.js.map +1 -1
- package/lib/commonjs/useNavigationCache.js +12 -18
- package/lib/commonjs/useNavigationCache.js.map +1 -1
- package/lib/commonjs/useNavigationContainerRef.js +1 -1
- package/lib/commonjs/useNavigationContainerRef.js.map +1 -1
- package/lib/commonjs/useNavigationHelpers.js +9 -12
- package/lib/commonjs/useNavigationHelpers.js.map +1 -1
- package/lib/commonjs/useNavigationIndependentTree.js +1 -1
- package/lib/commonjs/useNavigationIndependentTree.js.map +1 -1
- package/lib/commonjs/useNavigationState.js +1 -1
- package/lib/commonjs/useNavigationState.js.map +1 -1
- package/lib/commonjs/useOnAction.js +12 -14
- package/lib/commonjs/useOnAction.js.map +1 -1
- package/lib/commonjs/useOnGetState.js +5 -6
- package/lib/commonjs/useOnGetState.js.map +1 -1
- package/lib/commonjs/useOnPreventRemove.js +6 -7
- package/lib/commonjs/useOnPreventRemove.js.map +1 -1
- package/lib/commonjs/useOnRouteFocus.js +7 -8
- package/lib/commonjs/useOnRouteFocus.js.map +1 -1
- package/lib/commonjs/useOptionsGetters.js +6 -7
- package/lib/commonjs/useOptionsGetters.js.map +1 -1
- package/lib/commonjs/usePreventRemove.js +2 -2
- package/lib/commonjs/usePreventRemove.js.map +1 -1
- package/lib/commonjs/usePreventRemoveContext.js +1 -1
- package/lib/commonjs/usePreventRemoveContext.js.map +1 -1
- package/lib/commonjs/useRegisterNavigator.js +1 -1
- package/lib/commonjs/useRegisterNavigator.js.map +1 -1
- package/lib/commonjs/useRoute.js +1 -1
- package/lib/commonjs/useRoute.js.map +1 -1
- package/lib/commonjs/useRouteCache.js +16 -2
- package/lib/commonjs/useRouteCache.js.map +1 -1
- package/lib/commonjs/useSyncState.js +13 -4
- package/lib/commonjs/useSyncState.js.map +1 -1
- package/lib/commonjs/validatePathConfig.js +3 -8
- package/lib/commonjs/validatePathConfig.js.map +1 -1
- package/lib/module/BaseNavigationContainer.js +16 -17
- package/lib/module/BaseNavigationContainer.js.map +1 -1
- package/lib/module/CurrentRenderContext.js.map +1 -1
- package/lib/module/DeprecatedNavigationInChildContext.js.map +1 -1
- package/lib/module/EnsureSingleNavigator.js +3 -4
- package/lib/module/EnsureSingleNavigator.js.map +1 -1
- package/lib/module/Group.js.map +1 -1
- package/lib/module/NavigationBuilderContext.js.map +1 -1
- package/lib/module/NavigationContainerRefContext.js.map +1 -1
- package/lib/module/NavigationContext.js.map +1 -1
- package/lib/module/NavigationHelpersContext.js.map +1 -1
- package/lib/module/NavigationIndependentTree.js +3 -4
- package/lib/module/NavigationIndependentTree.js.map +1 -1
- package/lib/module/NavigationIndependentTreeContext.js.map +1 -1
- package/lib/module/NavigationRouteContext.js.map +1 -1
- package/lib/module/NavigationStateContext.js.map +1 -1
- package/lib/module/PreventRemoveContext.js.map +1 -1
- package/lib/module/PreventRemoveProvider.js +10 -15
- package/lib/module/PreventRemoveProvider.js.map +1 -1
- package/lib/module/SceneView.js +10 -11
- package/lib/module/SceneView.js.map +1 -1
- package/lib/module/Screen.js.map +1 -1
- package/lib/module/StaticContainer.js.map +1 -1
- package/lib/module/StaticNavigation.js +84 -36
- package/lib/module/StaticNavigation.js.map +1 -1
- package/lib/module/UnhandledActionContext.js.map +1 -1
- package/lib/module/checkDuplicateRouteNames.js.map +1 -1
- package/lib/module/checkSerializable.js.map +1 -1
- package/lib/module/createNavigationContainerRef.js +2 -6
- package/lib/module/createNavigationContainerRef.js.map +1 -1
- package/lib/module/createNavigatorFactory.js +1 -0
- package/lib/module/createNavigatorFactory.js.map +1 -1
- package/lib/module/deepFreeze.js +29 -0
- package/lib/module/deepFreeze.js.map +1 -0
- 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/getFocusedRouteNameFromRoute.js.map +1 -1
- package/lib/module/getPathFromState.js +7 -13
- package/lib/module/getPathFromState.js.map +1 -1
- package/lib/module/getStateFromPath.js +46 -18
- package/lib/module/getStateFromPath.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/isArrayEqual.js.map +1 -1
- package/lib/module/isRecordEqual.js.map +1 -1
- package/lib/module/theming/ThemeContext.js.map +1 -1
- package/lib/module/theming/ThemeProvider.js +4 -5
- package/lib/module/theming/ThemeProvider.js.map +1 -1
- package/lib/module/theming/useTheme.js.map +1 -1
- package/lib/module/types.js.map +1 -1
- package/lib/module/useChildListeners.js.map +1 -1
- package/lib/module/useComponent.js +7 -9
- package/lib/module/useComponent.js.map +1 -1
- package/lib/module/useCurrentRender.js +5 -6
- package/lib/module/useCurrentRender.js.map +1 -1
- package/lib/module/useDescriptors.js +15 -16
- package/lib/module/useDescriptors.js.map +1 -1
- package/lib/module/useEventEmitter.js +6 -7
- package/lib/module/useEventEmitter.js.map +1 -1
- package/lib/module/useFocusEffect.js +2 -2
- package/lib/module/useFocusEffect.js.map +1 -1
- package/lib/module/useFocusEvents.js +4 -5
- package/lib/module/useFocusEvents.js.map +1 -1
- package/lib/module/useFocusedListenersChildrenAdapter.js +4 -5
- package/lib/module/useFocusedListenersChildrenAdapter.js.map +1 -1
- package/lib/module/useIsFocused.js.map +1 -1
- package/lib/module/useIsomorphicLayoutEffect.js.map +1 -1
- package/lib/module/useIsomorphicLayoutEffect.native.js.map +1 -1
- package/lib/module/useKeyedChildListeners.js.map +1 -1
- package/lib/module/useLazyValue.js +9 -0
- package/lib/module/useLazyValue.js.map +1 -0
- package/lib/module/useNavigation.js.map +1 -1
- package/lib/module/useNavigationBuilder.js +14 -6
- package/lib/module/useNavigationBuilder.js.map +1 -1
- package/lib/module/useNavigationCache.js +11 -17
- package/lib/module/useNavigationCache.js.map +1 -1
- package/lib/module/useNavigationContainerRef.js.map +1 -1
- package/lib/module/useNavigationHelpers.js +8 -11
- package/lib/module/useNavigationHelpers.js.map +1 -1
- package/lib/module/useNavigationIndependentTree.js.map +1 -1
- package/lib/module/useNavigationState.js.map +1 -1
- package/lib/module/useOnAction.js +11 -13
- package/lib/module/useOnAction.js.map +1 -1
- package/lib/module/useOnGetState.js +4 -5
- package/lib/module/useOnGetState.js.map +1 -1
- package/lib/module/useOnPreventRemove.js +5 -6
- package/lib/module/useOnPreventRemove.js.map +1 -1
- package/lib/module/useOnRouteFocus.js +6 -7
- package/lib/module/useOnRouteFocus.js.map +1 -1
- package/lib/module/useOptionsGetters.js +5 -6
- package/lib/module/useOptionsGetters.js.map +1 -1
- package/lib/module/usePreventRemove.js.map +1 -1
- package/lib/module/usePreventRemoveContext.js.map +1 -1
- package/lib/module/useRegisterNavigator.js.map +1 -1
- package/lib/module/useRoute.js.map +1 -1
- package/lib/module/useRouteCache.js +15 -1
- package/lib/module/useRouteCache.js.map +1 -1
- package/lib/module/useSyncState.js +12 -3
- package/lib/module/useSyncState.js.map +1 -1
- package/lib/module/validatePathConfig.js +3 -8
- package/lib/module/validatePathConfig.js.map +1 -1
- package/lib/typescript/src/BaseNavigationContainer.d.ts.map +1 -1
- package/lib/typescript/src/CurrentRenderContext.d.ts +1 -1
- package/lib/typescript/src/CurrentRenderContext.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 +5 -5
- package/lib/typescript/src/NavigationBuilderContext.d.ts.map +1 -1
- package/lib/typescript/src/NavigationStateContext.d.ts +3 -19
- package/lib/typescript/src/NavigationStateContext.d.ts.map +1 -1
- package/lib/typescript/src/PreventRemoveContext.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 +43 -19
- package/lib/typescript/src/StaticNavigation.d.ts.map +1 -1
- package/lib/typescript/src/checkSerializable.d.ts.map +1 -1
- package/lib/typescript/src/createNavigatorFactory.d.ts +1 -9
- package/lib/typescript/src/createNavigatorFactory.d.ts.map +1 -1
- package/lib/typescript/src/deepFreeze.d.ts +3 -0
- package/lib/typescript/src/deepFreeze.d.ts.map +1 -0
- package/lib/typescript/src/findFocusedRoute.d.ts +1 -11
- package/lib/typescript/src/findFocusedRoute.d.ts.map +1 -1
- package/lib/typescript/src/getPathFromState.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +69 -24
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/useChildListeners.d.ts.map +1 -1
- package/lib/typescript/src/useComponent.d.ts.map +1 -1
- package/lib/typescript/src/useDescriptors.d.ts +35 -45
- package/lib/typescript/src/useDescriptors.d.ts.map +1 -1
- package/lib/typescript/src/useKeyedChildListeners.d.ts.map +1 -1
- package/lib/typescript/src/useLazyValue.d.ts +2 -0
- package/lib/typescript/src/useLazyValue.d.ts.map +1 -0
- package/lib/typescript/src/useNavigation.d.ts +4 -1
- package/lib/typescript/src/useNavigation.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationBuilder.d.ts +57 -93
- package/lib/typescript/src/useNavigationBuilder.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationCache.d.ts +17 -22
- package/lib/typescript/src/useNavigationCache.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationHelpers.d.ts +21 -26
- package/lib/typescript/src/useNavigationHelpers.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 +1 -1
- package/lib/typescript/src/useRouteCache.d.ts.map +1 -1
- package/lib/typescript/src/useSyncState.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/BaseNavigationContainer.tsx +3 -0
- package/src/Group.tsx +2 -1
- package/src/Screen.tsx +11 -1
- package/src/StaticNavigation.tsx +299 -72
- package/src/createNavigatorFactory.tsx +1 -36
- package/src/deepFreeze.tsx +34 -0
- package/src/getPathFromState.tsx +6 -1
- package/src/getStateFromPath.tsx +60 -16
- package/src/index.tsx +1 -0
- package/src/types.tsx +138 -23
- package/src/useDescriptors.tsx +8 -1
- package/src/useFocusEffect.tsx +2 -2
- package/src/useLazyValue.tsx +11 -0
- package/src/useNavigation.tsx +4 -1
- package/src/useNavigationBuilder.tsx +33 -11
- package/src/useRouteCache.tsx +17 -1
- package/src/useSyncState.tsx +16 -3
package/src/StaticNavigation.tsx
CHANGED
|
@@ -5,9 +5,12 @@ import { isValidElementType } from 'react-is';
|
|
|
5
5
|
import type {
|
|
6
6
|
DefaultNavigatorOptions,
|
|
7
7
|
EventMapBase,
|
|
8
|
+
NavigationListBase,
|
|
8
9
|
NavigatorScreenParams,
|
|
10
|
+
NavigatorTypeBagBase,
|
|
9
11
|
PathConfig,
|
|
10
|
-
|
|
12
|
+
RouteConfigComponent,
|
|
13
|
+
RouteConfigProps,
|
|
11
14
|
RouteGroupConfig,
|
|
12
15
|
} from './types';
|
|
13
16
|
import { useRoute } from './useRoute';
|
|
@@ -62,7 +65,8 @@ type ParamListForGroups<
|
|
|
62
65
|
ParamListBase,
|
|
63
66
|
NavigationState,
|
|
64
67
|
{},
|
|
65
|
-
EventMapBase
|
|
68
|
+
EventMapBase,
|
|
69
|
+
any
|
|
66
70
|
>;
|
|
67
71
|
};
|
|
68
72
|
}>
|
|
@@ -73,24 +77,53 @@ type ParamListForGroups<
|
|
|
73
77
|
ParamListBase,
|
|
74
78
|
NavigationState,
|
|
75
79
|
{},
|
|
76
|
-
EventMapBase
|
|
80
|
+
EventMapBase,
|
|
81
|
+
any
|
|
77
82
|
>;
|
|
78
83
|
};
|
|
79
84
|
}
|
|
80
85
|
? ParamListForScreens<UnionToIntersection<Groups[keyof Groups]['screens']>>
|
|
81
86
|
: {};
|
|
82
87
|
|
|
88
|
+
type StaticRouteConfig<
|
|
89
|
+
ParamList extends ParamListBase,
|
|
90
|
+
RouteName extends keyof ParamList,
|
|
91
|
+
State extends NavigationState,
|
|
92
|
+
ScreenOptions extends {},
|
|
93
|
+
EventMap extends EventMapBase,
|
|
94
|
+
Navigation,
|
|
95
|
+
> = RouteConfigProps<
|
|
96
|
+
// FIXME: the param list is inferred from the screen component
|
|
97
|
+
// So we can't use the type here
|
|
98
|
+
// Fallback to ParamListBase for now
|
|
99
|
+
ParamListBase,
|
|
100
|
+
string,
|
|
101
|
+
State,
|
|
102
|
+
ScreenOptions,
|
|
103
|
+
EventMap,
|
|
104
|
+
Navigation
|
|
105
|
+
> &
|
|
106
|
+
RouteConfigComponent<ParamList, RouteName>;
|
|
107
|
+
|
|
83
108
|
type StaticConfigScreens<
|
|
84
109
|
ParamList extends ParamListBase,
|
|
85
110
|
State extends NavigationState,
|
|
86
111
|
ScreenOptions extends {},
|
|
87
112
|
EventMap extends EventMapBase,
|
|
113
|
+
NavigationList extends NavigationListBase<ParamList>,
|
|
88
114
|
> = {
|
|
89
|
-
[
|
|
115
|
+
[RouteName in keyof ParamList]:
|
|
90
116
|
| React.ComponentType<any>
|
|
91
117
|
| StaticNavigation<any, any, any>
|
|
92
118
|
| (Omit<
|
|
93
|
-
|
|
119
|
+
StaticRouteConfig<
|
|
120
|
+
ParamList,
|
|
121
|
+
RouteName,
|
|
122
|
+
State,
|
|
123
|
+
ScreenOptions,
|
|
124
|
+
EventMap,
|
|
125
|
+
NavigationList[RouteName]
|
|
126
|
+
>,
|
|
94
127
|
'name' | 'component' | 'getComponent' | 'children'
|
|
95
128
|
> & {
|
|
96
129
|
/**
|
|
@@ -131,7 +164,11 @@ type GroupConfig<
|
|
|
131
164
|
State extends NavigationState,
|
|
132
165
|
ScreenOptions extends {},
|
|
133
166
|
EventMap extends EventMapBase,
|
|
134
|
-
|
|
167
|
+
NavigationList extends NavigationListBase<ParamList>,
|
|
168
|
+
> = Omit<
|
|
169
|
+
RouteGroupConfig<ParamList, ScreenOptions, NavigationList[keyof ParamList]>,
|
|
170
|
+
'screens' | 'children'
|
|
171
|
+
> & {
|
|
135
172
|
/**
|
|
136
173
|
* Callback to determine whether the screens in the group should be rendered or not.
|
|
137
174
|
* This can be useful for conditional rendering of group of screens.
|
|
@@ -140,39 +177,106 @@ type GroupConfig<
|
|
|
140
177
|
/**
|
|
141
178
|
* Static navigation config or Component to render for the screen.
|
|
142
179
|
*/
|
|
143
|
-
screens: StaticConfigScreens<
|
|
180
|
+
screens: StaticConfigScreens<
|
|
181
|
+
ParamList,
|
|
182
|
+
State,
|
|
183
|
+
ScreenOptions,
|
|
184
|
+
EventMap,
|
|
185
|
+
NavigationList
|
|
186
|
+
>;
|
|
144
187
|
};
|
|
145
188
|
|
|
146
|
-
export type StaticConfig<
|
|
189
|
+
export type StaticConfig<Bag extends NavigatorTypeBagBase> =
|
|
190
|
+
StaticConfigInternal<
|
|
191
|
+
Bag['ParamList'],
|
|
192
|
+
Bag['NavigatorID'],
|
|
193
|
+
Bag['State'],
|
|
194
|
+
Bag['ScreenOptions'],
|
|
195
|
+
Bag['EventMap'],
|
|
196
|
+
Bag['NavigationList'],
|
|
197
|
+
Bag['Navigator']
|
|
198
|
+
>;
|
|
199
|
+
|
|
200
|
+
type StaticConfigInternal<
|
|
147
201
|
ParamList extends ParamListBase,
|
|
202
|
+
NavigatorID extends string | undefined,
|
|
148
203
|
State extends NavigationState,
|
|
149
204
|
ScreenOptions extends {},
|
|
150
205
|
EventMap extends EventMapBase,
|
|
151
|
-
|
|
206
|
+
NavigationList extends NavigationListBase<ParamList>,
|
|
207
|
+
Navigator extends React.ComponentType<any>,
|
|
152
208
|
> = Omit<
|
|
153
209
|
Omit<
|
|
154
210
|
React.ComponentProps<Navigator>,
|
|
155
211
|
keyof DefaultNavigatorOptions<
|
|
156
212
|
ParamListBase,
|
|
213
|
+
string | undefined,
|
|
157
214
|
NavigationState,
|
|
158
215
|
{},
|
|
159
|
-
EventMapBase
|
|
216
|
+
EventMapBase,
|
|
217
|
+
NavigationList[keyof ParamList]
|
|
160
218
|
>
|
|
161
219
|
> &
|
|
162
|
-
DefaultNavigatorOptions<
|
|
220
|
+
DefaultNavigatorOptions<
|
|
221
|
+
ParamList,
|
|
222
|
+
NavigatorID,
|
|
223
|
+
State,
|
|
224
|
+
ScreenOptions,
|
|
225
|
+
EventMap,
|
|
226
|
+
NavigationList[keyof ParamList]
|
|
227
|
+
>,
|
|
163
228
|
'screens' | 'children'
|
|
164
|
-
> &
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
229
|
+
> &
|
|
230
|
+
(
|
|
231
|
+
| {
|
|
232
|
+
/**
|
|
233
|
+
* Screens to render in the navigator and their configuration.
|
|
234
|
+
*/
|
|
235
|
+
screens: StaticConfigScreens<
|
|
236
|
+
ParamList,
|
|
237
|
+
State,
|
|
238
|
+
ScreenOptions,
|
|
239
|
+
EventMap,
|
|
240
|
+
NavigationList
|
|
241
|
+
>;
|
|
242
|
+
/**
|
|
243
|
+
* Groups of screens to render in the navigator and their configuration.
|
|
244
|
+
*/
|
|
245
|
+
groups?: {
|
|
246
|
+
[key: string]: GroupConfig<
|
|
247
|
+
ParamList,
|
|
248
|
+
State,
|
|
249
|
+
ScreenOptions,
|
|
250
|
+
EventMap,
|
|
251
|
+
NavigationList
|
|
252
|
+
>;
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
| {
|
|
256
|
+
/**
|
|
257
|
+
* Screens to render in the navigator and their configuration.
|
|
258
|
+
*/
|
|
259
|
+
screens?: StaticConfigScreens<
|
|
260
|
+
ParamList,
|
|
261
|
+
State,
|
|
262
|
+
ScreenOptions,
|
|
263
|
+
EventMap,
|
|
264
|
+
NavigationList
|
|
265
|
+
>;
|
|
266
|
+
/**
|
|
267
|
+
* Groups of screens to render in the navigator and their configuration.
|
|
268
|
+
*/
|
|
269
|
+
groups: {
|
|
270
|
+
[key: string]: GroupConfig<
|
|
271
|
+
ParamList,
|
|
272
|
+
State,
|
|
273
|
+
ScreenOptions,
|
|
274
|
+
EventMap,
|
|
275
|
+
NavigationList
|
|
276
|
+
>;
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
);
|
|
176
280
|
|
|
177
281
|
/**
|
|
178
282
|
* Props for a screen component which is rendered by a static navigator.
|
|
@@ -190,7 +294,7 @@ export type StaticScreenProps<T extends Record<string, unknown> | undefined> = {
|
|
|
190
294
|
export type StaticParamList<
|
|
191
295
|
T extends {
|
|
192
296
|
readonly config: {
|
|
193
|
-
readonly screens
|
|
297
|
+
readonly screens?: Record<string, any>;
|
|
194
298
|
readonly groups?: {
|
|
195
299
|
[key: string]: {
|
|
196
300
|
screens: Record<string, any>;
|
|
@@ -207,13 +311,7 @@ export type StaticNavigation<NavigatorProps, GroupProps, ScreenProps> = {
|
|
|
207
311
|
Navigator: React.ComponentType<NavigatorProps>;
|
|
208
312
|
Group: React.ComponentType<GroupProps>;
|
|
209
313
|
Screen: React.ComponentType<ScreenProps>;
|
|
210
|
-
config: StaticConfig<
|
|
211
|
-
ParamListBase,
|
|
212
|
-
NavigationState,
|
|
213
|
-
{},
|
|
214
|
-
EventMapBase,
|
|
215
|
-
React.ComponentType<any>
|
|
216
|
-
>;
|
|
314
|
+
config: StaticConfig<NavigatorTypeBagBase>;
|
|
217
315
|
};
|
|
218
316
|
|
|
219
317
|
const MemoizedScreen = React.memo(
|
|
@@ -227,7 +325,7 @@ const MemoizedScreen = React.memo(
|
|
|
227
325
|
|
|
228
326
|
const getItemsFromScreens = (
|
|
229
327
|
Screen: React.ComponentType<any>,
|
|
230
|
-
screens: StaticConfigScreens<any, any, any, any>
|
|
328
|
+
screens: StaticConfigScreens<any, any, any, any, any>
|
|
231
329
|
) => {
|
|
232
330
|
return Object.entries(screens).map(([name, item]) => {
|
|
233
331
|
let component: React.ComponentType<any> | undefined;
|
|
@@ -300,13 +398,13 @@ export function createComponentForStaticNavigation(
|
|
|
300
398
|
const { Navigator, Group, Screen, config } = tree;
|
|
301
399
|
const { screens, groups, ...rest } = config;
|
|
302
400
|
|
|
303
|
-
if (screens == null) {
|
|
401
|
+
if (screens == null && groups == null) {
|
|
304
402
|
throw new Error(
|
|
305
|
-
"Couldn't find a 'screens' property. Make sure to define your screens under a 'screens' property in the configuration."
|
|
403
|
+
"Couldn't find a 'screens' or 'groups' property. Make sure to define your screens under a 'screens' property in the configuration."
|
|
306
404
|
);
|
|
307
405
|
}
|
|
308
406
|
|
|
309
|
-
const items = getItemsFromScreens(Screen, screens);
|
|
407
|
+
const items = screens ? getItemsFromScreens(Screen, screens) : [];
|
|
310
408
|
|
|
311
409
|
if (groups) {
|
|
312
410
|
items.push(
|
|
@@ -344,10 +442,36 @@ export function createComponentForStaticNavigation(
|
|
|
344
442
|
return NavigatorComponent;
|
|
345
443
|
}
|
|
346
444
|
|
|
445
|
+
type TreeForPathConfig = {
|
|
446
|
+
config: {
|
|
447
|
+
initialRouteName?: string;
|
|
448
|
+
screens?: StaticConfigScreens<
|
|
449
|
+
ParamListBase,
|
|
450
|
+
NavigationState,
|
|
451
|
+
{},
|
|
452
|
+
EventMapBase,
|
|
453
|
+
Record<string, unknown>
|
|
454
|
+
>;
|
|
455
|
+
groups?: {
|
|
456
|
+
[key: string]: {
|
|
457
|
+
screens: StaticConfigScreens<
|
|
458
|
+
ParamListBase,
|
|
459
|
+
NavigationState,
|
|
460
|
+
{},
|
|
461
|
+
EventMapBase,
|
|
462
|
+
Record<string, unknown>
|
|
463
|
+
>;
|
|
464
|
+
};
|
|
465
|
+
};
|
|
466
|
+
};
|
|
467
|
+
};
|
|
468
|
+
|
|
347
469
|
/**
|
|
348
470
|
* Create a path config object from a static navigation config for deep linking.
|
|
349
471
|
*
|
|
350
472
|
* @param tree Static navigation config.
|
|
473
|
+
* @param options Additional options from `linking.config`.
|
|
474
|
+
* @param auto Whether to automatically generate paths for leaf screens.
|
|
351
475
|
* @returns Path config object to use in linking config.
|
|
352
476
|
*
|
|
353
477
|
* @example
|
|
@@ -361,43 +485,146 @@ export function createComponentForStaticNavigation(
|
|
|
361
485
|
* };
|
|
362
486
|
* ```
|
|
363
487
|
*/
|
|
364
|
-
export function createPathConfigForStaticNavigation(
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
488
|
+
export function createPathConfigForStaticNavigation(
|
|
489
|
+
tree: TreeForPathConfig,
|
|
490
|
+
options?: {
|
|
491
|
+
initialRouteName?: string;
|
|
492
|
+
},
|
|
493
|
+
auto?: boolean
|
|
494
|
+
) {
|
|
495
|
+
let initialScreenConfig: PathConfig<ParamListBase> | undefined;
|
|
496
|
+
|
|
497
|
+
const createPathConfigForTree = (
|
|
498
|
+
t: TreeForPathConfig,
|
|
499
|
+
o: { initialRouteName?: string } | undefined,
|
|
500
|
+
// If a screen is a leaf node, but inside a screen with path,
|
|
501
|
+
// It should not be used for initial detection
|
|
502
|
+
skipInitialDetection: boolean
|
|
503
|
+
) => {
|
|
504
|
+
const createPathConfigForScreens = (
|
|
505
|
+
screens: StaticConfigScreens<
|
|
506
|
+
ParamListBase,
|
|
507
|
+
NavigationState,
|
|
508
|
+
{},
|
|
509
|
+
EventMapBase,
|
|
510
|
+
Record<string, unknown>
|
|
511
|
+
>,
|
|
512
|
+
initialRouteName: string | undefined
|
|
513
|
+
) => {
|
|
514
|
+
return Object.fromEntries(
|
|
515
|
+
Object.entries(screens)
|
|
516
|
+
// Re-order to move the initial route to the front
|
|
517
|
+
// This way we can detect the initial route correctly
|
|
518
|
+
.sort(([a], [b]) => {
|
|
519
|
+
if (a === initialRouteName) {
|
|
520
|
+
return -1;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
if (b === initialRouteName) {
|
|
524
|
+
return 1;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
return 0;
|
|
528
|
+
})
|
|
529
|
+
.map(([key, item]) => {
|
|
530
|
+
const screenConfig: PathConfig<ParamListBase> = {};
|
|
531
|
+
|
|
532
|
+
if ('linking' in item) {
|
|
533
|
+
if (typeof item.linking === 'string') {
|
|
534
|
+
screenConfig.path = item.linking;
|
|
535
|
+
} else {
|
|
536
|
+
Object.assign(screenConfig, item.linking);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
let screens;
|
|
541
|
+
|
|
542
|
+
if ('config' in item) {
|
|
543
|
+
screens = createPathConfigForTree(
|
|
544
|
+
item,
|
|
545
|
+
undefined,
|
|
546
|
+
skipInitialDetection || screenConfig.path != null
|
|
547
|
+
);
|
|
548
|
+
} else if (
|
|
549
|
+
'screen' in item &&
|
|
550
|
+
'config' in item.screen &&
|
|
551
|
+
(item.screen.config.screens || item.screen.config.groups)
|
|
552
|
+
) {
|
|
553
|
+
screens = createPathConfigForTree(
|
|
554
|
+
item.screen,
|
|
555
|
+
undefined,
|
|
556
|
+
skipInitialDetection || screenConfig.path != null
|
|
557
|
+
);
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
if (screens) {
|
|
561
|
+
screenConfig.screens = screens;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
if (auto && !screenConfig.screens && !('linking' in item)) {
|
|
565
|
+
if (screenConfig.path) {
|
|
566
|
+
if (!skipInitialDetection) {
|
|
567
|
+
// Normalize the path to remove leading and trailing slashes
|
|
568
|
+
const path = screenConfig.path
|
|
569
|
+
?.split('/')
|
|
570
|
+
.filter(Boolean)
|
|
571
|
+
.join('/');
|
|
572
|
+
|
|
573
|
+
// We encounter a leaf screen with empty path,
|
|
574
|
+
// Clear the initial screen config as it's not needed anymore
|
|
575
|
+
if (!skipInitialDetection && path === '') {
|
|
576
|
+
initialScreenConfig = undefined;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
} else {
|
|
580
|
+
if (!skipInitialDetection && initialScreenConfig == null) {
|
|
581
|
+
initialScreenConfig = screenConfig;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
screenConfig.path = key
|
|
585
|
+
.replace(/([A-Z]+)/g, '-$1')
|
|
586
|
+
.replace(/^-/, '')
|
|
587
|
+
.toLowerCase();
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
return [key, screenConfig] as const;
|
|
592
|
+
})
|
|
593
|
+
.filter(([, screen]) => Object.keys(screen).length > 0)
|
|
594
|
+
);
|
|
595
|
+
};
|
|
596
|
+
|
|
597
|
+
const screens = t.config.screens
|
|
598
|
+
? createPathConfigForScreens(
|
|
599
|
+
t.config.screens,
|
|
600
|
+
o?.initialRouteName ?? t.config.initialRouteName
|
|
601
|
+
)
|
|
602
|
+
: {};
|
|
603
|
+
|
|
604
|
+
if (t.config.groups) {
|
|
605
|
+
Object.entries(t.config.groups).forEach(([, group]) => {
|
|
606
|
+
Object.assign(
|
|
607
|
+
screens,
|
|
608
|
+
createPathConfigForScreens(
|
|
609
|
+
group.screens,
|
|
610
|
+
o?.initialRouteName ?? t.config.initialRouteName
|
|
611
|
+
)
|
|
612
|
+
);
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
if (Object.keys(screens).length === 0) {
|
|
617
|
+
return undefined;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
return screens;
|
|
372
621
|
};
|
|
373
|
-
}) {
|
|
374
|
-
return Object.fromEntries(
|
|
375
|
-
Object.entries(tree.config.screens)
|
|
376
|
-
.map(([key, item]) => {
|
|
377
|
-
const screenConfig: PathConfig<ParamListBase> = {};
|
|
378
|
-
|
|
379
|
-
if ('linking' in item) {
|
|
380
|
-
if (typeof item.linking === 'string') {
|
|
381
|
-
screenConfig.path = item.linking;
|
|
382
|
-
} else {
|
|
383
|
-
Object.assign(screenConfig, item.linking);
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
if ('config' in item) {
|
|
388
|
-
screenConfig.screens = createPathConfigForStaticNavigation(item);
|
|
389
|
-
} else if (
|
|
390
|
-
'screen' in item &&
|
|
391
|
-
'config' in item.screen &&
|
|
392
|
-
item.screen.config.screens
|
|
393
|
-
) {
|
|
394
|
-
screenConfig.screens = createPathConfigForStaticNavigation(
|
|
395
|
-
item.screen
|
|
396
|
-
);
|
|
397
|
-
}
|
|
398
622
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
623
|
+
const screens = createPathConfigForTree(tree, options, false);
|
|
624
|
+
|
|
625
|
+
if (auto && initialScreenConfig) {
|
|
626
|
+
initialScreenConfig.path = '';
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
return screens;
|
|
403
630
|
}
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import type { NavigationState, ParamListBase } from '@react-navigation/routers';
|
|
2
1
|
import type * as React from 'react';
|
|
3
2
|
|
|
4
3
|
import { Group } from './Group';
|
|
5
4
|
import { Screen } from './Screen';
|
|
6
|
-
import type { StaticConfig } from './StaticNavigation';
|
|
7
|
-
import type { EventMapBase, TypedNavigator } from './types';
|
|
8
5
|
|
|
9
6
|
/**
|
|
10
7
|
* Higher order component to create a `Navigator` and `Screen` pair.
|
|
@@ -13,39 +10,7 @@ import type { EventMapBase, TypedNavigator } from './types';
|
|
|
13
10
|
* @param Navigator The navigator component to wrap.
|
|
14
11
|
* @returns Factory method to create a `Navigator` and `Screen` pair.
|
|
15
12
|
*/
|
|
16
|
-
export function createNavigatorFactory<
|
|
17
|
-
State extends NavigationState,
|
|
18
|
-
ScreenOptions extends {},
|
|
19
|
-
EventMap extends EventMapBase,
|
|
20
|
-
NavigatorComponent extends React.ComponentType<any>,
|
|
21
|
-
>(Navigator: NavigatorComponent) {
|
|
22
|
-
function createNavigator<ParamList extends ParamListBase>(): TypedNavigator<
|
|
23
|
-
ParamList,
|
|
24
|
-
State,
|
|
25
|
-
ScreenOptions,
|
|
26
|
-
EventMap,
|
|
27
|
-
typeof Navigator
|
|
28
|
-
>;
|
|
29
|
-
|
|
30
|
-
function createNavigator<
|
|
31
|
-
ParamList extends ParamListBase,
|
|
32
|
-
Config extends StaticConfig<
|
|
33
|
-
ParamList,
|
|
34
|
-
State,
|
|
35
|
-
ScreenOptions,
|
|
36
|
-
EventMap,
|
|
37
|
-
typeof Navigator
|
|
38
|
-
>,
|
|
39
|
-
>(
|
|
40
|
-
config: Config
|
|
41
|
-
): TypedNavigator<
|
|
42
|
-
ParamList,
|
|
43
|
-
State,
|
|
44
|
-
ScreenOptions,
|
|
45
|
-
EventMap,
|
|
46
|
-
typeof Navigator
|
|
47
|
-
> & { config: Config };
|
|
48
|
-
|
|
13
|
+
export function createNavigatorFactory(Navigator: React.ComponentType<any>) {
|
|
49
14
|
function createNavigator(config?: any): any {
|
|
50
15
|
if (config != null) {
|
|
51
16
|
return {
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export const isPlainObject = (value: unknown): value is object => {
|
|
2
|
+
if (typeof value === 'object' && value !== null) {
|
|
3
|
+
return Object.getPrototypeOf(value) === Object.prototype;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
return false;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const deepFreeze = <T,>(object: T): Readonly<T> => {
|
|
10
|
+
// We only freeze in development to catch issues early
|
|
11
|
+
// Don't freeze in production to avoid unnecessary performance overhead
|
|
12
|
+
if (process.env.NODE_ENV === 'production') {
|
|
13
|
+
return object;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (Object.isFrozen(object)) {
|
|
17
|
+
return object;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (!isPlainObject(object) && !Array.isArray(object)) {
|
|
21
|
+
return object;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Freeze properties before freezing self
|
|
25
|
+
for (const key in object) {
|
|
26
|
+
if (Object.getOwnPropertyDescriptor(object, key)?.configurable) {
|
|
27
|
+
const value = object[key];
|
|
28
|
+
|
|
29
|
+
deepFreeze(value);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return Object.freeze(object);
|
|
34
|
+
};
|
package/src/getPathFromState.tsx
CHANGED
|
@@ -196,7 +196,12 @@ export function getPathFromState<ParamList extends {}>(
|
|
|
196
196
|
return '';
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
-
|
|
199
|
+
// Valid characters according to
|
|
200
|
+
// https://datatracker.ietf.org/doc/html/rfc3986#section-3.3 (see pchar definition)
|
|
201
|
+
return String(value).replace(
|
|
202
|
+
/[^A-Za-z0-9\-._~!$&'()*+,;=:@]/g,
|
|
203
|
+
(char) => encodeURIComponent(char)
|
|
204
|
+
);
|
|
200
205
|
}
|
|
201
206
|
|
|
202
207
|
return encodeURIComponent(p);
|
package/src/getStateFromPath.tsx
CHANGED
|
@@ -287,29 +287,73 @@ const matchAgainstConfigs = (remaining: string, configs: RouteConfig[]) => {
|
|
|
287
287
|
|
|
288
288
|
// If our regex matches, we need to extract params from the path
|
|
289
289
|
if (match) {
|
|
290
|
-
const
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
290
|
+
const matchResult = config.pattern?.split('/').reduce<{
|
|
291
|
+
pos: number; // Position of the current path param segment in the path (e.g in pattern `a/:b/:c`, `:a` is 0 and `:b` is 1)
|
|
292
|
+
matchedParams: Record<string, Record<string, string>>; // The extracted params
|
|
293
|
+
}>(
|
|
294
|
+
(acc, p, index) => {
|
|
295
|
+
if (!p.startsWith(':')) {
|
|
296
|
+
return acc;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Path parameter so increment position for the segment
|
|
300
|
+
acc.pos += 1;
|
|
301
|
+
|
|
302
|
+
const decodedParamSegment = decodeURIComponent(
|
|
303
|
+
// The param segments appear every second item starting from 2 in the regex match result
|
|
304
|
+
match![(acc.pos + 1) * 2]
|
|
305
|
+
// Remove trailing slash
|
|
306
|
+
.replace(/\/$/, '')
|
|
307
|
+
);
|
|
308
|
+
|
|
309
|
+
Object.assign(acc.matchedParams, {
|
|
310
|
+
[p]: Object.assign(acc.matchedParams[p] || {}, {
|
|
311
|
+
[index]: decodedParamSegment,
|
|
298
312
|
}),
|
|
299
|
-
|
|
300
|
-
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
return acc;
|
|
316
|
+
},
|
|
317
|
+
{ pos: -1, matchedParams: {} }
|
|
318
|
+
);
|
|
319
|
+
|
|
320
|
+
const matchedParams = matchResult.matchedParams || {};
|
|
301
321
|
|
|
302
322
|
routes = config.routeNames.map((name) => {
|
|
303
|
-
const
|
|
304
|
-
|
|
323
|
+
const routeConfig = configs.find((c) => {
|
|
324
|
+
// Check matching name AND pattern in case same screen is used at different levels in config
|
|
325
|
+
return c.screen === name && config.pattern.startsWith(c.pattern);
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
// Normalize pattern to remove any leading, trailing slashes, duplicate slashes etc.
|
|
329
|
+
const normalizedPath = routeConfig?.path
|
|
330
|
+
.split('/')
|
|
331
|
+
.filter(Boolean)
|
|
332
|
+
.join('/');
|
|
333
|
+
|
|
334
|
+
// Get the number of segments in the initial pattern
|
|
335
|
+
const numInitialSegments = routeConfig?.pattern
|
|
336
|
+
// Extract the prefix from the pattern by removing the ending path pattern (e.g pattern=`a/b/c/d` and normalizedPath=`c/d` becomes `a/b`)
|
|
337
|
+
.replace(new RegExp(`${escape(normalizedPath!)}$`), '')
|
|
338
|
+
?.split('/').length;
|
|
339
|
+
|
|
340
|
+
const params = normalizedPath
|
|
305
341
|
?.split('/')
|
|
306
|
-
.
|
|
307
|
-
|
|
308
|
-
|
|
342
|
+
.reduce<Record<string, unknown>>((acc, p, index) => {
|
|
343
|
+
if (!p.startsWith(':')) {
|
|
344
|
+
return acc;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Get the real index of the path parameter in the matched path
|
|
348
|
+
// by offsetting by the number of segments in the initial pattern
|
|
349
|
+
const offset = numInitialSegments ? numInitialSegments - 1 : 0;
|
|
350
|
+
const value = matchedParams[p]?.[index + offset];
|
|
309
351
|
|
|
310
352
|
if (value) {
|
|
311
353
|
const key = p.replace(/^:/, '').replace(/\?$/, '');
|
|
312
|
-
acc[key] =
|
|
354
|
+
acc[key] = routeConfig?.parse?.[key]
|
|
355
|
+
? routeConfig.parse[key](value)
|
|
356
|
+
: value;
|
|
313
357
|
}
|
|
314
358
|
|
|
315
359
|
return acc;
|
package/src/index.tsx
CHANGED