@react-navigation/core 8.0.0-alpha.3 → 8.0.0-alpha.30

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 (283) hide show
  1. package/lib/module/BaseNavigationContainer.js +34 -17
  2. package/lib/module/BaseNavigationContainer.js.map +1 -1
  3. package/lib/module/ConsumedParamsContext.js +5 -0
  4. package/lib/module/ConsumedParamsContext.js.map +1 -0
  5. package/lib/module/DataLoading.js +127 -0
  6. package/lib/module/DataLoading.js.map +1 -0
  7. package/lib/module/NavigationBuilderContext.js +1 -0
  8. package/lib/module/NavigationBuilderContext.js.map +1 -1
  9. package/lib/module/NavigationIndependentTree.js +17 -8
  10. package/lib/module/NavigationIndependentTree.js.map +1 -1
  11. package/lib/module/NavigationProvider.js +22 -11
  12. package/lib/module/NavigationProvider.js.map +1 -1
  13. package/lib/module/NavigationStateContext.js.map +1 -1
  14. package/lib/module/PreventRemoveContext.js.map +1 -1
  15. package/lib/module/PreventRemoveProvider.js +37 -27
  16. package/lib/module/PreventRemoveProvider.js.map +1 -1
  17. package/lib/module/SceneView.js +7 -40
  18. package/lib/module/SceneView.js.map +1 -1
  19. package/lib/module/StaticNavigation.js +179 -50
  20. package/lib/module/StaticNavigation.js.map +1 -1
  21. package/lib/module/StaticTreeContext.js +5 -0
  22. package/lib/module/StaticTreeContext.js.map +1 -0
  23. package/lib/module/checkSerializable.js +18 -13
  24. package/lib/module/checkSerializable.js.map +1 -1
  25. package/lib/module/createNavigationContainerRef.js +6 -8
  26. package/lib/module/createNavigationContainerRef.js.map +1 -1
  27. package/lib/module/createNavigatorFactory.js +27 -5
  28. package/lib/module/createNavigatorFactory.js.map +1 -1
  29. package/lib/module/findFocusedRoute.js +7 -4
  30. package/lib/module/findFocusedRoute.js.map +1 -1
  31. package/lib/module/getActionFromState.js +45 -20
  32. package/lib/module/getActionFromState.js.map +1 -1
  33. package/lib/module/getPathFromState.js +171 -90
  34. package/lib/module/getPathFromState.js.map +1 -1
  35. package/lib/module/getPatternParts.js +20 -4
  36. package/lib/module/getPatternParts.js.map +1 -1
  37. package/lib/module/getStateFromPath.js +485 -214
  38. package/lib/module/getStateFromPath.js.map +1 -1
  39. package/lib/module/getStateFromRouteParams.js +24 -0
  40. package/lib/module/getStateFromRouteParams.js.map +1 -0
  41. package/lib/module/index.js +5 -4
  42. package/lib/module/index.js.map +1 -1
  43. package/lib/module/theming/useTheme.js +1 -1
  44. package/lib/module/theming/useTheme.js.map +1 -1
  45. package/lib/module/types.js +35 -0
  46. package/lib/module/types.js.map +1 -1
  47. package/lib/module/useDescriptors.js +19 -11
  48. package/lib/module/useDescriptors.js.map +1 -1
  49. package/lib/module/useEventEmitter.js +48 -33
  50. package/lib/module/useEventEmitter.js.map +1 -1
  51. package/lib/module/useFocusEvents.js +12 -4
  52. package/lib/module/useFocusEvents.js.map +1 -1
  53. package/lib/module/useFocusedListenersChildrenAdapter.js +2 -2
  54. package/lib/module/useFocusedListenersChildrenAdapter.js.map +1 -1
  55. package/lib/module/useIsFocused.js +7 -12
  56. package/lib/module/useIsFocused.js.map +1 -1
  57. package/lib/module/useKeyedChildListeners.js +4 -2
  58. package/lib/module/useKeyedChildListeners.js.map +1 -1
  59. package/lib/module/useLazyValue.js.map +1 -1
  60. package/lib/module/useNavigation.js +2 -15
  61. package/lib/module/useNavigation.js.map +1 -1
  62. package/lib/module/useNavigationBuilder.js +201 -131
  63. package/lib/module/useNavigationBuilder.js.map +1 -1
  64. package/lib/module/useNavigationCache.js +22 -17
  65. package/lib/module/useNavigationCache.js.map +1 -1
  66. package/lib/module/useNavigationHelpers.js +28 -10
  67. package/lib/module/useNavigationHelpers.js.map +1 -1
  68. package/lib/module/useNavigationIndependentTree.js +1 -1
  69. package/lib/module/useNavigationIndependentTree.js.map +1 -1
  70. package/lib/module/useNavigationState.js +70 -35
  71. package/lib/module/useNavigationState.js.map +1 -1
  72. package/lib/module/useOnAction.js +37 -7
  73. package/lib/module/useOnAction.js.map +1 -1
  74. package/lib/module/useOnGetState.js +6 -3
  75. package/lib/module/useOnGetState.js.map +1 -1
  76. package/lib/module/useOnPreventRemove.js +39 -30
  77. package/lib/module/useOnPreventRemove.js.map +1 -1
  78. package/lib/module/useOnRouteFocus.js +1 -1
  79. package/lib/module/useOnRouteFocus.js.map +1 -1
  80. package/lib/module/useOptionsGetters.js +10 -5
  81. package/lib/module/useOptionsGetters.js.map +1 -1
  82. package/lib/module/usePreventRemove.js +10 -3
  83. package/lib/module/usePreventRemove.js.map +1 -1
  84. package/lib/module/usePreventRemoveContext.js +1 -1
  85. package/lib/module/usePreventRemoveContext.js.map +1 -1
  86. package/lib/module/useRegisterNavigator.js +2 -2
  87. package/lib/module/useRegisterNavigator.js.map +1 -1
  88. package/lib/module/useRoute.js +2 -0
  89. package/lib/module/useRoute.js.map +1 -1
  90. package/lib/module/useRouteCache.js +17 -11
  91. package/lib/module/useRouteCache.js.map +1 -1
  92. package/lib/module/useScheduleUpdate.js +9 -9
  93. package/lib/module/useScheduleUpdate.js.map +1 -1
  94. package/lib/module/useStateForPath.js +1 -1
  95. package/lib/module/useStateForPath.js.map +1 -1
  96. package/lib/module/useSyncState.js +7 -3
  97. package/lib/module/useSyncState.js.map +1 -1
  98. package/lib/module/validatePathConfig.js +50 -36
  99. package/lib/module/validatePathConfig.js.map +1 -1
  100. package/lib/typescript/src/BaseNavigationContainer.d.ts +6 -3
  101. package/lib/typescript/src/BaseNavigationContainer.d.ts.map +1 -1
  102. package/lib/typescript/src/ConsumedParamsContext.d.ts +3 -0
  103. package/lib/typescript/src/ConsumedParamsContext.d.ts.map +1 -0
  104. package/lib/typescript/src/DataLoading.d.ts +21 -0
  105. package/lib/typescript/src/DataLoading.d.ts.map +1 -0
  106. package/lib/typescript/src/EnsureSingleNavigator.d.ts +1 -1
  107. package/lib/typescript/src/EnsureSingleNavigator.d.ts.map +1 -1
  108. package/lib/typescript/src/Group.d.ts +1 -1
  109. package/lib/typescript/src/Group.d.ts.map +1 -1
  110. package/lib/typescript/src/NavigationBuilderContext.d.ts +9 -8
  111. package/lib/typescript/src/NavigationBuilderContext.d.ts.map +1 -1
  112. package/lib/typescript/src/NavigationContainerRefContext.d.ts +1 -1
  113. package/lib/typescript/src/NavigationContainerRefContext.d.ts.map +1 -1
  114. package/lib/typescript/src/NavigationFocusedRouteStateContext.d.ts +4 -4
  115. package/lib/typescript/src/NavigationFocusedRouteStateContext.d.ts.map +1 -1
  116. package/lib/typescript/src/NavigationHelpersContext.d.ts +1 -1
  117. package/lib/typescript/src/NavigationHelpersContext.d.ts.map +1 -1
  118. package/lib/typescript/src/NavigationIndependentTree.d.ts +1 -1
  119. package/lib/typescript/src/NavigationIndependentTree.d.ts.map +1 -1
  120. package/lib/typescript/src/NavigationProvider.d.ts +12 -13
  121. package/lib/typescript/src/NavigationProvider.d.ts.map +1 -1
  122. package/lib/typescript/src/NavigationStateContext.d.ts +3 -3
  123. package/lib/typescript/src/NavigationStateContext.d.ts.map +1 -1
  124. package/lib/typescript/src/PreventRemoveContext.d.ts +1 -0
  125. package/lib/typescript/src/PreventRemoveContext.d.ts.map +1 -1
  126. package/lib/typescript/src/PreventRemoveProvider.d.ts +1 -1
  127. package/lib/typescript/src/PreventRemoveProvider.d.ts.map +1 -1
  128. package/lib/typescript/src/SceneView.d.ts +3 -2
  129. package/lib/typescript/src/SceneView.d.ts.map +1 -1
  130. package/lib/typescript/src/Screen.d.ts +1 -1
  131. package/lib/typescript/src/Screen.d.ts.map +1 -1
  132. package/lib/typescript/src/StaticContainer.d.ts +1 -1
  133. package/lib/typescript/src/StaticContainer.d.ts.map +1 -1
  134. package/lib/typescript/src/StaticNavigation.d.ts +189 -109
  135. package/lib/typescript/src/StaticNavigation.d.ts.map +1 -1
  136. package/lib/typescript/src/StaticTreeContext.d.ts +4 -0
  137. package/lib/typescript/src/StaticTreeContext.d.ts.map +1 -0
  138. package/lib/typescript/src/checkSerializable.d.ts +8 -4
  139. package/lib/typescript/src/checkSerializable.d.ts.map +1 -1
  140. package/lib/typescript/src/createNavigationContainerRef.d.ts +1 -1
  141. package/lib/typescript/src/createNavigationContainerRef.d.ts.map +1 -1
  142. package/lib/typescript/src/createNavigatorFactory.d.ts +23 -5
  143. package/lib/typescript/src/createNavigatorFactory.d.ts.map +1 -1
  144. package/lib/typescript/src/findFocusedRoute.d.ts +3 -3
  145. package/lib/typescript/src/findFocusedRoute.d.ts.map +1 -1
  146. package/lib/typescript/src/getActionFromState.d.ts +4 -4
  147. package/lib/typescript/src/getActionFromState.d.ts.map +1 -1
  148. package/lib/typescript/src/getPathFromState.d.ts +3 -3
  149. package/lib/typescript/src/getPathFromState.d.ts.map +1 -1
  150. package/lib/typescript/src/getPatternParts.d.ts +1 -0
  151. package/lib/typescript/src/getPatternParts.d.ts.map +1 -1
  152. package/lib/typescript/src/getStateFromPath.d.ts +5 -5
  153. package/lib/typescript/src/getStateFromPath.d.ts.map +1 -1
  154. package/lib/typescript/src/getStateFromRouteParams.d.ts +3 -0
  155. package/lib/typescript/src/getStateFromRouteParams.d.ts.map +1 -0
  156. package/lib/typescript/src/index.d.ts +36 -33
  157. package/lib/typescript/src/index.d.ts.map +1 -1
  158. package/lib/typescript/src/theming/ThemeContext.d.ts +1 -1
  159. package/lib/typescript/src/theming/ThemeContext.d.ts.map +1 -1
  160. package/lib/typescript/src/theming/ThemeProvider.d.ts +2 -2
  161. package/lib/typescript/src/theming/ThemeProvider.d.ts.map +1 -1
  162. package/lib/typescript/src/theming/useTheme.d.ts +1 -1
  163. package/lib/typescript/src/theming/useTheme.d.ts.map +1 -1
  164. package/lib/typescript/src/types.d.ts +260 -159
  165. package/lib/typescript/src/types.d.ts.map +1 -1
  166. package/lib/typescript/src/useChildListeners.d.ts +3 -3
  167. package/lib/typescript/src/useChildListeners.d.ts.map +1 -1
  168. package/lib/typescript/src/useComponent.d.ts +1 -1
  169. package/lib/typescript/src/useComponent.d.ts.map +1 -1
  170. package/lib/typescript/src/useDescriptors.d.ts +8 -8
  171. package/lib/typescript/src/useDescriptors.d.ts.map +1 -1
  172. package/lib/typescript/src/useEventEmitter.d.ts +2 -2
  173. package/lib/typescript/src/useEventEmitter.d.ts.map +1 -1
  174. package/lib/typescript/src/useFocusEvents.d.ts +2 -2
  175. package/lib/typescript/src/useFocusEvents.d.ts.map +1 -1
  176. package/lib/typescript/src/useFocusedListenersChildrenAdapter.d.ts +2 -2
  177. package/lib/typescript/src/useFocusedListenersChildrenAdapter.d.ts.map +1 -1
  178. package/lib/typescript/src/useIsFocused.d.ts +3 -0
  179. package/lib/typescript/src/useIsFocused.d.ts.map +1 -1
  180. package/lib/typescript/src/useKeyedChildListeners.d.ts +3 -3
  181. package/lib/typescript/src/useKeyedChildListeners.d.ts.map +1 -1
  182. package/lib/typescript/src/useLazyValue.d.ts.map +1 -1
  183. package/lib/typescript/src/useNavigation.d.ts +4 -2
  184. package/lib/typescript/src/useNavigation.d.ts.map +1 -1
  185. package/lib/typescript/src/useNavigationBuilder.d.ts +23 -30
  186. package/lib/typescript/src/useNavigationBuilder.d.ts.map +1 -1
  187. package/lib/typescript/src/useNavigationCache.d.ts +3 -3
  188. package/lib/typescript/src/useNavigationCache.d.ts.map +1 -1
  189. package/lib/typescript/src/useNavigationContainerRef.d.ts +1 -1
  190. package/lib/typescript/src/useNavigationContainerRef.d.ts.map +1 -1
  191. package/lib/typescript/src/useNavigationHelpers.d.ts +19 -27
  192. package/lib/typescript/src/useNavigationHelpers.d.ts.map +1 -1
  193. package/lib/typescript/src/useNavigationState.d.ts +13 -3
  194. package/lib/typescript/src/useNavigationState.d.ts.map +1 -1
  195. package/lib/typescript/src/useOnAction.d.ts +9 -9
  196. package/lib/typescript/src/useOnAction.d.ts.map +1 -1
  197. package/lib/typescript/src/useOnGetState.d.ts +1 -1
  198. package/lib/typescript/src/useOnGetState.d.ts.map +1 -1
  199. package/lib/typescript/src/useOnPreventRemove.d.ts +5 -9
  200. package/lib/typescript/src/useOnPreventRemove.d.ts.map +1 -1
  201. package/lib/typescript/src/useOnRouteFocus.d.ts +6 -6
  202. package/lib/typescript/src/useOnRouteFocus.d.ts.map +1 -1
  203. package/lib/typescript/src/useOptionsGetters.d.ts +1 -1
  204. package/lib/typescript/src/useOptionsGetters.d.ts.map +1 -1
  205. package/lib/typescript/src/usePreventRemove.d.ts.map +1 -1
  206. package/lib/typescript/src/usePreventRemoveContext.d.ts +2 -1
  207. package/lib/typescript/src/usePreventRemoveContext.d.ts.map +1 -1
  208. package/lib/typescript/src/useRoute.d.ts +7 -3
  209. package/lib/typescript/src/useRoute.d.ts.map +1 -1
  210. package/lib/typescript/src/useRouteCache.d.ts +5 -5
  211. package/lib/typescript/src/useRouteCache.d.ts.map +1 -1
  212. package/lib/typescript/src/useScheduleUpdate.d.ts +5 -4
  213. package/lib/typescript/src/useScheduleUpdate.d.ts.map +1 -1
  214. package/lib/typescript/src/useStateForPath.d.ts +1 -1
  215. package/lib/typescript/src/useStateForPath.d.ts.map +1 -1
  216. package/lib/typescript/src/useSyncState.d.ts.map +1 -1
  217. package/lib/typescript/src/utilities.d.ts +74 -37
  218. package/lib/typescript/src/utilities.d.ts.map +1 -1
  219. package/lib/typescript/src/validatePathConfig.d.ts.map +1 -1
  220. package/package.json +23 -22
  221. package/src/BaseNavigationContainer.tsx +351 -333
  222. package/src/ConsumedParamsContext.tsx +5 -0
  223. package/src/DataLoading.tsx +203 -0
  224. package/src/NavigationBuilderContext.tsx +14 -9
  225. package/src/NavigationFocusedRouteStateContext.tsx +4 -4
  226. package/src/NavigationIndependentTree.tsx +18 -12
  227. package/src/NavigationProvider.tsx +26 -15
  228. package/src/NavigationStateContext.tsx +5 -6
  229. package/src/PreventRemoveContext.tsx +1 -0
  230. package/src/PreventRemoveProvider.tsx +51 -46
  231. package/src/SceneView.tsx +7 -39
  232. package/src/StaticNavigation.tsx +659 -307
  233. package/src/StaticTreeContext.tsx +7 -0
  234. package/src/checkSerializable.tsx +35 -19
  235. package/src/createNavigationContainerRef.tsx +12 -9
  236. package/src/createNavigatorFactory.tsx +92 -8
  237. package/src/findFocusedRoute.tsx +13 -8
  238. package/src/getActionFromState.tsx +86 -51
  239. package/src/getPathFromState.tsx +254 -128
  240. package/src/getPatternParts.tsx +25 -4
  241. package/src/getStateFromPath.tsx +811 -309
  242. package/src/getStateFromRouteParams.tsx +60 -0
  243. package/src/index.tsx +55 -5
  244. package/src/theming/useTheme.tsx +1 -1
  245. package/src/types.tsx +798 -373
  246. package/src/useDescriptors.tsx +28 -14
  247. package/src/useEventEmitter.tsx +52 -38
  248. package/src/useFocusEvents.tsx +15 -7
  249. package/src/useFocusedListenersChildrenAdapter.tsx +2 -2
  250. package/src/useIsFocused.tsx +14 -21
  251. package/src/useKeyedChildListeners.tsx +4 -2
  252. package/src/useLazyValue.tsx +2 -2
  253. package/src/useNavigation.tsx +7 -24
  254. package/src/useNavigationBuilder.tsx +311 -186
  255. package/src/useNavigationCache.tsx +32 -25
  256. package/src/useNavigationHelpers.tsx +27 -10
  257. package/src/useNavigationIndependentTree.tsx +1 -1
  258. package/src/useNavigationState.tsx +93 -59
  259. package/src/useOnAction.tsx +61 -13
  260. package/src/useOnGetState.tsx +5 -3
  261. package/src/useOnPreventRemove.tsx +75 -42
  262. package/src/useOnRouteFocus.tsx +10 -12
  263. package/src/useOptionsGetters.tsx +11 -5
  264. package/src/usePreventRemove.tsx +12 -3
  265. package/src/usePreventRemoveContext.tsx +1 -1
  266. package/src/useRegisterNavigator.tsx +2 -2
  267. package/src/useRoute.tsx +20 -6
  268. package/src/useRouteCache.tsx +22 -16
  269. package/src/useScheduleUpdate.tsx +9 -10
  270. package/src/useStateForPath.tsx +1 -1
  271. package/src/useSyncState.tsx +8 -3
  272. package/src/utilities.tsx +144 -31
  273. package/src/validatePathConfig.tsx +86 -57
  274. package/lib/module/CurrentRenderContext.js +0 -10
  275. package/lib/module/CurrentRenderContext.js.map +0 -1
  276. package/lib/module/useCurrentRender.js +0 -19
  277. package/lib/module/useCurrentRender.js.map +0 -1
  278. package/lib/typescript/src/CurrentRenderContext.d.ts +0 -9
  279. package/lib/typescript/src/CurrentRenderContext.d.ts.map +0 -1
  280. package/lib/typescript/src/useCurrentRender.d.ts +0 -14
  281. package/lib/typescript/src/useCurrentRender.d.ts.map +0 -1
  282. package/src/CurrentRenderContext.tsx +0 -9
  283. package/src/useCurrentRender.tsx +0 -31
