@react-navigation/core 8.0.0-alpha.2 → 8.0.0-alpha.20

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 (251) hide show
  1. package/lib/module/BaseNavigationContainer.js +20 -9
  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/NavigationBuilderContext.js +1 -0
  6. package/lib/module/NavigationBuilderContext.js.map +1 -1
  7. package/lib/module/NavigationIndependentTree.js +8 -4
  8. package/lib/module/NavigationIndependentTree.js.map +1 -1
  9. package/lib/module/NavigationProvider.js +14 -3
  10. package/lib/module/NavigationProvider.js.map +1 -1
  11. package/lib/module/NavigationStateContext.js.map +1 -1
  12. package/lib/module/PreventRemoveProvider.js +3 -3
  13. package/lib/module/PreventRemoveProvider.js.map +1 -1
  14. package/lib/module/SceneView.js +46 -56
  15. package/lib/module/SceneView.js.map +1 -1
  16. package/lib/module/StaticNavigation.js +166 -46
  17. package/lib/module/StaticNavigation.js.map +1 -1
  18. package/lib/module/checkSerializable.js +11 -4
  19. package/lib/module/checkSerializable.js.map +1 -1
  20. package/lib/module/createNavigatorFactory.js +27 -5
  21. package/lib/module/createNavigatorFactory.js.map +1 -1
  22. package/lib/module/findFocusedRoute.js +7 -4
  23. package/lib/module/findFocusedRoute.js.map +1 -1
  24. package/lib/module/getActionFromState.js +40 -14
  25. package/lib/module/getActionFromState.js.map +1 -1
  26. package/lib/module/getPathFromState.js +48 -11
  27. package/lib/module/getPathFromState.js.map +1 -1
  28. package/lib/module/getPatternParts.js +3 -0
  29. package/lib/module/getPatternParts.js.map +1 -1
  30. package/lib/module/getStateFromPath.js +353 -166
  31. package/lib/module/getStateFromPath.js.map +1 -1
  32. package/lib/module/getStateFromRouteParams.js +24 -0
  33. package/lib/module/getStateFromRouteParams.js.map +1 -0
  34. package/lib/module/index.js +3 -4
  35. package/lib/module/index.js.map +1 -1
  36. package/lib/module/theming/useTheme.js +1 -1
  37. package/lib/module/theming/useTheme.js.map +1 -1
  38. package/lib/module/types.js +15 -0
  39. package/lib/module/types.js.map +1 -1
  40. package/lib/module/useDescriptors.js +18 -9
  41. package/lib/module/useDescriptors.js.map +1 -1
  42. package/lib/module/useEventEmitter.js +43 -31
  43. package/lib/module/useEventEmitter.js.map +1 -1
  44. package/lib/module/useFocusEvents.js +6 -2
  45. package/lib/module/useFocusEvents.js.map +1 -1
  46. package/lib/module/useFocusedListenersChildrenAdapter.js +2 -2
  47. package/lib/module/useFocusedListenersChildrenAdapter.js.map +1 -1
  48. package/lib/module/useIsFocused.js +7 -12
  49. package/lib/module/useIsFocused.js.map +1 -1
  50. package/lib/module/useNavigation.js.map +1 -1
  51. package/lib/module/useNavigationBuilder.js +144 -86
  52. package/lib/module/useNavigationBuilder.js.map +1 -1
  53. package/lib/module/useNavigationCache.js +3 -3
  54. package/lib/module/useNavigationCache.js.map +1 -1
  55. package/lib/module/useNavigationHelpers.js +1 -1
  56. package/lib/module/useNavigationHelpers.js.map +1 -1
  57. package/lib/module/useNavigationIndependentTree.js +1 -1
  58. package/lib/module/useNavigationIndependentTree.js.map +1 -1
  59. package/lib/module/useNavigationState.js +6 -4
  60. package/lib/module/useNavigationState.js.map +1 -1
  61. package/lib/module/useOnAction.js +3 -3
  62. package/lib/module/useOnAction.js.map +1 -1
  63. package/lib/module/useOnGetState.js +6 -3
  64. package/lib/module/useOnGetState.js.map +1 -1
  65. package/lib/module/useOnPreventRemove.js +3 -3
  66. package/lib/module/useOnPreventRemove.js.map +1 -1
  67. package/lib/module/useOnRouteFocus.js +1 -1
  68. package/lib/module/useOnRouteFocus.js.map +1 -1
  69. package/lib/module/useOptionsGetters.js +7 -4
  70. package/lib/module/useOptionsGetters.js.map +1 -1
  71. package/lib/module/usePreventRemove.js +1 -1
  72. package/lib/module/usePreventRemove.js.map +1 -1
  73. package/lib/module/usePreventRemoveContext.js +1 -1
  74. package/lib/module/usePreventRemoveContext.js.map +1 -1
  75. package/lib/module/useRegisterNavigator.js +2 -2
  76. package/lib/module/useRegisterNavigator.js.map +1 -1
  77. package/lib/module/useRoute.js.map +1 -1
  78. package/lib/module/useRouteCache.js +2 -1
  79. package/lib/module/useRouteCache.js.map +1 -1
  80. package/lib/module/useScheduleUpdate.js +1 -1
  81. package/lib/module/useScheduleUpdate.js.map +1 -1
  82. package/lib/module/useStateForPath.js +1 -1
  83. package/lib/module/useStateForPath.js.map +1 -1
  84. package/lib/module/validatePathConfig.js +2 -1
  85. package/lib/module/validatePathConfig.js.map +1 -1
  86. package/lib/typescript/src/BaseNavigationContainer.d.ts +6 -3
  87. package/lib/typescript/src/BaseNavigationContainer.d.ts.map +1 -1
  88. package/lib/typescript/src/ConsumedParamsContext.d.ts +8 -0
  89. package/lib/typescript/src/ConsumedParamsContext.d.ts.map +1 -0
  90. package/lib/typescript/src/EnsureSingleNavigator.d.ts +1 -1
  91. package/lib/typescript/src/EnsureSingleNavigator.d.ts.map +1 -1
  92. package/lib/typescript/src/Group.d.ts +1 -1
  93. package/lib/typescript/src/Group.d.ts.map +1 -1
  94. package/lib/typescript/src/NavigationBuilderContext.d.ts +12 -6
  95. package/lib/typescript/src/NavigationBuilderContext.d.ts.map +1 -1
  96. package/lib/typescript/src/NavigationContainerRefContext.d.ts +1 -1
  97. package/lib/typescript/src/NavigationContainerRefContext.d.ts.map +1 -1
  98. package/lib/typescript/src/NavigationFocusedRouteStateContext.d.ts +4 -4
  99. package/lib/typescript/src/NavigationFocusedRouteStateContext.d.ts.map +1 -1
  100. package/lib/typescript/src/NavigationHelpersContext.d.ts +1 -1
  101. package/lib/typescript/src/NavigationHelpersContext.d.ts.map +1 -1
  102. package/lib/typescript/src/NavigationIndependentTree.d.ts +1 -1
  103. package/lib/typescript/src/NavigationIndependentTree.d.ts.map +1 -1
  104. package/lib/typescript/src/NavigationProvider.d.ts +10 -10
  105. package/lib/typescript/src/NavigationProvider.d.ts.map +1 -1
  106. package/lib/typescript/src/NavigationStateContext.d.ts +3 -3
  107. package/lib/typescript/src/NavigationStateContext.d.ts.map +1 -1
  108. package/lib/typescript/src/PreventRemoveProvider.d.ts +1 -1
  109. package/lib/typescript/src/PreventRemoveProvider.d.ts.map +1 -1
  110. package/lib/typescript/src/SceneView.d.ts +3 -2
  111. package/lib/typescript/src/SceneView.d.ts.map +1 -1
  112. package/lib/typescript/src/Screen.d.ts +1 -1
  113. package/lib/typescript/src/Screen.d.ts.map +1 -1
  114. package/lib/typescript/src/StaticContainer.d.ts +1 -1
  115. package/lib/typescript/src/StaticContainer.d.ts.map +1 -1
  116. package/lib/typescript/src/StaticNavigation.d.ts +123 -92
  117. package/lib/typescript/src/StaticNavigation.d.ts.map +1 -1
  118. package/lib/typescript/src/checkSerializable.d.ts +5 -3
  119. package/lib/typescript/src/checkSerializable.d.ts.map +1 -1
  120. package/lib/typescript/src/createNavigationContainerRef.d.ts +1 -1
  121. package/lib/typescript/src/createNavigationContainerRef.d.ts.map +1 -1
  122. package/lib/typescript/src/createNavigatorFactory.d.ts +17 -5
  123. package/lib/typescript/src/createNavigatorFactory.d.ts.map +1 -1
  124. package/lib/typescript/src/findFocusedRoute.d.ts +3 -3
  125. package/lib/typescript/src/findFocusedRoute.d.ts.map +1 -1
  126. package/lib/typescript/src/getActionFromState.d.ts +4 -4
  127. package/lib/typescript/src/getActionFromState.d.ts.map +1 -1
  128. package/lib/typescript/src/getPathFromState.d.ts +3 -3
  129. package/lib/typescript/src/getPathFromState.d.ts.map +1 -1
  130. package/lib/typescript/src/getPatternParts.d.ts +1 -0
  131. package/lib/typescript/src/getPatternParts.d.ts.map +1 -1
  132. package/lib/typescript/src/getStateFromPath.d.ts +5 -5
  133. package/lib/typescript/src/getStateFromPath.d.ts.map +1 -1
  134. package/lib/typescript/src/getStateFromRouteParams.d.ts +3 -0
  135. package/lib/typescript/src/getStateFromRouteParams.d.ts.map +1 -0
  136. package/lib/typescript/src/index.d.ts +34 -33
  137. package/lib/typescript/src/index.d.ts.map +1 -1
  138. package/lib/typescript/src/theming/ThemeContext.d.ts +1 -1
  139. package/lib/typescript/src/theming/ThemeContext.d.ts.map +1 -1
  140. package/lib/typescript/src/theming/ThemeProvider.d.ts +2 -2
  141. package/lib/typescript/src/theming/ThemeProvider.d.ts.map +1 -1
  142. package/lib/typescript/src/theming/useTheme.d.ts +1 -1
  143. package/lib/typescript/src/theming/useTheme.d.ts.map +1 -1
  144. package/lib/typescript/src/types.d.ts +215 -131
  145. package/lib/typescript/src/types.d.ts.map +1 -1
  146. package/lib/typescript/src/useChildListeners.d.ts +3 -3
  147. package/lib/typescript/src/useChildListeners.d.ts.map +1 -1
  148. package/lib/typescript/src/useComponent.d.ts +1 -1
  149. package/lib/typescript/src/useComponent.d.ts.map +1 -1
  150. package/lib/typescript/src/useDescriptors.d.ts +7 -7
  151. package/lib/typescript/src/useDescriptors.d.ts.map +1 -1
  152. package/lib/typescript/src/useEventEmitter.d.ts +1 -1
  153. package/lib/typescript/src/useEventEmitter.d.ts.map +1 -1
  154. package/lib/typescript/src/useFocusEvents.d.ts +2 -2
  155. package/lib/typescript/src/useFocusEvents.d.ts.map +1 -1
  156. package/lib/typescript/src/useFocusedListenersChildrenAdapter.d.ts +2 -2
  157. package/lib/typescript/src/useFocusedListenersChildrenAdapter.d.ts.map +1 -1
  158. package/lib/typescript/src/useIsFocused.d.ts +3 -0
  159. package/lib/typescript/src/useIsFocused.d.ts.map +1 -1
  160. package/lib/typescript/src/useKeyedChildListeners.d.ts +3 -3
  161. package/lib/typescript/src/useKeyedChildListeners.d.ts.map +1 -1
  162. package/lib/typescript/src/useNavigation.d.ts +5 -3
  163. package/lib/typescript/src/useNavigation.d.ts.map +1 -1
  164. package/lib/typescript/src/useNavigationBuilder.d.ts +24 -24
  165. package/lib/typescript/src/useNavigationBuilder.d.ts.map +1 -1
  166. package/lib/typescript/src/useNavigationCache.d.ts +3 -3
  167. package/lib/typescript/src/useNavigationCache.d.ts.map +1 -1
  168. package/lib/typescript/src/useNavigationContainerRef.d.ts +1 -1
  169. package/lib/typescript/src/useNavigationContainerRef.d.ts.map +1 -1
  170. package/lib/typescript/src/useNavigationHelpers.d.ts +19 -19
  171. package/lib/typescript/src/useNavigationHelpers.d.ts.map +1 -1
  172. package/lib/typescript/src/useNavigationState.d.ts +2 -2
  173. package/lib/typescript/src/useNavigationState.d.ts.map +1 -1
  174. package/lib/typescript/src/useOnAction.d.ts +9 -9
  175. package/lib/typescript/src/useOnAction.d.ts.map +1 -1
  176. package/lib/typescript/src/useOnGetState.d.ts +1 -1
  177. package/lib/typescript/src/useOnGetState.d.ts.map +1 -1
  178. package/lib/typescript/src/useOnPreventRemove.d.ts +3 -3
  179. package/lib/typescript/src/useOnPreventRemove.d.ts.map +1 -1
  180. package/lib/typescript/src/useOnRouteFocus.d.ts +6 -6
  181. package/lib/typescript/src/useOnRouteFocus.d.ts.map +1 -1
  182. package/lib/typescript/src/useOptionsGetters.d.ts +1 -1
  183. package/lib/typescript/src/useOptionsGetters.d.ts.map +1 -1
  184. package/lib/typescript/src/usePreventRemoveContext.d.ts +1 -1
  185. package/lib/typescript/src/useRoute.d.ts +2 -2
  186. package/lib/typescript/src/useRoute.d.ts.map +1 -1
  187. package/lib/typescript/src/useRouteCache.d.ts +4 -4
  188. package/lib/typescript/src/useRouteCache.d.ts.map +1 -1
  189. package/lib/typescript/src/useScheduleUpdate.d.ts.map +1 -1
  190. package/lib/typescript/src/useStateForPath.d.ts +1 -1
  191. package/lib/typescript/src/useStateForPath.d.ts.map +1 -1
  192. package/lib/typescript/src/utilities.d.ts +45 -5
  193. package/lib/typescript/src/utilities.d.ts.map +1 -1
  194. package/lib/typescript/src/validatePathConfig.d.ts.map +1 -1
  195. package/package.json +23 -20
  196. package/src/BaseNavigationContainer.tsx +337 -326
  197. package/src/ConsumedParamsContext.tsx +10 -0
  198. package/src/NavigationBuilderContext.tsx +14 -8
  199. package/src/NavigationFocusedRouteStateContext.tsx +4 -4
  200. package/src/NavigationIndependentTree.tsx +8 -5
  201. package/src/NavigationProvider.tsx +17 -3
  202. package/src/NavigationStateContext.tsx +5 -6
  203. package/src/PreventRemoveProvider.tsx +3 -3
  204. package/src/SceneView.tsx +58 -56
  205. package/src/StaticNavigation.tsx +488 -250
  206. package/src/checkSerializable.tsx +22 -12
  207. package/src/createNavigatorFactory.tsx +83 -8
  208. package/src/findFocusedRoute.tsx +13 -8
  209. package/src/getActionFromState.tsx +68 -39
  210. package/src/getPathFromState.tsx +91 -27
  211. package/src/getPatternParts.tsx +8 -0
  212. package/src/getStateFromPath.tsx +555 -180
  213. package/src/getStateFromRouteParams.tsx +60 -0
  214. package/src/index.tsx +47 -5
  215. package/src/theming/useTheme.tsx +1 -1
  216. package/src/types.tsx +541 -338
  217. package/src/useDescriptors.tsx +27 -12
  218. package/src/useEventEmitter.tsx +45 -36
  219. package/src/useFocusEvents.tsx +8 -2
  220. package/src/useFocusedListenersChildrenAdapter.tsx +2 -2
  221. package/src/useIsFocused.tsx +14 -21
  222. package/src/useNavigation.tsx +8 -4
  223. package/src/useNavigationBuilder.tsx +220 -132
  224. package/src/useNavigationCache.tsx +6 -6
  225. package/src/useNavigationHelpers.tsx +1 -1
  226. package/src/useNavigationIndependentTree.tsx +1 -1
  227. package/src/useNavigationState.tsx +11 -7
  228. package/src/useOnAction.tsx +10 -10
  229. package/src/useOnGetState.tsx +5 -3
  230. package/src/useOnPreventRemove.tsx +3 -3
  231. package/src/useOnRouteFocus.tsx +10 -12
  232. package/src/useOptionsGetters.tsx +7 -4
  233. package/src/usePreventRemove.tsx +1 -1
  234. package/src/usePreventRemoveContext.tsx +1 -1
  235. package/src/useRegisterNavigator.tsx +2 -2
  236. package/src/useRoute.tsx +4 -2
  237. package/src/useRouteCache.tsx +2 -1
  238. package/src/useScheduleUpdate.tsx +1 -3
  239. package/src/useStateForPath.tsx +1 -1
  240. package/src/utilities.tsx +101 -5
  241. package/src/validatePathConfig.tsx +1 -0
  242. package/lib/module/CurrentRenderContext.js +0 -10
  243. package/lib/module/CurrentRenderContext.js.map +0 -1
  244. package/lib/module/useCurrentRender.js +0 -19
  245. package/lib/module/useCurrentRender.js.map +0 -1
  246. package/lib/typescript/src/CurrentRenderContext.d.ts +0 -9
  247. package/lib/typescript/src/CurrentRenderContext.d.ts.map +0 -1
  248. package/lib/typescript/src/useCurrentRender.d.ts +0 -14
  249. package/lib/typescript/src/useCurrentRender.d.ts.map +0 -1
  250. package/src/CurrentRenderContext.tsx +0 -9
  251. package/src/useCurrentRender.tsx +0 -31
