@react-navigation/core 8.0.0-alpha.23 → 8.0.0-alpha.25

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.
Files changed (153) hide show
  1. package/lib/module/BaseNavigationContainer.js +5 -2
  2. package/lib/module/BaseNavigationContainer.js.map +1 -1
  3. package/lib/module/DataLoading.js +102 -0
  4. package/lib/module/DataLoading.js.map +1 -0
  5. package/lib/module/NavigationBuilderContext.js.map +1 -1
  6. package/lib/module/NavigationIndependentTree.js +7 -6
  7. package/lib/module/NavigationIndependentTree.js.map +1 -1
  8. package/lib/module/NavigationProvider.js +12 -12
  9. package/lib/module/NavigationProvider.js.map +1 -1
  10. package/lib/module/PreventRemoveContext.js.map +1 -1
  11. package/lib/module/PreventRemoveProvider.js +34 -24
  12. package/lib/module/PreventRemoveProvider.js.map +1 -1
  13. package/lib/module/StaticNavigation.js +15 -7
  14. package/lib/module/StaticNavigation.js.map +1 -1
  15. package/lib/module/StaticTreeContext.js +5 -0
  16. package/lib/module/StaticTreeContext.js.map +1 -0
  17. package/lib/module/checkSerializable.js +7 -9
  18. package/lib/module/checkSerializable.js.map +1 -1
  19. package/lib/module/createNavigationContainerRef.js +6 -8
  20. package/lib/module/createNavigationContainerRef.js.map +1 -1
  21. package/lib/module/createNavigatorFactory.js.map +1 -1
  22. package/lib/module/getActionFromState.js +11 -11
  23. package/lib/module/getActionFromState.js.map +1 -1
  24. package/lib/module/getPathFromState.js +125 -96
  25. package/lib/module/getPathFromState.js.map +1 -1
  26. package/lib/module/getPatternParts.js +2 -2
  27. package/lib/module/getPatternParts.js.map +1 -1
  28. package/lib/module/getStateFromPath.js +136 -78
  29. package/lib/module/getStateFromPath.js.map +1 -1
  30. package/lib/module/index.js +1 -0
  31. package/lib/module/index.js.map +1 -1
  32. package/lib/module/types.js +13 -0
  33. package/lib/module/types.js.map +1 -1
  34. package/lib/module/useEventEmitter.js +5 -2
  35. package/lib/module/useEventEmitter.js.map +1 -1
  36. package/lib/module/useKeyedChildListeners.js +4 -2
  37. package/lib/module/useKeyedChildListeners.js.map +1 -1
  38. package/lib/module/useNavigation.js +2 -15
  39. package/lib/module/useNavigation.js.map +1 -1
  40. package/lib/module/useNavigationBuilder.js +5 -21
  41. package/lib/module/useNavigationBuilder.js.map +1 -1
  42. package/lib/module/useNavigationCache.js +19 -14
  43. package/lib/module/useNavigationCache.js.map +1 -1
  44. package/lib/module/useNavigationHelpers.js +27 -9
  45. package/lib/module/useNavigationHelpers.js.map +1 -1
  46. package/lib/module/useNavigationState.js +69 -36
  47. package/lib/module/useNavigationState.js.map +1 -1
  48. package/lib/module/useOnAction.js +25 -3
  49. package/lib/module/useOnAction.js.map +1 -1
  50. package/lib/module/useOnPreventRemove.js +35 -24
  51. package/lib/module/useOnPreventRemove.js.map +1 -1
  52. package/lib/module/useOptionsGetters.js +3 -1
  53. package/lib/module/useOptionsGetters.js.map +1 -1
  54. package/lib/module/usePreventRemove.js +9 -2
  55. package/lib/module/usePreventRemove.js.map +1 -1
  56. package/lib/module/useRoute.js.map +1 -1
  57. package/lib/module/useRouteCache.js +14 -7
  58. package/lib/module/useRouteCache.js.map +1 -1
  59. package/lib/module/useScheduleUpdate.js +8 -8
  60. package/lib/module/useScheduleUpdate.js.map +1 -1
  61. package/lib/module/useSyncState.js +4 -1
  62. package/lib/module/useSyncState.js.map +1 -1
  63. package/lib/module/validatePathConfig.js +50 -37
  64. package/lib/module/validatePathConfig.js.map +1 -1
  65. package/lib/typescript/src/BaseNavigationContainer.d.ts.map +1 -1
  66. package/lib/typescript/src/DataLoading.d.ts +20 -0
  67. package/lib/typescript/src/DataLoading.d.ts.map +1 -0
  68. package/lib/typescript/src/NavigationBuilderContext.d.ts +2 -2
  69. package/lib/typescript/src/NavigationBuilderContext.d.ts.map +1 -1
  70. package/lib/typescript/src/NavigationProvider.d.ts +0 -1
  71. package/lib/typescript/src/NavigationProvider.d.ts.map +1 -1
  72. package/lib/typescript/src/PreventRemoveContext.d.ts +1 -0
  73. package/lib/typescript/src/PreventRemoveContext.d.ts.map +1 -1
  74. package/lib/typescript/src/PreventRemoveProvider.d.ts.map +1 -1
  75. package/lib/typescript/src/StaticNavigation.d.ts +68 -42
  76. package/lib/typescript/src/StaticNavigation.d.ts.map +1 -1
  77. package/lib/typescript/src/StaticTreeContext.d.ts +4 -0
  78. package/lib/typescript/src/StaticTreeContext.d.ts.map +1 -0
  79. package/lib/typescript/src/checkSerializable.d.ts +4 -2
  80. package/lib/typescript/src/checkSerializable.d.ts.map +1 -1
  81. package/lib/typescript/src/createNavigationContainerRef.d.ts.map +1 -1
  82. package/lib/typescript/src/createNavigatorFactory.d.ts +11 -5
  83. package/lib/typescript/src/createNavigatorFactory.d.ts.map +1 -1
  84. package/lib/typescript/src/getActionFromState.d.ts.map +1 -1
  85. package/lib/typescript/src/getPathFromState.d.ts.map +1 -1
  86. package/lib/typescript/src/getStateFromPath.d.ts.map +1 -1
  87. package/lib/typescript/src/index.d.ts +2 -1
  88. package/lib/typescript/src/index.d.ts.map +1 -1
  89. package/lib/typescript/src/types.d.ts +84 -29
  90. package/lib/typescript/src/types.d.ts.map +1 -1
  91. package/lib/typescript/src/useEventEmitter.d.ts +1 -1
  92. package/lib/typescript/src/useEventEmitter.d.ts.map +1 -1
  93. package/lib/typescript/src/useKeyedChildListeners.d.ts.map +1 -1
  94. package/lib/typescript/src/useNavigation.d.ts.map +1 -1
  95. package/lib/typescript/src/useNavigationBuilder.d.ts +1 -1
  96. package/lib/typescript/src/useNavigationBuilder.d.ts.map +1 -1
  97. package/lib/typescript/src/useNavigationCache.d.ts.map +1 -1
  98. package/lib/typescript/src/useNavigationHelpers.d.ts +3 -4
  99. package/lib/typescript/src/useNavigationHelpers.d.ts.map +1 -1
  100. package/lib/typescript/src/useNavigationState.d.ts +11 -1
  101. package/lib/typescript/src/useNavigationState.d.ts.map +1 -1
  102. package/lib/typescript/src/useOnAction.d.ts.map +1 -1
  103. package/lib/typescript/src/useOnPreventRemove.d.ts +2 -6
  104. package/lib/typescript/src/useOnPreventRemove.d.ts.map +1 -1
  105. package/lib/typescript/src/useOptionsGetters.d.ts.map +1 -1
  106. package/lib/typescript/src/usePreventRemove.d.ts.map +1 -1
  107. package/lib/typescript/src/usePreventRemoveContext.d.ts +1 -0
  108. package/lib/typescript/src/usePreventRemoveContext.d.ts.map +1 -1
  109. package/lib/typescript/src/useRoute.d.ts +1 -1
  110. package/lib/typescript/src/useRoute.d.ts.map +1 -1
  111. package/lib/typescript/src/useRouteCache.d.ts.map +1 -1
  112. package/lib/typescript/src/useScheduleUpdate.d.ts +5 -4
  113. package/lib/typescript/src/useScheduleUpdate.d.ts.map +1 -1
  114. package/lib/typescript/src/useSyncState.d.ts.map +1 -1
  115. package/lib/typescript/src/utilities.d.ts +21 -38
  116. package/lib/typescript/src/utilities.d.ts.map +1 -1
  117. package/lib/typescript/src/validatePathConfig.d.ts.map +1 -1
  118. package/package.json +6 -8
  119. package/src/BaseNavigationContainer.tsx +9 -2
  120. package/src/DataLoading.tsx +139 -0
  121. package/src/NavigationBuilderContext.tsx +5 -1
  122. package/src/NavigationIndependentTree.tsx +11 -11
  123. package/src/NavigationProvider.tsx +13 -16
  124. package/src/PreventRemoveContext.tsx +1 -0
  125. package/src/PreventRemoveProvider.tsx +48 -43
  126. package/src/StaticNavigation.tsx +164 -99
  127. package/src/StaticTreeContext.tsx +7 -0
  128. package/src/checkSerializable.tsx +20 -14
  129. package/src/createNavigationContainerRef.tsx +12 -9
  130. package/src/createNavigatorFactory.tsx +27 -18
  131. package/src/getActionFromState.tsx +18 -16
  132. package/src/getPathFromState.tsx +167 -132
  133. package/src/getPatternParts.tsx +2 -2
  134. package/src/getStateFromPath.tsx +260 -193
  135. package/src/index.tsx +3 -0
  136. package/src/types.tsx +298 -62
  137. package/src/useEventEmitter.tsx +7 -2
  138. package/src/useKeyedChildListeners.tsx +4 -2
  139. package/src/useNavigation.tsx +2 -21
  140. package/src/useNavigationBuilder.tsx +7 -24
  141. package/src/useNavigationCache.tsx +26 -19
  142. package/src/useNavigationHelpers.tsx +26 -9
  143. package/src/useNavigationState.tsx +90 -60
  144. package/src/useOnAction.tsx +55 -3
  145. package/src/useOnPreventRemove.tsx +68 -36
  146. package/src/useOptionsGetters.tsx +4 -1
  147. package/src/usePreventRemove.tsx +11 -2
  148. package/src/useRoute.tsx +3 -5
  149. package/src/useRouteCache.tsx +19 -11
  150. package/src/useScheduleUpdate.tsx +8 -7
  151. package/src/useSyncState.tsx +5 -1
  152. package/src/utilities.tsx +36 -41
  153. package/src/validatePathConfig.tsx +86 -58