package/src/utilities.tsx CHANGED
@@ -15,6 +15,39 @@ export type KeysOf<T> = T extends {} ? keyof T : never;
15
15
  */
16
16
  export type KeyOf<T extends {}> = Extract<keyof T, string>;
17
17
 
18
+ /**
19
+ * TS only checks object literals for excess properties when they are not generic.
20
+ * When an object is captured as a generic type, unknown keys are not caught.
21
+ * This builds a type from the provided object where any key not in the allowed type has the type `never`.
22
+ * Checking the provided object against this type then produces an error for each unknown key.
23
+ *
24
+ * When `Provided` has a string index signature (e.g. a type built from `any`,
25
+ * whose `keyof` includes `string`), there are no specific excess keys to flag,
26
+ * so this resolves to an empty type to avoid marking every key as `never`.
27
+ */
28
+ export type NoExcessObject<Provided, Allowed> = string extends keyof Provided
29
+ ? {}
30
+ : Record<Exclude<keyof Provided, keyof Allowed>, never>;
31
+
32
+ /**
33
+ * Check an object captured as a generic type against an allowed type,
34
+ * e.g. an object returned from a callback isn't checked for excess properties.
35
+ */
36
+ export type NoExcessCallbackReturn<
37
+ Provided extends {},
38
+ Allowed extends {},
39
+ > = Allowed & Provided & NoExcessObject<Provided, Allowed>;
40
+
41
+ /**
42
+ * Apply excess property checking to a value,
43
+ * or to the return value if the value is a function.
44
+ */
45
+ export type NoExcessValue<Provided, Allowed extends {}> = Provided extends (
46
+ ...args: never[]
47
+ ) => infer Return
48
+ ? (...args: never[]) => Allowed & NoExcessObject<Return, Allowed>
49
+ : NoExcessObject<Provided, Allowed>;
50
+
18
51
  /**
19
52
  * We get a union type when using keyof, but we want an intersection instead.
20
53
  * https://stackoverflow.com/a/50375286/1665026
@@ -25,8 +58,6 @@ export type UnionToIntersection<U> = (
25
58
  ? I
26
59
  : never;
27
60
 
28
- export type UnknownToUndefined<T> = unknown extends T ? undefined : T;
29
-
30
61
  /**
31
62
  * Exclude undefined from a type.
32
63
  * Similar to NonNullable but only excludes undefined, not null.
@@ -35,6 +66,33 @@ export type NotUndefined<T> = T extends undefined ? never : T;
35
66
 
36
67
  export type AnyToUnknown<T> = 0 extends 1 & T ? unknown : T;
37
68
 
69
+ export type RequiredKeys<T extends object> = {
70
+ [K in keyof T]-?: {} extends Pick<T, K> ? never : K;
71
+ }[keyof T];
72
+
73
+ type OptionalKeys<T extends object> = Exclude<keyof T, RequiredKeys<T>>;
74
+
75
+ /**
76
+ * Remove `| undefined` from the object type,
77
+ * and adjust the optionality of the keys based on the original type.
78
+ */
79
+ export type NotUndefinedObject<
80
+ T extends object | undefined,
81
+ O extends object = NotUndefined<T>,
82
+ > = undefined extends T
83
+ ? {
84
+ [K in RequiredKeys<O>]: O[K];
85
+ } & {
86
+ [K in OptionalKeys<O>]?: O[K] | undefined;
87
+ }
88
+ : T;
89
+
90
+ export type UndefinedIfAllOptional<T> = T extends object
91
+ ? RequiredKeys<T> extends never
92
+ ? T | undefined
93
+ : T
94
+ : T;
95
+
38
96
  /**
39
97
  * Check if a function type has arguments.
40
98
  */
