@react-navigation/core 8.0.0-alpha.23 → 8.0.0-alpha.24
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/NavigationBuilderContext.js.map +1 -1
- package/lib/module/StaticNavigation.js +1 -1
- package/lib/module/StaticNavigation.js.map +1 -1
- package/lib/module/createNavigatorFactory.js.map +1 -1
- package/lib/module/getPathFromState.js +87 -57
- package/lib/module/getPathFromState.js.map +1 -1
- package/lib/module/getStateFromPath.js +77 -46
- package/lib/module/getStateFromPath.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/types.js +13 -0
- package/lib/module/types.js.map +1 -1
- package/lib/module/useEventEmitter.js +4 -1
- package/lib/module/useEventEmitter.js.map +1 -1
- package/lib/module/useNavigationBuilder.js +1 -7
- package/lib/module/useNavigationBuilder.js.map +1 -1
- package/lib/module/useOnAction.js +4 -1
- package/lib/module/useOnAction.js.map +1 -1
- package/lib/module/useOnPreventRemove.js +35 -24
- package/lib/module/useOnPreventRemove.js.map +1 -1
- package/lib/module/useRoute.js.map +1 -1
- package/lib/module/validatePathConfig.js +50 -37
- package/lib/module/validatePathConfig.js.map +1 -1
- package/lib/typescript/src/NavigationBuilderContext.d.ts +2 -2
- package/lib/typescript/src/NavigationBuilderContext.d.ts.map +1 -1
- package/lib/typescript/src/StaticNavigation.d.ts +3 -3
- package/lib/typescript/src/StaticNavigation.d.ts.map +1 -1
- package/lib/typescript/src/createNavigatorFactory.d.ts +4 -2
- package/lib/typescript/src/createNavigatorFactory.d.ts.map +1 -1
- package/lib/typescript/src/getPathFromState.d.ts.map +1 -1
- package/lib/typescript/src/getStateFromPath.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 +66 -17
- package/lib/typescript/src/types.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/useNavigationBuilder.d.ts.map +1 -1
- package/lib/typescript/src/useOnAction.d.ts.map +1 -1
- package/lib/typescript/src/useOnPreventRemove.d.ts +2 -6
- package/lib/typescript/src/useOnPreventRemove.d.ts.map +1 -1
- package/lib/typescript/src/useRoute.d.ts +1 -1
- package/lib/typescript/src/useRoute.d.ts.map +1 -1
- package/lib/typescript/src/utilities.d.ts +4 -38
- package/lib/typescript/src/utilities.d.ts.map +1 -1
- package/lib/typescript/src/validatePathConfig.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/NavigationBuilderContext.tsx +5 -1
- package/src/StaticNavigation.tsx +7 -6
- package/src/createNavigatorFactory.tsx +23 -2
- package/src/getPathFromState.tsx +97 -66
- package/src/getStateFromPath.tsx +168 -142
- package/src/index.tsx +1 -0
- package/src/types.tsx +257 -33
- package/src/useEventEmitter.tsx +6 -1
- package/src/useNavigationBuilder.tsx +1 -8
- package/src/useOnAction.tsx +6 -2
- package/src/useOnPreventRemove.tsx +68 -36
- package/src/useRoute.tsx +3 -5
- package/src/utilities.tsx +8 -41
- package/src/validatePathConfig.tsx +85 -58
package/src/types.tsx
CHANGED
|
@@ -287,6 +287,45 @@ export class PrivateValueStore<T extends [any, any, any, any]> {
|
|
|
287
287
|
protected ''?: T;
|
|
288
288
|
}
|
|
289
289
|
|
|
290
|
+
type NavigatorLike =
|
|
291
|
+
| {
|
|
292
|
+
Navigator: React.ComponentType<any>;
|
|
293
|
+
Screen: unknown;
|
|
294
|
+
Group: unknown;
|
|
295
|
+
}
|
|
296
|
+
| {
|
|
297
|
+
config: unknown;
|
|
298
|
+
getComponent: () => React.ComponentType<any>;
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
type ParamListForNavigator<T extends {}> = T extends NavigatorLike
|
|
302
|
+
? T extends PrivateValueStore<[infer ParamList extends {}, any, any, any]>
|
|
303
|
+
? ParamList
|
|
304
|
+
: T
|
|
305
|
+
: T;
|
|
306
|
+
|
|
307
|
+
// Remove `undefined` before checking for nested navigator params.
|
|
308
|
+
// If nothing remains, avoid matching `never` against `NavigatorScreenParams`
|
|
309
|
+
type NestedNavigatorForScreenParams<T, Params = NotUndefined<T>> = [
|
|
310
|
+
Params,
|
|
311
|
+
] extends [never]
|
|
312
|
+
? never
|
|
313
|
+
: Params extends NavigatorScreenParams<infer Navigator>
|
|
314
|
+
? Navigator extends PrivateValueStore<[any, any, any, any]>
|
|
315
|
+
? Navigator extends NavigatorLike
|
|
316
|
+
? Navigator
|
|
317
|
+
: never
|
|
318
|
+
: never
|
|
319
|
+
: never;
|
|
320
|
+
|
|
321
|
+
export type NestedNavigatorsForParamList<ParamList extends {}> = {
|
|
322
|
+
[RouteName in keyof ParamList as NestedNavigatorForScreenParams<
|
|
323
|
+
ParamList[RouteName]
|
|
324
|
+
> extends never
|
|
325
|
+
? never
|
|
326
|
+
: RouteName]: NestedNavigatorForScreenParams<ParamList[RouteName]>;
|
|
327
|
+
};
|
|
328
|
+
|
|
290
329
|
type NavigateOptions = {
|
|
291
330
|
merge?: boolean | undefined;
|
|
292
331
|
pop?: boolean | undefined;
|
|
@@ -912,15 +951,19 @@ export type NavigationContainerEventMap = {
|
|
|
912
951
|
/**
|
|
913
952
|
* The data object passed when emitting the event.
|
|
914
953
|
*/
|
|
915
|
-
data
|
|
954
|
+
data?: unknown;
|
|
916
955
|
/**
|
|
917
956
|
* The key of the target route which received the event.
|
|
918
957
|
*/
|
|
919
|
-
target
|
|
958
|
+
target?: string | undefined;
|
|
920
959
|
/**
|
|
921
960
|
* Whether `event.preventDefault()` was called on this event.
|
|
922
961
|
*/
|
|
923
|
-
defaultPrevented
|
|
962
|
+
defaultPrevented?: boolean | undefined;
|
|
963
|
+
/**
|
|
964
|
+
* Prevent the default action which happens on this event.
|
|
965
|
+
*/
|
|
966
|
+
preventDefault?: (() => void) | undefined;
|
|
924
967
|
};
|
|
925
968
|
};
|
|
926
969
|
};
|
|
@@ -1000,8 +1043,8 @@ export type RouteForName<
|
|
|
1000
1043
|
// Look up route object by checking each level and recursing into the nested param lists
|
|
1001
1044
|
// This avoids building a union of all routes, which doesn't scale on large trees
|
|
1002
1045
|
type RouteForNameInternal<ParamList extends {}, RouteName extends string> =
|
|
1003
|
-
| (RouteName extends
|
|
1004
|
-
? RouteProp<ParamList,
|
|
1046
|
+
| (RouteName extends KeyOf<ParamList>
|
|
1047
|
+
? RouteProp<ParamList, RouteName>
|
|
1005
1048
|
: never)
|
|
1006
1049
|
| RouteForNameNested<NestedParamLists<ParamList>, RouteName>;
|
|
1007
1050
|
|
|
@@ -1010,11 +1053,7 @@ type RouteForNameNested<ParamLists, RouteName extends string> =
|
|
|
1010
1053
|
// e.g. if ParamLists is A | B
|
|
1011
1054
|
// TypeScript evaluates the branch once per member (A, then B)
|
|
1012
1055
|
// and unions the outcomes
|
|
1013
|
-
|
|
1014
|
-
// and re-asserts the {} constraint that RouteForNameInternal requires
|
|
1015
|
-
ParamLists extends infer ParamList extends {}
|
|
1016
|
-
? RouteForNameInternal<ParamList, RouteName>
|
|
1017
|
-
: never;
|
|
1056
|
+
ParamLists extends {} ? RouteForNameInternal<ParamLists, RouteName> : never;
|
|
1018
1057
|
|
|
1019
1058
|
/**
|
|
1020
1059
|
* Union of param lists of the nested navigators in a param list.
|
|
@@ -1022,7 +1061,7 @@ type RouteForNameNested<ParamLists, RouteName extends string> =
|
|
|
1022
1061
|
export type NestedParamLists<ParamList extends {}> = {
|
|
1023
1062
|
[RouteName in keyof ParamList]: NavigatorScreenParams<{}> extends ParamList[RouteName]
|
|
1024
1063
|
? NotUndefined<ParamList[RouteName]> extends NavigatorScreenParams<infer T>
|
|
1025
|
-
? T
|
|
1064
|
+
? ParamListForNavigator<T>
|
|
1026
1065
|
: never
|
|
1027
1066
|
: never;
|
|
1028
1067
|
}[keyof ParamList];
|
|
@@ -1030,7 +1069,9 @@ export type NestedParamLists<ParamList extends {}> = {
|
|
|
1030
1069
|
type ParamListRoute<ParamList extends {}> = {
|
|
1031
1070
|
[RouteName in keyof ParamList]: NavigatorScreenParams<{}> extends ParamList[RouteName]
|
|
1032
1071
|
? NotUndefined<ParamList[RouteName]> extends NavigatorScreenParams<infer T>
|
|
1033
|
-
?
|
|
1072
|
+
?
|
|
1073
|
+
| ParamListRoute<ParamListForNavigator<T>>
|
|
1074
|
+
| RouteProp<ParamList, RouteName>
|
|
1034
1075
|
: RouteProp<ParamList, RouteName>
|
|
1035
1076
|
: RouteProp<ParamList, RouteName>;
|
|
1036
1077
|
}[keyof ParamList];
|
|
@@ -1056,13 +1097,15 @@ type BasicNavigationList<
|
|
|
1056
1097
|
? NotUndefined<ParamList[RouteName]> extends NavigatorScreenParams<
|
|
1057
1098
|
infer T
|
|
1058
1099
|
>
|
|
1059
|
-
?
|
|
1060
|
-
?
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1100
|
+
? ParamListForNavigator<T> extends infer NestedParamList extends {}
|
|
1101
|
+
? keyof NestedParamList extends ExcludedRouteNames
|
|
1102
|
+
? {}
|
|
1103
|
+
: BasicNavigationList<
|
|
1104
|
+
NestedParamList,
|
|
1105
|
+
ExcludedRouteNames,
|
|
1106
|
+
NavigationProp<ParamList, RouteName>
|
|
1107
|
+
>
|
|
1108
|
+
: {}
|
|
1066
1109
|
: {}
|
|
1067
1110
|
: {}) &
|
|
1068
1111
|
(RouteName extends ExcludedRouteNames
|
|
@@ -1076,6 +1119,105 @@ type BasicNavigationList<
|
|
|
1076
1119
|
}[keyof ParamList]
|
|
1077
1120
|
>;
|
|
1078
1121
|
|
|
1122
|
+
type InheritedParentParams<ParentParamList, ParamList> = {
|
|
1123
|
+
[K in keyof ParentParamList as K extends keyof ParamList
|
|
1124
|
+
? never
|
|
1125
|
+
: string extends K
|
|
1126
|
+
? never
|
|
1127
|
+
: K]: ParentParamList[K];
|
|
1128
|
+
};
|
|
1129
|
+
|
|
1130
|
+
type GenericNavigationComposite<
|
|
1131
|
+
ParamList extends ParamListBase,
|
|
1132
|
+
RouteName extends keyof ParamList,
|
|
1133
|
+
Parent,
|
|
1134
|
+
> =
|
|
1135
|
+
Parent extends NavigationProp<any, any, any, any, any>
|
|
1136
|
+
? ParamListOfNavigationProp<Parent> extends infer ParentParamList
|
|
1137
|
+
? NavigationProp<
|
|
1138
|
+
ParamList & InheritedParentParams<ParentParamList, ParamList>,
|
|
1139
|
+
RouteName
|
|
1140
|
+
> & { getParent: Parent['getParent'] }
|
|
1141
|
+
: never
|
|
1142
|
+
: NavigationProp<ParamList, RouteName>;
|
|
1143
|
+
|
|
1144
|
+
type NavigationListForScreenParams<
|
|
1145
|
+
T extends {},
|
|
1146
|
+
ParamList extends ParamListBase,
|
|
1147
|
+
RouteName extends keyof ParamList,
|
|
1148
|
+
ExcludedRouteNames,
|
|
1149
|
+
Parent extends NavigationProp<any, any, any, any, any> | undefined,
|
|
1150
|
+
> =
|
|
1151
|
+
T extends PrivateValueStore<[any, any, any, any]>
|
|
1152
|
+
? T extends NavigatorLike
|
|
1153
|
+
? NavigationListForNestedInternal<
|
|
1154
|
+
T,
|
|
1155
|
+
GenericNavigationComposite<ParamList, RouteName, Parent>
|
|
1156
|
+
>
|
|
1157
|
+
: NavigationListForParamListScreenParams<
|
|
1158
|
+
T,
|
|
1159
|
+
ParamList,
|
|
1160
|
+
RouteName,
|
|
1161
|
+
ExcludedRouteNames,
|
|
1162
|
+
Parent
|
|
1163
|
+
>
|
|
1164
|
+
: NavigationListForParamListScreenParams<
|
|
1165
|
+
T,
|
|
1166
|
+
ParamList,
|
|
1167
|
+
RouteName,
|
|
1168
|
+
ExcludedRouteNames,
|
|
1169
|
+
Parent
|
|
1170
|
+
>;
|
|
1171
|
+
|
|
1172
|
+
type NavigationListForParamListScreenParams<
|
|
1173
|
+
T extends {},
|
|
1174
|
+
ParamList extends ParamListBase,
|
|
1175
|
+
RouteName extends keyof ParamList,
|
|
1176
|
+
ExcludedRouteNames,
|
|
1177
|
+
Parent extends NavigationProp<any, any, any, any, any> | undefined,
|
|
1178
|
+
> =
|
|
1179
|
+
// `T` is only ever a plain param list here, since navigators are routed to
|
|
1180
|
+
// `NavigationListForNestedInternal` by `NavigationListForScreenParams`.
|
|
1181
|
+
// So there's no navigator to unwrap with `ParamListForNavigator`.
|
|
1182
|
+
T extends ParamListBase
|
|
1183
|
+
? BasicNavigationListForParamList<
|
|
1184
|
+
T,
|
|
1185
|
+
ExcludedRouteNames,
|
|
1186
|
+
GenericNavigationComposite<ParamList, RouteName, Parent>
|
|
1187
|
+
>
|
|
1188
|
+
: {};
|
|
1189
|
+
|
|
1190
|
+
type BasicNavigationListForParamList<
|
|
1191
|
+
ParamList extends ParamListBase,
|
|
1192
|
+
ExcludedRouteNames,
|
|
1193
|
+
Parent extends NavigationProp<any, any, any, any, any> | undefined,
|
|
1194
|
+
> = UnionToIntersection<
|
|
1195
|
+
{
|
|
1196
|
+
[RouteName in keyof ParamList]: (NavigatorScreenParams<{}> extends ParamList[RouteName]
|
|
1197
|
+
? NotUndefined<ParamList[RouteName]> extends NavigatorScreenParams<
|
|
1198
|
+
infer T
|
|
1199
|
+
>
|
|
1200
|
+
? NavigationListForScreenParams<
|
|
1201
|
+
T,
|
|
1202
|
+
ParamList,
|
|
1203
|
+
RouteName,
|
|
1204
|
+
ExcludedRouteNames,
|
|
1205
|
+
Parent
|
|
1206
|
+
>
|
|
1207
|
+
: {}
|
|
1208
|
+
: {}) &
|
|
1209
|
+
(RouteName extends ExcludedRouteNames
|
|
1210
|
+
? {}
|
|
1211
|
+
: {
|
|
1212
|
+
[Key in RouteName]: GenericNavigationComposite<
|
|
1213
|
+
ParamList,
|
|
1214
|
+
RouteName,
|
|
1215
|
+
Parent
|
|
1216
|
+
>;
|
|
1217
|
+
});
|
|
1218
|
+
}[keyof ParamList]
|
|
1219
|
+
>;
|
|
1220
|
+
|
|
1079
1221
|
export type NavigationListForNavigator<Navigator> =
|
|
1080
1222
|
Navigator extends PrivateValueStore<infer Value> ? Value[1] : {};
|
|
1081
1223
|
|
|
@@ -1094,13 +1236,14 @@ type NavigationListForNestedInternal<
|
|
|
1094
1236
|
Parent = undefined,
|
|
1095
1237
|
NavigatorList extends Record<string, any> =
|
|
1096
1238
|
NavigationListForNavigator<Navigator>,
|
|
1239
|
+
Navigators = NestedNavigatorsOf<Navigator>,
|
|
1097
1240
|
// This navigator's own routes, each composed with the accumulated parent.
|
|
1098
1241
|
// It's threaded into the recursion as the parent for nested navigators so
|
|
1099
1242
|
// each route is composed with its ancestors exactly once, instead of
|
|
1100
1243
|
// re-wrapping the whole descendant list at every level (which is quadratic
|
|
1101
1244
|
// in the nesting depth).
|
|
1102
1245
|
ComposedList = ComposeNavigationList<NavigatorList, Parent>,
|
|
1103
|
-
> = Navigator extends {
|
|
1246
|
+
> = (Navigator extends {
|
|
1104
1247
|
readonly config: {
|
|
1105
1248
|
readonly screens?: infer Screens;
|
|
1106
1249
|
readonly groups?: infer Groups;
|
|
@@ -1109,7 +1252,69 @@ type NavigationListForNestedInternal<
|
|
|
1109
1252
|
? ComposedList &
|
|
1110
1253
|
NavigationListForScreens<ComposedList, Screens> &
|
|
1111
1254
|
NavigationListForGroups<ComposedList, Groups>
|
|
1112
|
-
: ComposedList
|
|
1255
|
+
: ComposedList) &
|
|
1256
|
+
NavigationListForNestedNavigators<ComposedList, Navigators> &
|
|
1257
|
+
NavigationListForDynamicNestedParamLists<Navigator, ComposedList, Navigators>;
|
|
1258
|
+
|
|
1259
|
+
type NavigationListForDynamicNestedParamLists<
|
|
1260
|
+
Navigator,
|
|
1261
|
+
ParentList,
|
|
1262
|
+
Navigators,
|
|
1263
|
+
> = Navigator extends { readonly config: unknown }
|
|
1264
|
+
? {}
|
|
1265
|
+
: Navigator extends PrivateValueStore<[infer ParamList, any, any, any]>
|
|
1266
|
+
? NavigationListForNestedParamLists<ParentList, ParamList, Navigators>
|
|
1267
|
+
: {};
|
|
1268
|
+
|
|
1269
|
+
// Map of route name to nested navigator type
|
|
1270
|
+
// inferred from `NavigatorScreenParams<typeof Navigator>`
|
|
1271
|
+
type NestedNavigatorsOf<Navigator> =
|
|
1272
|
+
Navigator extends PrivateValueStore<[any, any, any, infer Nesting]>
|
|
1273
|
+
? Nesting extends Record<string, any>
|
|
1274
|
+
? Nesting
|
|
1275
|
+
: {}
|
|
1276
|
+
: {};
|
|
1277
|
+
|
|
1278
|
+
// Like `NavigationListForScreens`, but reads nested navigators from the brand
|
|
1279
|
+
// map instead of a static config.
|
|
1280
|
+
type NavigationListForNestedNavigators<ParentList, Navigators> =
|
|
1281
|
+
UnionToIntersection<
|
|
1282
|
+
{
|
|
1283
|
+
[K in keyof Navigators]: K extends keyof ParentList
|
|
1284
|
+
? NavigationListForNestedInternal<Navigators[K], ParentList[K]>
|
|
1285
|
+
: {};
|
|
1286
|
+
}[keyof Navigators]
|
|
1287
|
+
>;
|
|
1288
|
+
|
|
1289
|
+
// Fallback for dynamic nested routes declared through NavigatorScreenParams<ParamList>.
|
|
1290
|
+
// Param-list branches expose generic navigation props, while nested navigator
|
|
1291
|
+
// entries still recover their concrete navigator props.
|
|
1292
|
+
type NavigationListForNestedParamLists<ParentList, ParamList, Navigators> =
|
|
1293
|
+
ParentList extends Record<string, any>
|
|
1294
|
+
? ParamList extends ParamListBase
|
|
1295
|
+
? UnionToIntersection<
|
|
1296
|
+
{
|
|
1297
|
+
[K in keyof ParamList]: K extends keyof Navigators
|
|
1298
|
+
? {}
|
|
1299
|
+
: K extends keyof ParentList
|
|
1300
|
+
? NavigatorScreenParams<{}> extends ParamList[K]
|
|
1301
|
+
? NotUndefined<ParamList[K]> extends NavigatorScreenParams<
|
|
1302
|
+
infer T
|
|
1303
|
+
>
|
|
1304
|
+
? NavigationListForScreenParams<
|
|
1305
|
+
T,
|
|
1306
|
+
ParamList,
|
|
1307
|
+
K,
|
|
1308
|
+
keyof ParentList,
|
|
1309
|
+
ParentList[K]
|
|
1310
|
+
>
|
|
1311
|
+
: {}
|
|
1312
|
+
: {}
|
|
1313
|
+
: {};
|
|
1314
|
+
}[keyof ParamList]
|
|
1315
|
+
>
|
|
1316
|
+
: {}
|
|
1317
|
+
: {};
|
|
1113
1318
|
|
|
1114
1319
|
// Compose every entry in a navigator's list with the accumulated parent.
|
|
1115
1320
|
// When there's no parent (root navigator), the list is returned as-is so the
|
|
@@ -1270,6 +1475,7 @@ type TypedNavigatorStatic<
|
|
|
1270
1475
|
export type TypedNavigator<
|
|
1271
1476
|
Bag extends NavigatorTypeBagBase,
|
|
1272
1477
|
Config = unknown,
|
|
1478
|
+
Nesting = unknown,
|
|
1273
1479
|
> = (undefined extends Config
|
|
1274
1480
|
? TypedNavigatorInternal<
|
|
1275
1481
|
Bag['ParamList'],
|
|
@@ -1281,7 +1487,7 @@ export type TypedNavigator<
|
|
|
1281
1487
|
>
|
|
1282
1488
|
: TypedNavigatorStatic<Bag, Config>) &
|
|
1283
1489
|
PrivateValueStore<
|
|
1284
|
-
[Bag['ParamList'], Bag['NavigationList'], unknown,
|
|
1490
|
+
[Bag['ParamList'], Bag['NavigationList'], unknown, Nesting]
|
|
1285
1491
|
>;
|
|
1286
1492
|
|
|
1287
1493
|
type TypedNavigatorInternal<
|
|
@@ -1329,7 +1535,17 @@ type TypedNavigatorInternal<
|
|
|
1329
1535
|
) => null;
|
|
1330
1536
|
};
|
|
1331
1537
|
|
|
1332
|
-
|
|
1538
|
+
declare const NavigatorScreenParamsSymbol: unique symbol;
|
|
1539
|
+
|
|
1540
|
+
type NavigatorScreenParamsBrand<T extends {}> = {
|
|
1541
|
+
// Preserve the original generic for inference without affecting assignability.
|
|
1542
|
+
// - The symbol key hides the property from normal object usage
|
|
1543
|
+
// - The actual type is intersected for inference
|
|
1544
|
+
// - The `any` makes the property effectively `any` for assignability
|
|
1545
|
+
readonly [NavigatorScreenParamsSymbol]?: any & { readonly type: T };
|
|
1546
|
+
};
|
|
1547
|
+
|
|
1548
|
+
type NavigatorScreenParamsForParamList<ParamList extends {}> =
|
|
1333
1549
|
| {
|
|
1334
1550
|
screen?: never;
|
|
1335
1551
|
params?: never;
|
|
@@ -1364,6 +1580,10 @@ export type NavigatorScreenParams<ParamList extends {}> =
|
|
|
1364
1580
|
};
|
|
1365
1581
|
}[keyof ParamList];
|
|
1366
1582
|
|
|
1583
|
+
export type NavigatorScreenParams<ParamList extends {}> =
|
|
1584
|
+
NavigatorScreenParamsForParamList<ParamListForNavigator<ParamList>> &
|
|
1585
|
+
NavigatorScreenParamsBrand<ParamList>;
|
|
1586
|
+
|
|
1367
1587
|
type ParseConfig<Params> = {
|
|
1368
1588
|
[K in keyof Params]?:
|
|
1369
1589
|
| ((value: string) => Params[K])
|
|
@@ -1431,16 +1651,20 @@ export type PathConfig<Params> = FlatType<
|
|
|
1431
1651
|
*/
|
|
1432
1652
|
alias?: (string | PathConfigAlias<Params>)[] | undefined;
|
|
1433
1653
|
} & (NonNullable<Params> extends NavigatorScreenParams<infer ParamList>
|
|
1434
|
-
? {
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1654
|
+
? ParamListForNavigator<ParamList> extends infer ChildParamList extends {}
|
|
1655
|
+
? {
|
|
1656
|
+
/**
|
|
1657
|
+
* Path configuration for child screens.
|
|
1658
|
+
*/
|
|
1659
|
+
screens?: PathConfigMap<ChildParamList> | undefined;
|
|
1660
|
+
/**
|
|
1661
|
+
* Name of the initial route to use for the navigator when the path matches.
|
|
1662
|
+
*/
|
|
1663
|
+
initialRouteName?:
|
|
1664
|
+
| Extract<keyof ChildParamList, string>
|
|
1665
|
+
| undefined;
|
|
1666
|
+
}
|
|
1667
|
+
: {}
|
|
1444
1668
|
: {})
|
|
1445
1669
|
>;
|
|
1446
1670
|
|
package/src/useEventEmitter.tsx
CHANGED
|
@@ -13,12 +13,15 @@ type Listeners = Set<(e: any) => void>;
|
|
|
13
13
|
* Hook to manage the event system used by the navigator to notify screens of various events.
|
|
14
14
|
*/
|
|
15
15
|
export function useEventEmitter<T extends Record<string, any>>(
|
|
16
|
-
listen?: (e: any) => void
|
|
16
|
+
listen?: (e: any) => void,
|
|
17
|
+
onPostEmit?: (e: any) => void
|
|
17
18
|
): NavigationEventEmitter<T> {
|
|
18
19
|
const listenRef = React.useRef(listen);
|
|
20
|
+
const onPostEmitRef = React.useRef(onPostEmit);
|
|
19
21
|
|
|
20
22
|
React.useEffect(() => {
|
|
21
23
|
listenRef.current = listen;
|
|
24
|
+
onPostEmitRef.current = onPostEmit;
|
|
22
25
|
});
|
|
23
26
|
|
|
24
27
|
const listeners = React.useRef<Record<string, Record<string, Listeners>>>(
|
|
@@ -124,6 +127,8 @@ export function useEventEmitter<T extends Record<string, any>>(
|
|
|
124
127
|
|
|
125
128
|
callbacks?.forEach((cb) => cb(event));
|
|
126
129
|
|
|
130
|
+
onPostEmitRef.current?.(event);
|
|
131
|
+
|
|
127
132
|
return event as any;
|
|
128
133
|
},
|
|
129
134
|
[]
|
|
@@ -877,14 +877,7 @@ export function useNavigationBuilder<
|
|
|
877
877
|
|
|
878
878
|
listeners.forEach((listener) => listener?.(e));
|
|
879
879
|
}
|
|
880
|
-
|
|
881
|
-
onEmitEvent({
|
|
882
|
-
type: e.type,
|
|
883
|
-
data: e.data,
|
|
884
|
-
target: e.target,
|
|
885
|
-
defaultPrevented: e.defaultPrevented,
|
|
886
|
-
});
|
|
887
|
-
});
|
|
880
|
+
}, onEmitEvent);
|
|
888
881
|
|
|
889
882
|
useFocusEvents({ state, emitter });
|
|
890
883
|
|
package/src/useOnAction.tsx
CHANGED
|
@@ -88,8 +88,6 @@ export function useOnAction<State extends NavigationState>({
|
|
|
88
88
|
result === null && action.target === state.key ? state : result;
|
|
89
89
|
|
|
90
90
|
if (result !== null) {
|
|
91
|
-
onDispatchAction(action, state === result);
|
|
92
|
-
|
|
93
91
|
if (state !== result) {
|
|
94
92
|
const isPrevented = shouldPreventRemove(
|
|
95
93
|
emitter,
|
|
@@ -100,10 +98,16 @@ export function useOnAction<State extends NavigationState>({
|
|
|
100
98
|
);
|
|
101
99
|
|
|
102
100
|
if (isPrevented) {
|
|
101
|
+
onDispatchAction(action, true);
|
|
102
|
+
|
|
103
103
|
return true;
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
+
onDispatchAction(action, false);
|
|
107
|
+
|
|
106
108
|
setState(result);
|
|
109
|
+
} else {
|
|
110
|
+
onDispatchAction(action, true);
|
|
107
111
|
}
|
|
108
112
|
|
|
109
113
|
if (onRouteFocusParent !== undefined) {
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
NavigationAction,
|
|
3
|
+
NavigationRoute,
|
|
3
4
|
NavigationState,
|
|
5
|
+
ParamListBase,
|
|
6
|
+
PartialRoute,
|
|
4
7
|
} from '@react-navigation/routers';
|
|
5
8
|
import * as React from 'react';
|
|
6
9
|
|
|
@@ -23,16 +26,18 @@ const VISITED_ROUTE_KEYS = Symbol('VISITED_ROUTE_KEYS');
|
|
|
23
26
|
export const shouldPreventRemove = (
|
|
24
27
|
emitter: NavigationEventEmitter<EventMapCore<any>>,
|
|
25
28
|
beforeRemoveListeners: Record<string, ChildBeforeRemoveListener | undefined>,
|
|
26
|
-
currentRoutes:
|
|
27
|
-
nextRoutes:
|
|
29
|
+
currentRoutes: NavigationRoute<ParamListBase, string>[],
|
|
30
|
+
nextRoutes: (
|
|
31
|
+
| NavigationRoute<ParamListBase, string>
|
|
32
|
+
| PartialRoute<NavigationRoute<ParamListBase, string>>
|
|
33
|
+
)[],
|
|
28
34
|
action: NavigationAction
|
|
29
35
|
) => {
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
.reverse();
|
|
36
|
+
const nextRoutesByKey = new Map(
|
|
37
|
+
nextRoutes
|
|
38
|
+
.map((route) => [route.key, route] as const)
|
|
39
|
+
.filter(([, route]) => route.key != null)
|
|
40
|
+
);
|
|
36
41
|
|
|
37
42
|
const visitedRouteKeys: Set<string> =
|
|
38
43
|
// @ts-expect-error: add this property to mark that we've already emitted this action
|
|
@@ -43,30 +48,53 @@ export const shouldPreventRemove = (
|
|
|
43
48
|
[VISITED_ROUTE_KEYS]: visitedRouteKeys,
|
|
44
49
|
};
|
|
45
50
|
|
|
46
|
-
|
|
51
|
+
// Call these in reverse order so last screens handle the event first
|
|
52
|
+
const reversedCurrentRoutes = [...currentRoutes].reverse();
|
|
53
|
+
|
|
54
|
+
for (const route of reversedCurrentRoutes) {
|
|
47
55
|
if (visitedRouteKeys.has(route.key)) {
|
|
48
56
|
// Skip if we've already emitted this action for this screen
|
|
49
57
|
continue;
|
|
50
58
|
}
|
|
51
59
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
+
if (!nextRoutesByKey.has(route.key)) {
|
|
61
|
+
// The route is not in next state, so it's being removed
|
|
62
|
+
// First, we need to check if any child screens want to prevent it
|
|
63
|
+
const isPrevented = beforeRemoveListeners[route.key]?.(
|
|
64
|
+
beforeRemoveAction,
|
|
65
|
+
undefined
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
if (isPrevented) {
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
visitedRouteKeys.add(route.key);
|
|
73
|
+
|
|
74
|
+
const event = emitter.emit({
|
|
75
|
+
type: 'beforeRemove',
|
|
76
|
+
target: route.key,
|
|
77
|
+
data: { action: beforeRemoveAction },
|
|
78
|
+
canPreventDefault: true,
|
|
79
|
+
});
|
|
60
80
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
81
|
+
if (event.defaultPrevented) {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
} else {
|
|
85
|
+
// The route is kept but its nested state changed, so propagate the check into the nested navigator
|
|
86
|
+
const nextRoute = nextRoutesByKey.get(route.key);
|
|
87
|
+
|
|
88
|
+
if (route.state != null && route.state !== nextRoute?.state) {
|
|
89
|
+
const isPrevented = beforeRemoveListeners[route.key]?.(
|
|
90
|
+
beforeRemoveAction,
|
|
91
|
+
nextRoute?.state
|
|
92
|
+
);
|
|
67
93
|
|
|
68
|
-
|
|
69
|
-
|
|
94
|
+
if (isPrevented) {
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
70
98
|
}
|
|
71
99
|
}
|
|
72
100
|
|
|
@@ -84,17 +112,21 @@ export function useOnPreventRemove({
|
|
|
84
112
|
|
|
85
113
|
React.useInsertionEffect(() => {
|
|
86
114
|
if (routeKey) {
|
|
87
|
-
return addKeyedListener?.(
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
115
|
+
return addKeyedListener?.(
|
|
116
|
+
'beforeRemove',
|
|
117
|
+
routeKey,
|
|
118
|
+
(action, nextState) => {
|
|
119
|
+
const state = getState();
|
|
120
|
+
|
|
121
|
+
return shouldPreventRemove(
|
|
122
|
+
emitter,
|
|
123
|
+
beforeRemoveListeners,
|
|
124
|
+
state.routes,
|
|
125
|
+
nextState?.routes ?? [],
|
|
126
|
+
action
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
);
|
|
98
130
|
}
|
|
99
131
|
}, [addKeyedListener, beforeRemoveListeners, emitter, getState, routeKey]);
|
|
100
132
|
}
|
package/src/useRoute.tsx
CHANGED
|
@@ -22,11 +22,9 @@ type AllRouteNames<ParamList extends {}> =
|
|
|
22
22
|
| KeyOf<ParamList>
|
|
23
23
|
| AllNestedRouteNames<NestedParamLists<ParamList>>;
|
|
24
24
|
|
|
25
|
-
type AllNestedRouteNames<ParamLists> =
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
? AllRouteNames<ParamList>
|
|
29
|
-
: never;
|
|
25
|
+
type AllNestedRouteNames<ParamLists> = ParamLists extends {}
|
|
26
|
+
? AllRouteNames<ParamLists>
|
|
27
|
+
: never;
|
|
30
28
|
|
|
31
29
|
/**
|
|
32
30
|
* Hook to access the route prop of the parent screen anywhere.
|
package/src/utilities.tsx
CHANGED
|
@@ -25,8 +25,6 @@ export type UnionToIntersection<U> = (
|
|
|
25
25
|
? I
|
|
26
26
|
: never;
|
|
27
27
|
|
|
28
|
-
export type UnknownToUndefined<T> = unknown extends T ? undefined : T;
|
|
29
|
-
|
|
30
28
|
/**
|
|
31
29
|
* Exclude undefined from a type.
|
|
32
30
|
* Similar to NonNullable but only excludes undefined, not null.
|
|
@@ -173,46 +171,15 @@ type QueryParamRequiredKeys<Params, Parse> = Exclude<
|
|
|
173
171
|
QueryParamOptionalKeys<Params, Parse>
|
|
174
172
|
>;
|
|
175
173
|
|
|
176
|
-
/**
|
|
177
|
-
* Infer the path string from a linking config.
|
|
178
|
-
*/
|
|
179
|
-
export type InferPath<T> = T extends { path: infer P extends string }
|
|
180
|
-
? P
|
|
181
|
-
: never;
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Infer the parse functions from a linking config.
|
|
185
|
-
*/
|
|
186
|
-
export type InferParse<T> = T extends { parse: infer P } ? P : {};
|
|
187
|
-
|
|
188
174
|
export type InferParamsFromLinking<T> = T extends {
|
|
189
175
|
path: infer P extends string;
|
|
176
|
+
parse: infer Parse;
|
|
190
177
|
}
|
|
191
|
-
? UndefinedIfAllOptional<
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
? UndefinedIfAllOptional<
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
: undefined;
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Infer the params type from a screen component or nested navigator.
|
|
202
|
-
*/
|
|
203
|
-
export type InferScreenParams<T> =
|
|
204
|
-
T extends React.ComponentType<{ route: { params: infer P } }>
|
|
205
|
-
? P
|
|
206
|
-
: T extends { config: { screens: infer Screens } }
|
|
207
|
-
? import('./types').NavigatorScreenParams<{
|
|
208
|
-
[K in keyof Screens]: Screens[K] extends React.ComponentType<{
|
|
209
|
-
route: { params: infer P };
|
|
210
|
-
}>
|
|
211
|
-
? P
|
|
212
|
-
: Screens[K] extends { screen: infer S }
|
|
213
|
-
? S extends React.ComponentType<{ route: { params: infer P } }>
|
|
214
|
-
? P
|
|
215
|
-
: undefined
|
|
216
|
-
: undefined;
|
|
217
|
-
}>
|
|
178
|
+
? UndefinedIfAllOptional<ExtractParamsType<ExtractParamStrings<P>, Parse>>
|
|
179
|
+
: T extends {
|
|
180
|
+
path: infer P extends string;
|
|
181
|
+
}
|
|
182
|
+
? UndefinedIfAllOptional<ExtractParamStrings<P>>
|
|
183
|
+
: T extends string
|
|
184
|
+
? UndefinedIfAllOptional<ExtractParamStrings<T>>
|
|
218
185
|
: undefined;
|