@@ -16,11 +16,11 @@ import type { EventMapCore } from './types';
16
16
  import type { NavigationEventEmitter } from './useEventEmitter';
17
17
  import { shouldPreventRemove, useOnPreventRemove } from './useOnPreventRemove';
18
18
 
19
- type Options = {
20
- router: Router<NavigationState, NavigationAction>;
21
- key?: string;
22
- getState: () => NavigationState;
23
- setState: (state: NavigationState | PartialState<NavigationState>) => void;
19
+ type Options<State extends NavigationState> = {
20
+ router: Router<State, NavigationAction>;
21
+ key?: string | undefined;
22
+ getState: () => State;
23
+ setState: (state: State | PartialState<State>) => void;
24
24
  actionListeners: ChildActionListener[];
25
25
  beforeRemoveListeners: Record<string, ChildBeforeRemoveListener | undefined>;
26
26
  routerConfigOptions: RouterConfigOptions;
@@ -36,7 +36,7 @@ type Options = {
36
36
  *
37
37
  * When the action handler handles as action, it returns `true`, otherwise `false`.
38
38
  */
39
- export function useOnAction({
39
+ export function useOnAction<State extends NavigationState>({
40
40
  router,
41
41
  getState,
42
42
  setState,
@@ -45,13 +45,13 @@ export function useOnAction({
45
45
  beforeRemoveListeners,
46
46
  routerConfigOptions,
47
47
  emitter,
48
- }: Options) {
48
+ }: Options<State>) {
49
49
  const {
50
50
  onAction: onActionParent,
51
51
  onRouteFocus: onRouteFocusParent,
52
52
  addListener: addListenerParent,
53
53
  onDispatchAction,
54
- } = React.useContext(NavigationBuilderContext);
54
+ } = React.use(NavigationBuilderContext);
55
55
 
56
56
  const routerConfigOptionsRef =
57
57
  React.useRef<RouterConfigOptions>(routerConfigOptions);
@@ -132,7 +132,7 @@ export function useOnAction({
132
132
  for (let i = actionListeners.length - 1; i >= 0; i--) {
133
133
  const listener = actionListeners[i];
134
134
 
135
- if (listener(action, visitedNavigators)) {
135
+ if (listener?.(action, visitedNavigators)) {
136
136
  return true;
137
137
  }
138
138
  }
@@ -160,7 +160,7 @@ export function useOnAction({
160
160
  beforeRemoveListeners,
161
161
  });
162
162
 
163
- React.useEffect(
163
+ React.useInsertionEffect(
164
164
  () => addListenerParent?.('action', onAction),
165
165
  [addListenerParent, onAction]
166
166
  );
@@ -14,8 +14,8 @@ type Options = {
14
14
  };
15
15
 
16
16
  export function useOnGetState({ getState, getStateListeners }: Options) {
17
- const { addKeyedListener } = React.useContext(NavigationBuilderContext);
18
- const route = React.useContext(NavigationRouteContext);
17
+ const { addKeyedListener } = React.use(NavigationBuilderContext);
18
+ const route = React.use(NavigationRouteContext);
19
19
  const key = route ? route.key : 'root';
20
20
 
21
21
  const getRehydratedState = React.useCallback(() => {
@@ -39,7 +39,9 @@ export function useOnGetState({ getState, getStateListeners }: Options) {
39
39
  return { ...state, routes };
40
40
  }, [getState, getStateListeners]);
41
41
 
42
- React.useEffect(() => {
42
+ // Use insertion effect to preserve the listener under `<Activity mode="hidden">`
43
+ // So `getRootState` will still return state of nested navigators
44
+ React.useInsertionEffect(() => {
43
45
  return addKeyedListener?.('getState', key, getRehydratedState);
44
46
  }, [addKeyedListener, getRehydratedState, key]);
45
47
  }
@@ -78,11 +78,11 @@ export function useOnPreventRemove({
78
78
  emitter,
79
79
  beforeRemoveListeners,
80
80
  }: Options) {
81
- const { addKeyedListener } = React.useContext(NavigationBuilderContext);
82
- const route = React.useContext(NavigationRouteContext);
81
+ const { addKeyedListener } = React.use(NavigationBuilderContext);
82
+ const route = React.use(NavigationRouteContext);
83
83
  const routeKey = route?.key;
84
84
 
85
- React.useEffect(() => {
85
+ React.useInsertionEffect(() => {
86
86
  if (routeKey) {
87
87
  return addKeyedListener?.('beforeRemove', routeKey, (action) => {
88
88
  const state = getState();
@@ -7,11 +7,11 @@ import * as React from 'react';
7
7
 
8
8
  import { NavigationBuilderContext } from './NavigationBuilderContext';
9
9
 
10
- type Options<Action extends NavigationAction> = {
11
- router: Router<NavigationState, Action>;
12
- getState: () => NavigationState;
13
- setState: (state: NavigationState) => void;
14
- key?: string;
10
+ type Options<State extends NavigationState, Action extends NavigationAction> = {
11
+ router: Router<State, Action>;
12
+ getState: () => State;
13
+ setState: (state: State) => void;
14
+ key?: string | undefined;
15
15
  };
16
16
 
17
17
  /**
@@ -19,13 +19,11 @@ type Options<Action extends NavigationAction> = {
19
19
  * Focus action needs to be treated specially, coz when a nested route is focused,
20
20
  * the parent navigators also needs to be focused.
21
21
  */
22
- export function useOnRouteFocus<Action extends NavigationAction>({
23
- router,
24
- getState,
25
- key: sourceRouteKey,
26
- setState,
27
- }: Options<Action>) {
28
- const { onRouteFocus: onRouteFocusParent } = React.useContext(
22
+ export function useOnRouteFocus<
23
+ State extends NavigationState,
24
+ Action extends NavigationAction,
25
+ >({ router, getState, key: sourceRouteKey, setState }: Options<State, Action>) {
26
+ const { onRouteFocus: onRouteFocusParent } = React.use(
29
27
  NavigationBuilderContext
30
28
  );
31
29
 
@@ -17,8 +17,8 @@ export function useOptionsGetters({ key, options, navigation }: Options) {
17
17
  Record<string, () => object | undefined | null>
18
18
  >({});
19
19
 
20
- const { onOptionsChange } = React.useContext(NavigationBuilderContext);
21
- const { addOptionsGetter: parentAddOptionsGetter } = React.useContext(
20
+ const { onOptionsChange } = React.use(NavigationBuilderContext);
21
+ const { addOptionsGetter: parentAddOptionsGetter } = React.use(
22
22
  NavigationStateContext
23
23
  );
24
24
 
@@ -69,8 +69,11 @@ export function useOptionsGetters({ key, options, navigation }: Options) {
69
69
  return optionsRef.current;
70
70
  }, [navigation, getOptionsFromListener]);
71
71
 
72
- React.useEffect(() => {
73
- return parentAddOptionsGetter?.(key!, getCurrentOptions);
72
+ React.useInsertionEffect(() => {
73
+ // We don't have a parent at the root
74
+ if (key != null) {
75
+ return parentAddOptionsGetter?.(key, getCurrentOptions);
76
+ }
74
77
  }, [getCurrentOptions, parentAddOptionsGetter, key]);
75
78
 
76
79
  const addOptionsGetter = React.useCallback(
@@ -44,7 +44,7 @@ export function usePreventRemove(
44
44
  callback({ data: e.data });
45
45
  });
46
46
 
47
- React.useEffect(
47
+ React.useInsertionEffect(
48
48
  () => navigation?.addListener('beforeRemove', beforeRemoveListener),
49
49
  [navigation, beforeRemoveListener]
50
50
  );
@@ -3,7 +3,7 @@ import * as React from 'react';
3
3
  import { PreventRemoveContext } from './PreventRemoveContext';
4
4
 
5
5
  export function usePreventRemoveContext() {
6
- const value = React.useContext(PreventRemoveContext);
6
+ const value = React.use(PreventRemoveContext);
7
7
 
8
8
  if (value == null) {
9
9
  throw new Error(
@@ -9,7 +9,7 @@ import { SingleNavigatorContext } from './EnsureSingleNavigator';
9
9
  */
10
10
  export function useRegisterNavigator() {
11
11
  const [key] = React.useState(() => nanoid());
12
- const container = React.useContext(SingleNavigatorContext);
12
+ const container = React.use(SingleNavigatorContext);
13
13
 
14
14
  if (container === undefined) {
15
15
  throw new Error(
@@ -17,7 +17,7 @@ export function useRegisterNavigator() {
17
17
  );
18
18
  }
19
19
 
20
- React.useEffect(() => {
20
+ React.useInsertionEffect(() => {
21
21
  const { register, unregister } = container;
22
22
 
23
23
  register(key);
package/src/useRoute.tsx CHANGED
@@ -22,8 +22,10 @@ type AllRouteNames<ParamList extends {}> = RouteForName<
22
22
  */
23
23
  export function useRoute<
24
24
  const ParamList extends {} = RootParamList,
25
- const RouteName extends AllRouteNames<ParamList> = AllRouteNames<ParamList>,
26
- >(name: RouteName): RouteForName<ParamList, RouteName>;
25
+ const RouteName extends string = string,
26
+ >(
27
+ name: RouteName & AllRouteNames<ParamList>
28
+ ): RouteForName<ParamList, RouteName>;
27
29
  export function useRoute<
28
30
  const ParamList extends {} = RootParamList,
29
31
  >(): {} extends ParamList
@@ -36,9 +36,10 @@ export function useRouteCache<State extends NavigationState>(
36
36
  proxy = routeWithoutState;
37
37
  }
38
38
 
39
- if (process.env.NODE_ENV !== 'production') {
39
+ if (process.env.NODE_ENV !== 'production' && proxy !== previous) {
40
40
  // FIXME: since the state is updated with mutation, the route object cannot be frozen
41
41
  // As a workaround, loop through the object and make the properties readonly
42
+ // Only needed once per proxy - skip if we're reusing a previously-frozen one
42
43
  for (const key in proxy) {
43
44
  // @ts-expect-error: this is fine since we are looping through the object
44
45
  const value = proxy[key];
@@ -10,9 +10,7 @@ import { NavigationBuilderContext } from './NavigationBuilderContext';
10
10
  * Then we call setState during after the component updates.
11
11
  */
12
12
  export function useScheduleUpdate(callback: () => void) {
13
- const { scheduleUpdate, flushUpdates } = React.useContext(
14
- NavigationBuilderContext
15
- );
13
+ const { scheduleUpdate, flushUpdates } = React.use(NavigationBuilderContext);
16
14
 
17
15
  // FIXME: This is potentially unsafe
18
16
  // However, since we are using sync store, it might be fine
@@ -9,7 +9,7 @@ import { NavigationFocusedRouteStateContext } from './NavigationFocusedRouteStat
9
9
  * @returns Minimal state to build a path for the current route.
10
10
  */
11
11
  export function useStateForPath() {
12
- const state = React.useContext(NavigationFocusedRouteStateContext);
12
+ const state = React.use(NavigationFocusedRouteStateContext);
13
13
 
14
14
  return state;
15
15
  }
package/src/utilities.tsx CHANGED
@@ -35,6 +35,16 @@ export type NotUndefined<T> = T extends undefined ? never : T;
35
35
 
36
36
  export type AnyToUnknown<T> = 0 extends 1 & T ? unknown : T;
37
37
 
38
+ export type RequiredKeys<T extends object> = {
39
+ [K in keyof T]-?: {} extends Pick<T, K> ? never : K;
40
+ }[keyof T];
41
+
42
+ export type UndefinedIfAllOptional<T> = T extends object
43
+ ? RequiredKeys<T> extends never
44
+ ? T | undefined
45
+ : T
46
+ : T;
47
+
38
48
  /**
39
49
  * Check if a function type has arguments.
40
50
  */
@@ -66,6 +76,24 @@ type ExtractSegmentParam<Segment extends string> =
66
76
  ? { [K in StripRegex<Param>]: string }
67
77
  : {};
68
78
 
79
+ export type StandardSchemaValidationResult<Output> =
80
+ | { value: Output; issues?: undefined }
81
+ | { value?: undefined; issues: readonly unknown[] };
82
+
83
+ export type StandardSchemaV1<Input = unknown, Output = Input> = {
84
+ readonly '~standard': {
85
+ readonly version: 1;
86
+ readonly vendor: string;
87
+ readonly validate: (
88
+ value: Input
89
+ ) =>
90
+ | StandardSchemaValidationResult<Output>
91
+ | Promise<StandardSchemaValidationResult<Output>>;
92
+ };
93
+ };
94
+
95
+ export type QueryParamInput = string | string[] | null | undefined;
96
+
69
97
  /**
70
98
  * Extract path params from a path string.
71
99
  * e.g. `/foo/:userId/:postId` -> `{ userId: string; postId: string }`
@@ -78,16 +106,72 @@ export type ExtractParamStrings<Path extends string> =
78
106
  : ExtractSegmentParam<Path>;
79
107
 
80
108
  /**
81
- * Extract the parsed params type from base params and parse functions.
82
- * Applies the return type of parse functions to the corresponding params.
109
+ * Get the type of params based on the `parse` config and the path pattern.
83
110
  */
84
111
  export type ExtractParamsType<Params, Parse> = {
112
+ /**
113
+ * Base param types from path pattern
114
+ * Refine the type based on standard schema, then parse function
115
+ * Otherwise, use the type from path pattern
116
+ */
85
117
  [K in keyof Params]: K extends keyof Parse
86
- ? Parse[K] extends (value: string) => infer R
118
+ ? Parse[K] extends StandardSchemaV1<unknown, infer R>
87
119
  ? R
88
- : Params[K]
120
+ : Parse[K] extends (value: string) => infer R
121
+ ? R
122
+ : Params[K]
89
123
  : Params[K];
90
- };
124
+ } & // Query params are the parse keys not present in the path pattern. When there
125
+ // are none (the common case), skip building the query param mapped types.
126
+ ([Exclude<keyof Parse, keyof Params>] extends [never]
127
+ ? {}
128
+ : {
129
+ /**
130
+ * Optional param types not in path pattern (for query params)
131
+ */
132
+ [K in QueryParamOptionalKeys<Params, Parse>]?: QueryParamValue<
133
+ Parse[K]
134
+ >;
135
+ } & {
136
+ /**
137
+ * Required param types not in path pattern (for query params)
138
+ */
139
+ [K in QueryParamRequiredKeys<Params, Parse>]: QueryParamValue<Parse[K]>;
140
+ });
141
+
142
+ type QueryParamValue<ParseValue> =
143
+ ParseValue extends StandardSchemaV1<unknown, infer R>
144
+ ? R
145
+ : ParseValue extends (value: string) => infer R
146
+ ? R
147
+ : never;
148
+
149
+ /**
150
+ * For schema, it's optional if the output has `undefined`, otherwise required
151
+ * For parse function, it's always optional as it can't say if it's required or not
152
+ */
153
+ type QueryParamOptionalKeys<Params, Parse> = {
154
+ [K in Exclude<keyof Parse, keyof Params>]: Parse[K] extends StandardSchemaV1<
155
+ unknown,
156
+ infer R
157
+ >
158
+ ? undefined extends R
159
+ ? K
160
+ : never
161
+ : Parse[K] extends (value: string) => unknown
162
+ ? K
163
+ : never;
164
+ }[Exclude<keyof Parse, keyof Params>];
165
+
166
+ /**
167
+ * Exclude optional keys to get required keys
168
+ * For schema, it's required if the output doesn't have `undefined`, otherwise optional
169
+ * It doesn't include parse functions (as they are always optional)
170
+ */
171
+ type QueryParamRequiredKeys<Params, Parse> = Exclude<
172
+ Exclude<keyof Parse, keyof Params>,
173
+ QueryParamOptionalKeys<Params, Parse>
174
+ >;
91
175
 
92
176
  /**
93
177
  * Infer the path string from a linking config.
@@ -101,6 +185,18 @@ export type InferPath<T> = T extends { path: infer P extends string }
101
185
  */
102
186
  export type InferParse<T> = T extends { parse: infer P } ? P : {};
103
187
 
188
+ export type InferParamsFromLinking<T> = T extends {
189
+ path: infer P extends string;
190
+ }
191
+ ? UndefinedIfAllOptional<
192
+ ExtractParamsType<ExtractParamStrings<P>, InferParse<T>>
193
+ >
194
+ : T extends string
195
+ ? UndefinedIfAllOptional<
196
+ ExtractParamsType<ExtractParamStrings<T>, undefined>
197
+ >
198
+ : undefined;
199
+
104
200
  /**
105
201
  * Infer the params type from a screen component or nested navigator.
106
202
  */
@@ -15,6 +15,7 @@ export function validatePathConfig(config: unknown, root = true) {
15
15
  exact: 'boolean',
16
16
  stringify: 'object',
17
17
  parse: 'object',
18
+ shared: 'boolean',
18
19
  }),
19
20
  };
20
21
 
@@ -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
- }