@@ -66,6 +124,24 @@ type ExtractSegmentParam<Segment extends string> =
66
124
  ? { [K in StripRegex<Param>]: string }
67
125
  : {};
68
126
 
127
+ export type StandardSchemaValidationResult<Output> =
128
+ | { value: Output; issues?: undefined }
129
+ | { value?: undefined; issues: readonly unknown[] };
130
+
131
+ export type StandardSchemaV1<Input = unknown, Output = Input> = {
132
+ readonly '~standard': {
133
+ readonly version: 1;
134
+ readonly vendor: string;
135
+ readonly validate: (
136
+ value: Input
137
+ ) =>
138
+ | StandardSchemaValidationResult<Output>
139
+ | Promise<StandardSchemaValidationResult<Output>>;
140
+ };
141
+ };
142
+
143
+ export type QueryParamInput = string | string[] | null | undefined;
144
+
69
145
  /**
70
146
  * Extract path params from a path string.
71
147
  * e.g. `/foo/:userId/:postId` -> `{ userId: string; postId: string }`
@@ -78,45 +154,82 @@ export type ExtractParamStrings<Path extends string> =
78
154
  : ExtractSegmentParam<Path>;
79
155
 
80
156
  /**
81
- * Extract the parsed params type from base params and parse functions.
82
- * Applies the return type of parse functions to the corresponding params.
157
+ * Get the type of params based on the `parse` config and the path pattern.
83
158
  */