package/src/index.tsx CHANGED
@@ -4,6 +4,7 @@ export {
4
4
  createNavigatorFactory,
5
5
  type TypedNavigatorFactory,
6
6
  } from './createNavigatorFactory';
7
+ export { getLoaderForState as UNSTABLE_getLoaderForState } from './DataLoading';
7
8
  export { findFocusedRoute } from './findFocusedRoute';
8
9
  export { getActionFromState } from './getActionFromState';
9
10
  export { getFocusedRouteNameFromRoute } from './getFocusedRouteNameFromRoute';
@@ -47,6 +48,7 @@ export type {
47
48
  EventMapBase,
48
49
  EventMapCore,
49
50
  GenericNavigation,
51
+ NavigationContainerEventMap,
50
52
  NavigationContainerProps,
51
53
  NavigationContainerRef,
52
54
  NavigationContainerRefWithCurrent,
@@ -58,6 +60,7 @@ export type {
58
60
  NavigatorScreenParams,
59
61
  NavigatorTypeBagBase,
60
62
  NavigatorTypeBagFor,
63
+ NestedNavigatorsForParamList,
61
64
  PathConfig,
62
65
  PathConfigMap,
63
66
  RootNavigator,
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;
@@ -390,7 +429,7 @@ type NavigationHelpersCommon<
390
429
 
391
430
  type ParamType<
392
431
  ParamList extends {},
393
- RouteName extends keyof ParamList | unknown,
432
+ RouteName,
394
433
  IsPartial extends boolean = false,
395
434
  > = RouteName extends keyof ParamList
396
435
  ? ParamList[RouteName] extends undefined
@@ -685,16 +724,16 @@ export type RouteConfigComponent<
685
724
  * React component to render for this screen.
686
725
  */
687
726
  component: ScreenComponentType<ParamList, RouteName>;
688
- getComponent?: never | undefined;
689
- children?: never | undefined;
727
+ getComponent?: never;
728
+ children?: never;
690
729
  }
691
730
  | {
692
731
  /**
693
732
  * Lazily get a React component to render for this screen.
694
733
  */
695
734
  getComponent: () => ScreenComponentType<ParamList, RouteName>;
696
- component?: never | undefined;
697
- children?: never | undefined;
735
+ component?: never;
736
+ children?: never;
698
737
  }
699
738
  | {
700
739
  /**
@@ -704,8 +743,8 @@ export type RouteConfigComponent<
704
743
  route: RouteProp<ParamList, RouteName>;
705
744
  navigation: any;
706
745
  }) => React.ReactNode;
707
- component?: never | undefined;
708
- getComponent?: never | undefined;
746
+ component?: never;
747
+ getComponent?: never;
709
748
  };
710
749
 
711
750
  export type RouteConfigProps<
@@ -912,15 +951,19 @@ export type NavigationContainerEventMap = {
912
951
  /**
913
952
  * The data object passed when emitting the event.
914
953
  */
915
- data: unknown;
954
+ data?: unknown;
916
955
  /**
917
956
  * The key of the target route which received the event.
918
957
  */
919
- target: string | undefined;
958
+ target?: string | undefined;
920
959
  /**
921
960
  * Whether `event.preventDefault()` was called on this event.
922
961
  */
923
- defaultPrevented: boolean | undefined;
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 infer Name extends KeyOf<ParamList>
1004
- ? RouteProp<ParamList, Name>
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
- // The infer ParamList extends {} just captures the current member
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
- ? ParamListRoute<T> | RouteProp<ParamList, RouteName>
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
- ? keyof T extends ExcludedRouteNames
1060
- ? {}
1061
- : BasicNavigationList<
1062
- T,
1063
- ExcludedRouteNames,
1064
- NavigationProp<ParamList, RouteName>
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,96 @@ 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
+ > = T extends PrivateValueStore<[any, any, any, any]> & NavigatorLike
1151
+ ? NavigationListForNestedInternal<
1152
+ T,
1153
+ GenericNavigationComposite<ParamList, RouteName, Parent>
1154
+ >
1155
+ : NavigationListForParamListScreenParams<
1156
+ T,
1157
+ ParamList,
1158
+ RouteName,
1159
+ ExcludedRouteNames,
1160
+ Parent
1161
+ >;
1162
+
1163
+ type NavigationListForParamListScreenParams<
1164
+ T extends {},
1165
+ ParamList extends ParamListBase,
1166
+ RouteName extends keyof ParamList,
1167
+ ExcludedRouteNames,
1168
+ Parent extends NavigationProp<any, any, any, any, any> | undefined,
1169
+ > =
1170
+ // `T` is only ever a plain param list here, since navigators are routed to
1171
+ // `NavigationListForNestedInternal` by `NavigationListForScreenParams`.
1172
+ // So there's no navigator to unwrap with `ParamListForNavigator`.
1173
+ T extends ParamListBase
1174
+ ? BasicNavigationListForParamList<
1175
+ T,
1176
+ ExcludedRouteNames,
1177
+ GenericNavigationComposite<ParamList, RouteName, Parent>
1178
+ >
1179
+ : {};
1180
+
1181
+ type BasicNavigationListForParamList<
1182
+ ParamList extends ParamListBase,
1183
+ ExcludedRouteNames,
1184
+ Parent extends NavigationProp<any, any, any, any, any> | undefined,
1185
+ > = UnionToIntersection<
1186
+ {
1187
+ [RouteName in keyof ParamList]: (NavigatorScreenParams<{}> extends ParamList[RouteName]
1188
+ ? NotUndefined<ParamList[RouteName]> extends NavigatorScreenParams<
1189
+ infer T
1190
+ >
1191
+ ? NavigationListForScreenParams<
1192
+ T,
1193
+ ParamList,
1194
+ RouteName,
1195
+ ExcludedRouteNames,
1196
+ Parent
1197
+ >
1198
+ : {}
1199
+ : {}) &
1200
+ (RouteName extends ExcludedRouteNames
1201
+ ? {}
1202
+ : {
1203
+ [Key in RouteName]: GenericNavigationComposite<
1204
+ ParamList,
1205
+ RouteName,
1206
+ Parent
1207
+ >;
1208
+ });
1209
+ }[keyof ParamList]
1210
+ >;
1211
+
1079
1212
  export type NavigationListForNavigator<Navigator> =
1080
1213
  Navigator extends PrivateValueStore<infer Value> ? Value[1] : {};
1081
1214
 
@@ -1094,13 +1227,14 @@ type NavigationListForNestedInternal<
1094
1227
  Parent = undefined,
1095
1228
  NavigatorList extends Record<string, any> =
1096
1229
  NavigationListForNavigator<Navigator>,
1230
+ Navigators = NestedNavigatorsOf<Navigator>,
1097
1231
  // This navigator's own routes, each composed with the accumulated parent.
1098
1232
  // It's threaded into the recursion as the parent for nested navigators so
1099
1233
  // each route is composed with its ancestors exactly once, instead of
1100
1234
  // re-wrapping the whole descendant list at every level (which is quadratic
1101
1235
  // in the nesting depth).
1102
1236
  ComposedList = ComposeNavigationList<NavigatorList, Parent>,
1103
- > = Navigator extends {
1237
+ > = (Navigator extends {
1104
1238
  readonly config: {
1105
1239
  readonly screens?: infer Screens;
1106
1240
  readonly groups?: infer Groups;
@@ -1109,7 +1243,69 @@ type NavigationListForNestedInternal<
1109
1243
  ? ComposedList &
1110
1244
  NavigationListForScreens<ComposedList, Screens> &
1111
1245
  NavigationListForGroups<ComposedList, Groups>
1112
- : ComposedList;
1246
+ : ComposedList) &
1247
+ NavigationListForNestedNavigators<ComposedList, Navigators> &
1248
+ NavigationListForDynamicNestedParamLists<Navigator, ComposedList, Navigators>;
1249
+
1250
+ type NavigationListForDynamicNestedParamLists<
1251
+ Navigator,
1252
+ ParentList,
1253
+ Navigators,
1254
+ > = Navigator extends { readonly config: unknown }
1255
+ ? {}
1256
+ : Navigator extends PrivateValueStore<[infer ParamList, any, any, any]>
1257
+ ? NavigationListForNestedParamLists<ParentList, ParamList, Navigators>
1258
+ : {};
1259
+
1260
+ // Map of route name to nested navigator type
1261
+ // inferred from `NavigatorScreenParams<typeof Navigator>`
1262
+ type NestedNavigatorsOf<Navigator> =
1263
+ Navigator extends PrivateValueStore<[any, any, any, infer Nesting]>
1264
+ ? Nesting extends Record<string, any>
1265
+ ? Nesting
1266
+ : {}
1267
+ : {};
1268
+
1269
+ // Like `NavigationListForScreens`, but reads nested navigators from the brand
1270
+ // map instead of a static config.
1271
+ type NavigationListForNestedNavigators<ParentList, Navigators> =
1272
+ UnionToIntersection<
1273
+ {
1274
+ [K in keyof Navigators]: K extends keyof ParentList
1275
+ ? NavigationListForNestedInternal<Navigators[K], ParentList[K]>
1276
+ : {};
1277
+ }[keyof Navigators]
1278
+ >;
1279
+
1280
+ // Fallback for dynamic nested routes declared through NavigatorScreenParams<ParamList>.
1281
+ // Param-list branches expose generic navigation props, while nested navigator
1282
+ // entries still recover their concrete navigator props.
1283
+ type NavigationListForNestedParamLists<ParentList, ParamList, Navigators> =
1284
+ ParentList extends Record<string, any>
1285
+ ? ParamList extends ParamListBase
1286
+ ? UnionToIntersection<
1287
+ {
1288
+ [K in keyof ParamList]: K extends keyof Navigators
1289
+ ? {}
1290
+ : K extends keyof ParentList
1291
+ ? NavigatorScreenParams<{}> extends ParamList[K]
1292
+ ? NotUndefined<ParamList[K]> extends NavigatorScreenParams<
1293
+ infer T
1294
+ >
1295
+ ? NavigationListForScreenParams<
1296
+ T,
1297
+ ParamList,
1298
+ K,
1299
+ keyof ParentList,
1300
+ ParentList[K]
1301
+ >
1302
+ : {}
1303
+ : {}
1304
+ : {};
1305
+ }[keyof ParamList]
1306
+ >
1307
+ : {}
1308
+ : {};
1113
1309
 
1114
1310
  // Compose every entry in a navigator's list with the accumulated parent.
1115
1311
  // When there's no parent (root navigator), the list is returned as-is so the
@@ -1230,20 +1426,39 @@ export type NavigatorTypeBagFor<
1230
1426
  ParamList extends {},
1231
1427
  > = TypeBag & { ParamList: ParamList };
1232
1428
 
1233
- type TypedNavigatorComponent<Bag extends NavigatorTypeBagBase> =
1429
+ export type NavigatorProps<
1430
+ ParamList extends ParamListBase,
1431
+ State extends NavigationState,
1432
+ ScreenOptions extends {},
1433
+ EventMap extends EventMapBase,
1434
+ Navigation,
1435
+ Navigator extends React.ComponentType<any>,
1436
+ > = Omit<
1437
+ React.ComponentProps<Navigator>,
1438
+ keyof DefaultNavigatorOptions<any, any, any, any, any>
1439
+ > &
1440
+ DefaultNavigatorOptions<
1441
+ ParamList,
1442
+ State,
1443
+ ScreenOptions,
1444
+ EventMap,
1445
+ Navigation
1446
+ >;
1447
+
1448
+ type TypedNavigatorStaticComponent<Bag extends NavigatorTypeBagBase> =
1234
1449
  React.ComponentType<
1235
- Omit<
1236
- React.ComponentProps<
1237
- TypedNavigatorInternal<
1450
+ Partial<
1451
+ Omit<
1452
+ NavigatorProps<
1238
1453
  Bag['ParamList'],
1239
1454
  Bag['State'],
1240
1455
  Bag['ScreenOptions'],
1241
1456
  Bag['EventMap'],
1242
- Bag['NavigationList'],
1457
+ Bag['NavigationList'][keyof Bag['ParamList']],
1243
1458
  Bag['Navigator']
1244
- >['Navigator']
1245
- >,
1246
- 'children'
1459
+ >,
1460
+ 'children'
1461
+ >
1247
1462
  >
1248
1463
  >;
1249
1464
 
@@ -1261,15 +1476,16 @@ type TypedNavigatorStatic<
1261
1476
  config: Config;
1262
1477
  with: (
1263
1478
  Component: React.ComponentType<{
1264
- Navigator: TypedNavigatorComponent<Bag>;
1479
+ Navigator: TypedNavigatorStaticComponent<Bag>;
1265
1480
  }>
1266
1481
  ) => TypedNavigatorStaticDecorated<Bag, Config>;
1267
- getComponent: () => TypedNavigatorComponent<Bag>;
1482
+ getComponent: () => TypedNavigatorStaticComponent<Bag>;
1268
1483
  };
1269
1484
 
1270
1485
  export type TypedNavigator<
1271
1486
  Bag extends NavigatorTypeBagBase,
1272
1487
  Config = unknown,
1488
+ Nesting = unknown,
1273
1489
  > = (undefined extends Config
1274
1490
  ? TypedNavigatorInternal<
1275
1491
  Bag['ParamList'],
@@ -1281,7 +1497,7 @@ export type TypedNavigator<
1281
1497
  >
1282
1498
  : TypedNavigatorStatic<Bag, Config>) &
1283
1499
  PrivateValueStore<
1284
- [Bag['ParamList'], Bag['NavigationList'], unknown, unknown]
1500
+ [Bag['ParamList'], Bag['NavigationList'], unknown, Nesting]
1285
1501
  >;
1286
1502
 
1287
1503
  type TypedNavigatorInternal<
@@ -1296,17 +1512,14 @@ type TypedNavigatorInternal<
1296
1512
  * Navigator component which manages the child screens.
1297
1513
  */
1298
1514
  Navigator: React.ComponentType<
1299
- Omit<
1300
- React.ComponentProps<Navigator>,
1301
- keyof DefaultNavigatorOptions<any, any, any, any, any>
1302
- > &
1303
- DefaultNavigatorOptions<
1304
- ParamList,
1305
- State,
1306
- ScreenOptions,
1307
- EventMap,
1308
- NavigationList[keyof ParamList]
1309
- >
1515
+ NavigatorProps<
1516
+ ParamList,
1517
+ State,
1518
+ ScreenOptions,
1519
+ EventMap,
1520
+ NavigationList[keyof ParamList],
1521
+ Navigator
1522
+ >
1310
1523
  >;
1311
1524
  /**
1312
1525
  * Component used for grouping multiple route configuration.
@@ -1329,7 +1542,17 @@ type TypedNavigatorInternal<
1329
1542
  ) => null;
1330
1543
  };
1331
1544
 
1332
- export type NavigatorScreenParams<ParamList extends {}> =
1545
+ declare const NavigatorScreenParamsSymbol: unique symbol;
1546
+
1547
+ type NavigatorScreenParamsBrand<T extends {}> = {
1548
+ // Preserve the original generic for inference without affecting assignability.
1549
+ // - The symbol key hides the property from normal object usage
1550
+ // - The actual type is intersected for inference
1551
+ // - The `any` makes the property effectively `any` for assignability
1552
+ readonly [NavigatorScreenParamsSymbol]?: any & { readonly type: T };
1553
+ };
1554
+
1555
+ type NavigatorScreenParamsForParamList<ParamList extends {}> =
1333
1556
  | {
1334
1557
  screen?: never;
1335
1558
  params?: never;
@@ -1364,6 +1587,10 @@ export type NavigatorScreenParams<ParamList extends {}> =
1364
1587
  };
1365
1588
  }[keyof ParamList];
1366
1589
 
1590
+ export type NavigatorScreenParams<ParamList extends {}> =
1591
+ NavigatorScreenParamsForParamList<ParamListForNavigator<ParamList>> &
1592
+ NavigatorScreenParamsBrand<ParamList>;
1593
+
1367
1594
  type ParseConfig<Params> = {
1368
1595
  [K in keyof Params]?:
1369
1596
  | ((value: string) => Params[K])
@@ -1412,7 +1639,12 @@ type PathConfigAlias<Params> = {
1412
1639
  };
1413
1640
 
1414
1641
  export type PathConfig<Params> = FlatType<
1415
- Partial<PathConfigAlias<Params>> & {
1642
+ Partial<Omit<PathConfigAlias<Params>, 'path'>> & {
1643
+ /**
1644
+ * Path string to match against.
1645
+ * e.g. `/users/:id` will match `/users/1` and extract `id` param as `1`.
1646
+ */
1647
+ path?: string | undefined;
1416
1648
  /**
1417
1649
  * An object mapping the param name to a function which converts the param value to a string.
1418
1650
  * By default, all params are converted to strings using `String(value)`.
@@ -1431,16 +1663,20 @@ export type PathConfig<Params> = FlatType<
1431
1663
  */
1432
1664
  alias?: (string | PathConfigAlias<Params>)[] | undefined;
1433
1665
  } & (NonNullable<Params> extends NavigatorScreenParams<infer ParamList>
1434
- ? {
1435
- /**
1436
- * Path configuration for child screens.
1437
- */
1438
- screens?: PathConfigMap<ParamList> | undefined;
1439
- /**
1440
- * Name of the initial route to use for the navigator when the path matches.
1441
- */
1442
- initialRouteName?: Extract<keyof ParamList, string> | undefined;
1443
- }
1666
+ ? ParamListForNavigator<ParamList> extends infer ChildParamList extends {}
1667
+ ? {
1668
+ /**
1669
+ * Path configuration for child screens.
1670
+ */
1671
+ screens?: PathConfigMap<ChildParamList> | undefined;
1672
+ /**
1673
+ * Name of the initial route to use for the navigator when the path matches.
1674
+ */
1675
+ initialRouteName?:
1676
+ | Extract<keyof ChildParamList, string>
1677
+ | undefined;
1678
+ }
1679
+ : {}
1444
1680
  : {})
1445
1681
  >;
1446
1682
 
@@ -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
- React.useEffect(() => {
22
+ React.useInsertionEffect(() => {
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
  []
@@ -28,8 +28,10 @@ export function useKeyedChildListeners() {
28
28
  keyedListeners[type][key] = listener;
29
29
 
30
30
  return () => {
31
- // @ts-expect-error: according to ref stated above you can use `key` to index type
32
- keyedListeners[type][key] = undefined;
31
+ if (keyedListeners[type][key] === listener) {
32
+ // @ts-expect-error: according to ref stated above you can use `key` to index type
33
+ keyedListeners[type][key] = undefined;
34
+ }
33
35
  };
34
36
  },
35
37
  [keyedListeners]
@@ -1,10 +1,7 @@
1
1
  import * as React from 'react';
2
2
 
3
3
  import { NavigationContainerRefContext } from './NavigationContainerRefContext';
4
- import {
5
- NavigationContext,
6
- NavigationRouteNameContext,
7
- } from './NavigationProvider';
4
+ import { NavigationContext } from './NavigationProvider';
8
5
  import type {
9
6
  GenericNavigation,
10
7
  NavigationListForNavigator,
@@ -46,23 +43,7 @@ export function useNavigation(name?: string): unknown {
46
43
  return navigation ?? root;
47
44
  }
48
45
 
49
- const routeName = React.use(NavigationRouteNameContext);
50
-
51
- // Generally, this condition isn't needed as `getParent(name)` works for current screen
52
- // However, it'll throw if the hook is used in a preloaded screen
53
- if (routeName === name) {
54
- if (navigation === undefined) {
55
- throw new Error(
56
- `Couldn't find a navigation object for '${name}'. This is not expected.`
57
- );
58
- }
59
-
60
- return navigation;
61
- }
62
-
63
- // We get parent first so that `getParent(name)` is not called in preloaded screens
64
- // It's ok since `getParent` also works for current screen, so parent is not skipped
65
- const parent = navigation?.getParent()?.getParent(name);
46
+ const parent = navigation?.getParent(name);
66
47
 
67
48
  if (parent === undefined) {
68
49
  throw new Error(