84
159
  export type ExtractParamsType<Params, Parse> = {
160
+ /**
161
+ * Base param types from path pattern
162
+ * Refine the type based on standard schema, then parse function
163
+ * Otherwise, use the type from path pattern
164
+ */
85
165
  [K in keyof Params]: K extends keyof Parse
86
- ? Parse[K] extends (value: string) => infer R
166
+ ? Parse[K] extends StandardSchemaV1<unknown, infer R>
87
167
  ? R
88
- : Params[K]
168
+ : Parse[K] extends (value: string) => infer R
169
+ ? R
170
+ : Params[K]
89
171
  : Params[K];
90
- };
172
+ } & // Query params are the parse keys not present in the path pattern. When there
173
+ // are none (the common case), skip building the query param mapped types.
174
+ ([Exclude<keyof Parse, keyof Params>] extends [never]
175
+ ? {}
176
+ : {
177
+ /**
178
+ * Optional param types not in path pattern (for query params)
179
+ */
180
+ [K in QueryParamOptionalKeys<Params, Parse>]?: QueryParamValue<
181
+ Parse[K]
182
+ >;
183
+ } & {
184
+ /**
185
+ * Required param types not in path pattern (for query params)
186
+ */
187
+ [K in QueryParamRequiredKeys<Params, Parse>]: QueryParamValue<Parse[K]>;
188
+ });
91
189
 
92
- /**
93
- * Infer the path string from a linking config.
94
- */
95
- export type InferPath<T> = T extends { path: infer P extends string }
96
- ? P
97
- : never;
190
+ type QueryParamValue<ParseValue> =
191
+ ParseValue extends StandardSchemaV1<unknown, infer R>
192
+ ? R
193
+ : ParseValue extends (value: string) => infer R
194
+ ? R
195
+ : never;
98
196
 
99
197
  /**
100
- * Infer the parse functions from a linking config.
198
+ * For schema, it's optional if the output has `undefined`, otherwise required
199
+ * For parse function, it's always optional as it can't say if it's required or not
101
200
  */
102
- export type InferParse<T> = T extends { parse: infer P } ? P : {};
201
+ type QueryParamOptionalKeys<Params, Parse> = {
202
+ [K in Exclude<keyof Parse, keyof Params>]: Parse[K] extends StandardSchemaV1<
203
+ unknown,
204
+ infer R
205
+ >
206
+ ? undefined extends R
207
+ ? K
208
+ : never
209
+ : Parse[K] extends (value: string) => unknown
210
+ ? K
211
+ : never;
212
+ }[Exclude<keyof Parse, keyof Params>];
103
213
 
104
214
  /**
105
- * Infer the params type from a screen component or nested navigator.
215
+ * Exclude optional keys to get required keys
216
+ * For schema, it's required if the output doesn't have `undefined`, otherwise optional
217
+ * It doesn't include parse functions (as they are always optional)
106
218
  */
107
- export type InferScreenParams<T> =
108
- T extends React.ComponentType<{ route: { params: infer P } }>
109
- ? P
110
- : T extends { config: { screens: infer Screens } }
111
- ? import('./types').NavigatorScreenParams<{
112
- [K in keyof Screens]: Screens[K] extends React.ComponentType<{
113
- route: { params: infer P };
114
- }>
115
- ? P
116
- : Screens[K] extends { screen: infer S }
117
- ? S extends React.ComponentType<{ route: { params: infer P } }>
118
- ? P
119
- : undefined
120
- : undefined;
121
- }>
219
+ type QueryParamRequiredKeys<Params, Parse> = Exclude<
220
+ Exclude<keyof Parse, keyof Params>,
221
+ QueryParamOptionalKeys<Params, Parse>
222
+ >;
223
+
224
+ export type InferParamsFromLinking<T> = T extends {
225
+ path: infer P extends string;
226
+ parse: infer Parse;
227
+ }
228
+ ? UndefinedIfAllOptional<ExtractParamsType<ExtractParamStrings<P>, Parse>>
229
+ : T extends {
230
+ path: infer P extends string;
231
+ }
232
+ ? UndefinedIfAllOptional<ExtractParamStrings<P>>
233
+ : T extends string
234
+ ? UndefinedIfAllOptional<ExtractParamStrings<T>>
122
235
  : undefined;
@@ -1,23 +1,39 @@
1
- const formatToList = (items: Record<string, string>) =>
2
- Object.entries(items)
3
- .map(([key, value]) => `- ${key} (${value})`)
4
- .join('\n');
1
+ const ROOT_VALIDATION_LIST = [
2
+ '- path (string)',
3
+ '- initialRouteName (string)',
4
+ '- screens (object)',
5
+ ].join('\n');
5
6
 
6
- export function validatePathConfig(config: unknown, root = true) {
7
- const validation = {
8
- path: 'string',
9
- initialRouteName: 'string',
10
- screens: 'object',
11
- ...(root
12
- ? null
13
- : {
14
- alias: 'array',
15
- exact: 'boolean',
16
- stringify: 'object',
17
- parse: 'object',
18
- }),
19
- };
7
+ const NESTED_VALIDATION_LIST = [
8
+ ROOT_VALIDATION_LIST,
9
+ '- alias (array)',
10
+ '- exact (boolean)',
11
+ '- stringify (object)',
12
+ '- parse (object)',
13
+ '- shared (boolean)',
14
+ ].join('\n');
15
+
16
+ const getValidationType = (key: string, root: boolean) => {
17
+ switch (key) {
18
+ case 'path':
19
+ case 'initialRouteName':
20
+ return 'string';
21
+ case 'screens':
22
+ return 'object';
23
+ case 'alias':
24
+ return root ? undefined : 'array';
25
+ case 'exact':
26
+ case 'shared':
27
+ return root ? undefined : 'boolean';
28
+ case 'stringify':
29
+ case 'parse':
30
+ return root ? undefined : 'object';
31
+ default:
32
+ return undefined;
33
+ }
34
+ };
20
35
 
36
+ export function validatePathConfig(config: unknown, root = true) {
21
37
  if (typeof config !== 'object' || config === null) {
22
38
  throw new Error(
23
39
  `Expected the configuration to be an object, but got ${JSON.stringify(
@@ -26,58 +42,71 @@ export function validatePathConfig(config: unknown, root = true) {
26
42
  );
27
43
  }
28
44
 
29
- const validationErrors = Object.fromEntries(
30
- Object.keys(config)
31
- .map((key) => {
32
- if (key in validation) {
33
- const type = validation[key as keyof typeof validation];
34
- // @ts-expect-error: we know the key exists
35
- const value = config[key];
36
-
37
- if (value !== undefined) {
38
- if (type === 'array') {
39
- if (!Array.isArray(value)) {
40
- return [key, `expected 'Array', got '${typeof value}'`];
41
- }
42
- } else if (typeof value !== type) {
43
- return [key, `expected '${type}', got '${typeof value}'`];
44
- }
45
- }
46
- } else {
47
- return [key, 'extraneous'];
48
- }
49
-
50
- return null;
51
- })
52
- .filter(Boolean) as [string, string][]
53
- );
54
-
55
- if (Object.keys(validationErrors).length) {
45
+ const pathConfig = config as Record<string, unknown>;
46
+
47
+ let validationErrors: string[] | undefined;
48
+
49
+ for (const key in pathConfig) {
50
+ const type = getValidationType(key, root);
51
+
52
+ if (type === undefined) {
53
+ (validationErrors ??= []).push(`- ${key} (extraneous)`);
54
+ continue;
55
+ }
56
+
57
+ const value = pathConfig[key];
58
+
59
+ if (value === undefined) {
60
+ continue;
61
+ }
62
+
63
+ if (type === 'array') {
64
+ if (!Array.isArray(value)) {
65
+ (validationErrors ??= []).push(
66
+ `- ${key} (expected 'Array', got '${typeof value}')`
67
+ );
68
+ }
69
+ } else if (typeof value !== type) {
70
+ (validationErrors ??= []).push(
71
+ `- ${key} (expected '${type}', got '${typeof value}')`
72
+ );
73
+ }
74
+ }
75
+
76
+ if (validationErrors) {
56
77
  throw new Error(
57
- `Found invalid properties in the configuration:\n${formatToList(
58
- validationErrors
59
- )}\n\nYou can only specify the following properties:\n${formatToList(
60
- validation
61
- )}\n\nIf you want to specify configuration for screens, you need to specify them under a 'screens' property.\n\nSee https://reactnavigation.org/docs/configuring-links for more details on how to specify a linking configuration.`
78
+ `Found invalid properties in the configuration:\n${validationErrors.join(
79
+ '\n'
80
+ )}\n\nYou can only specify the following properties:\n${
81
+ root ? ROOT_VALIDATION_LIST : NESTED_VALIDATION_LIST
82
+ }\n\nIf you want to specify configuration for screens, you need to specify them under a 'screens' property.\n\nSee https://reactnavigation.org/docs/configuring-links for more details on how to specify a linking configuration.`
62
83
  );
63
84
  }
64
85
 
86
+ const path = pathConfig.path;
87
+
65
88
  if (
66
89
  root &&
67
- 'path' in config &&
68
- typeof config.path === 'string' &&
69
- config.path.includes(':')
90
+ 'path' in pathConfig &&
91
+ typeof path === 'string' &&
92
+ path.includes(':')
70
93
  ) {
71
94
  throw new Error(
72
- `Found invalid path '${config.path}'. The 'path' in the top-level configuration cannot contain patterns for params.`
95
+ `Found invalid path '${path}'. The 'path' in the top-level configuration cannot contain patterns for params.`
73
96
  );
74
97
  }
75
98
 
76
- if ('screens' in config && config.screens) {
77
- Object.entries(config.screens).forEach(([_, value]) => {
99
+ const screens = pathConfig.screens;
100
+
101
+ if (screens && typeof screens === 'object') {
102
+ const screenConfig = screens as Record<string, unknown>;
103
+
104
+ for (const name in screenConfig) {
105
+ const value = screenConfig[name];
106
+
78
107
  if (typeof value !== 'string') {
79
108
  validatePathConfig(value, false);
80
109
  }
81
- });
110
+ }
82
111
  }
83
112
  }
@@ -1,10 +0,0 @@
1
- "use strict";
2
-
3
- import * as React from 'react';
4
-
5
- /**
6
- * Context which holds the values for the current navigation tree.
7
- * Intended for use in SSR. This is not safe to use on the client.
8
- */
9
- export const CurrentRenderContext = /*#__PURE__*/React.createContext(undefined);
10
- //# sourceMappingURL=CurrentRenderContext.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["React","CurrentRenderContext","createContext","undefined"],"sourceRoot":"../../src","sources":["CurrentRenderContext.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;;AAE9B;AACA;AACA;AACA;AACA,OAAO,MAAMC,oBAAoB,gBAAGD,KAAK,CAACE,aAAa,CAErDC,SAAS,CAAC","ignoreList":[]}
@@ -1,19 +0,0 @@
1
- "use strict";
2
-
3
- import * as React from 'react';
4
- import { CurrentRenderContext } from "./CurrentRenderContext.js";
5
- /**
6
- * Write the current options, so that server renderer can get current values
7
- * Mutating values like this is not safe in async mode, but it doesn't apply to SSR
8
- */
9
- export function useCurrentRender({
10
- state,
11
- navigation,
12
- descriptors
13
- }) {
14
- const current = React.useContext(CurrentRenderContext);
15
- if (current && navigation.isFocused()) {
16
- current.options = descriptors[state.routes[state.index].key].options;
17
- }
18
- }
19
- //# sourceMappingURL=useCurrentRender.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["React","CurrentRenderContext","useCurrentRender","state","navigation","descriptors","current","useContext","isFocused","options","routes","index","key"],"sourceRoot":"../../src","sources":["useCurrentRender.tsx"],"mappings":";;AACA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAE9B,SAASC,oBAAoB,QAAQ,2BAAwB;AAiB7D;AACA;AACA;AACA;AACA,OAAO,SAASC,gBAAgBA,CAAC;EAAEC,KAAK;EAAEC,UAAU;EAAEC;AAAqB,CAAC,EAAE;EAC5E,MAAMC,OAAO,GAAGN,KAAK,CAACO,UAAU,CAACN,oBAAoB,CAAC;EAEtD,IAAIK,OAAO,IAAIF,UAAU,CAACI,SAAS,CAAC,CAAC,EAAE;IACrCF,OAAO,CAACG,OAAO,GAAGJ,WAAW,CAACF,KAAK,CAACO,MAAM,CAACP,KAAK,CAACQ,KAAK,CAAC,CAACC,GAAG,CAAC,CAACH,OAAO;EACtE;AACF","ignoreList":[]}
@@ -1,9 +0,0 @@
1
- import * as React from 'react';
2
- /**
3
- * Context which holds the values for the current navigation tree.
4
- * Intended for use in SSR. This is not safe to use on the client.
5
- */
6
- export declare const CurrentRenderContext: React.Context<{
7
- options?: object;
8
- } | undefined>;
9
- //# sourceMappingURL=CurrentRenderContext.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"CurrentRenderContext.d.ts","sourceRoot":"","sources":["../../../src/CurrentRenderContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B;;;GAGG;AACH,eAAO,MAAM,oBAAoB;cACnB,MAAM;cACR,CAAC"}
@@ -1,14 +0,0 @@
1
- import type { NavigationState, ParamListBase } from '@react-navigation/routers';
2
- import type { Descriptor, NavigationHelpers, NavigationProp, RouteProp } from './types';
3
- type Options = {
4
- state: NavigationState;
5
- navigation: NavigationHelpers<ParamListBase>;
6
- descriptors: Record<string, Descriptor<object, NavigationProp<ParamListBase>, RouteProp<ParamListBase>>>;
7
- };
8
- /**
9
- * Write the current options, so that server renderer can get current values
10
- * Mutating values like this is not safe in async mode, but it doesn't apply to SSR
11
- */
12
- export declare function useCurrentRender({ state, navigation, descriptors }: Options): void;
13
- export {};
14
- //# sourceMappingURL=useCurrentRender.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useCurrentRender.d.ts","sourceRoot":"","sources":["../../../src/useCurrentRender.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAIhF,OAAO,KAAK,EACV,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,SAAS,EACV,MAAM,SAAS,CAAC;AAEjB,KAAK,OAAO,GAAG;IACb,KAAK,EAAE,eAAe,CAAC;IACvB,UAAU,EAAE,iBAAiB,CAAC,aAAa,CAAC,CAAC;IAC7C,WAAW,EAAE,MAAM,CACjB,MAAM,EACN,UAAU,CAAC,MAAM,EAAE,cAAc,CAAC,aAAa,CAAC,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC,CAC5E,CAAC;CACH,CAAC;AAEF;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,EAAE,OAAO,QAM3E"}
@@ -1,9 +0,0 @@
1
- import * as React from 'react';
2
-
3
- /**
4
- * Context which holds the values for the current navigation tree.
5
- * Intended for use in SSR. This is not safe to use on the client.
6
- */
7
- export const CurrentRenderContext = React.createContext<
8
- { options?: object } | undefined
9
- >(undefined);
@@ -1,31 +0,0 @@
1
- import type { NavigationState, ParamListBase } from '@react-navigation/routers';
2
- import * as React from 'react';
3
-
4
- import { CurrentRenderContext } from './CurrentRenderContext';
5
- import type {
6
- Descriptor,
7
- NavigationHelpers,
8
- NavigationProp,
9
- RouteProp,
10
- } from './types';
11
-
12
- type Options = {
13
- state: NavigationState;
14
- navigation: NavigationHelpers<ParamListBase>;
15
- descriptors: Record<
16
- string,
17
- Descriptor<object, NavigationProp<ParamListBase>, RouteProp<ParamListBase>>
18
- >;
19
- };
20
-
21
- /**
22
- * Write the current options, so that server renderer can get current values
23
- * Mutating values like this is not safe in async mode, but it doesn't apply to SSR
24
- */
25
- export function useCurrentRender({ state, navigation, descriptors }: Options) {
26
- const current = React.useContext(CurrentRenderContext);
27
-
28
- if (current && navigation.isFocused()) {
29
- current.options = descriptors[state.routes[state.index].key].options;
30
- }
31
- }