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

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 (85) hide show
  1. package/lib/module/BaseNavigationContainer.js.map +1 -1
  2. package/lib/module/NavigationBuilderContext.js.map +1 -1
  3. package/lib/module/NavigationIndependentTree.js +8 -4
  4. package/lib/module/NavigationIndependentTree.js.map +1 -1
  5. package/lib/module/NavigationProvider.js +14 -3
  6. package/lib/module/NavigationProvider.js.map +1 -1
  7. package/lib/module/NavigationStateContext.js.map +1 -1
  8. package/lib/module/SceneView.js +6 -39
  9. package/lib/module/SceneView.js.map +1 -1
  10. package/lib/module/StaticNavigation.js +13 -1
  11. package/lib/module/StaticNavigation.js.map +1 -1
  12. package/lib/module/getPathFromState.js +24 -2
  13. package/lib/module/getPathFromState.js.map +1 -1
  14. package/lib/module/getStateFromPath.js +157 -72
  15. package/lib/module/getStateFromPath.js.map +1 -1
  16. package/lib/module/getStateFromRouteParams.js +24 -0
  17. package/lib/module/getStateFromRouteParams.js.map +1 -0
  18. package/lib/module/index.js.map +1 -1
  19. package/lib/module/types.js.map +1 -1
  20. package/lib/module/useIsFocused.js +7 -12
  21. package/lib/module/useIsFocused.js.map +1 -1
  22. package/lib/module/useNavigationBuilder.js +71 -28
  23. package/lib/module/useNavigationBuilder.js.map +1 -1
  24. package/lib/module/useOnAction.js.map +1 -1
  25. package/lib/module/useOnRouteFocus.js.map +1 -1
  26. package/lib/typescript/src/NavigationBuilderContext.d.ts +5 -5
  27. package/lib/typescript/src/NavigationBuilderContext.d.ts.map +1 -1
  28. package/lib/typescript/src/NavigationFocusedRouteStateContext.d.ts +4 -4
  29. package/lib/typescript/src/NavigationFocusedRouteStateContext.d.ts.map +1 -1
  30. package/lib/typescript/src/NavigationIndependentTree.d.ts.map +1 -1
  31. package/lib/typescript/src/NavigationProvider.d.ts +4 -4
  32. package/lib/typescript/src/NavigationProvider.d.ts.map +1 -1
  33. package/lib/typescript/src/NavigationStateContext.d.ts +3 -3
  34. package/lib/typescript/src/NavigationStateContext.d.ts.map +1 -1
  35. package/lib/typescript/src/SceneView.d.ts.map +1 -1
  36. package/lib/typescript/src/StaticNavigation.d.ts +13 -11
  37. package/lib/typescript/src/StaticNavigation.d.ts.map +1 -1
  38. package/lib/typescript/src/findFocusedRoute.d.ts +3 -3
  39. package/lib/typescript/src/findFocusedRoute.d.ts.map +1 -1
  40. package/lib/typescript/src/getActionFromState.d.ts +3 -3
  41. package/lib/typescript/src/getActionFromState.d.ts.map +1 -1
  42. package/lib/typescript/src/getPathFromState.d.ts +2 -2
  43. package/lib/typescript/src/getPathFromState.d.ts.map +1 -1
  44. package/lib/typescript/src/getStateFromPath.d.ts +3 -3
  45. package/lib/typescript/src/getStateFromPath.d.ts.map +1 -1
  46. package/lib/typescript/src/getStateFromRouteParams.d.ts +3 -0
  47. package/lib/typescript/src/getStateFromRouteParams.d.ts.map +1 -0
  48. package/lib/typescript/src/index.d.ts +1 -0
  49. package/lib/typescript/src/index.d.ts.map +1 -1
  50. package/lib/typescript/src/types.d.ts +64 -64
  51. package/lib/typescript/src/types.d.ts.map +1 -1
  52. package/lib/typescript/src/useDescriptors.d.ts +2 -2
  53. package/lib/typescript/src/useIsFocused.d.ts +3 -0
  54. package/lib/typescript/src/useIsFocused.d.ts.map +1 -1
  55. package/lib/typescript/src/useNavigationBuilder.d.ts +17 -17
  56. package/lib/typescript/src/useNavigationBuilder.d.ts.map +1 -1
  57. package/lib/typescript/src/useNavigationHelpers.d.ts +15 -15
  58. package/lib/typescript/src/useOnAction.d.ts +6 -6
  59. package/lib/typescript/src/useOnAction.d.ts.map +1 -1
  60. package/lib/typescript/src/useOnRouteFocus.d.ts +6 -6
  61. package/lib/typescript/src/useOnRouteFocus.d.ts.map +1 -1
  62. package/lib/typescript/src/useRouteCache.d.ts +2 -2
  63. package/lib/typescript/src/utilities.d.ts +35 -3
  64. package/lib/typescript/src/utilities.d.ts.map +1 -1
  65. package/package.json +10 -8
  66. package/src/BaseNavigationContainer.tsx +1 -1
  67. package/src/NavigationBuilderContext.tsx +7 -8
  68. package/src/NavigationFocusedRouteStateContext.tsx +4 -4
  69. package/src/NavigationIndependentTree.tsx +8 -5
  70. package/src/NavigationProvider.tsx +17 -3
  71. package/src/NavigationStateContext.tsx +5 -6
  72. package/src/SceneView.tsx +6 -36
  73. package/src/StaticNavigation.tsx +48 -17
  74. package/src/findFocusedRoute.tsx +3 -3
  75. package/src/getActionFromState.tsx +7 -7
  76. package/src/getPathFromState.tsx +52 -8
  77. package/src/getStateFromPath.tsx +254 -96
  78. package/src/getStateFromRouteParams.tsx +60 -0
  79. package/src/index.tsx +1 -0
  80. package/src/types.tsx +164 -120
  81. package/src/useIsFocused.tsx +14 -21
  82. package/src/useNavigationBuilder.tsx +116 -41
  83. package/src/useOnAction.tsx +7 -7
  84. package/src/useOnRouteFocus.tsx +9 -11
  85. package/src/utilities.tsx +72 -4
@@ -28,6 +28,7 @@ import type {
28
28
  InferParse,
29
29
  InferPath,
30
30
  KeysOf,
31
+ StandardSchemaV1,
31
32
  UnionToIntersection,
32
33
  ValidPathPattern,
33
34
  } from './utilities';
@@ -44,10 +45,10 @@ type ParamsForScreenComponent<T> = T extends (...args: any[]) => any
44
45
 
45
46
  type ParamsForScreen<T> =
46
47
  // Nested navigator in screen property
47
- T extends { screen: StaticNavigation<any, any, any> }
48
+ T extends { screen: StaticNavigationBase }
48
49
  ? NavigatorScreenParams<StaticParamList<T['screen']>> | undefined
49
50
  : // Direct nested navigator
50
- T extends StaticNavigation<any, any, any>
51
+ T extends StaticNavigationBase
51
52
  ? NavigatorScreenParams<StaticParamList<T>> | undefined
52
53
  : T extends {
53
54
  screen: React.ComponentType<any>;
@@ -75,7 +76,7 @@ type ParamsForConfig<Linking, Screen> = undefined extends Linking
75
76
  : // Only infer params from linking if it's a pattern (i.e., contains ':')
76
77
  // This avoids inferring non-literals like 'string'
77
78
  Linking extends ValidPathPattern | { path: ValidPathPattern }
78
- ? Screen extends StaticNavigation<any, any, any>
79
+ ? Screen extends StaticNavigationBase
79
80
  ? FlatType<ParamsForLinking<Linking>> & ParamsForScreen<Screen>
80
81
  : // Don't combine if `undefined`, otherwise it'll result in `never`
81
82
  undefined extends ParamsForScreen<Screen>
@@ -147,7 +148,7 @@ type StaticScreenConfigLinkingAlias = {
147
148
  */
148
149
  exact?: boolean;
149
150
  /**
150
- * An object mapping the param name to a function which parses the param value.
151
+ * An object mapping the param name to a parser function or a Standard Schema.
151
152
  *
152
153
  * @example
153
154
  * ```js
@@ -157,7 +158,11 @@ type StaticScreenConfigLinkingAlias = {
157
158
  * }
158
159
  * ```
159
160
  */
160
- parse?: Record<string, (value: string) => unknown>;
161
+ parse?: Record<
162
+ string,
163
+ | ((value: string) => unknown)
164
+ | StandardSchemaV1<string | string[] | null | undefined, unknown>
165
+ >;
161
166
  /**
162
167
  * An object mapping the param name to a function which converts the param value to a string.
163
168
  * By default, all params are converted to strings using `String(value)`.
@@ -332,7 +337,10 @@ type StaticConfigScreens<
332
337
  | StaticScreenConfig<
333
338
  | {
334
339
  path: string;
335
- parse?: Record<string, (value: string) => any>;
340
+ parse?: Record<
341
+ string,
342
+ ((value: string) => any) | StandardSchemaV1<any, any>
343
+ >;
336
344
  }
337
345
  | string
338
346
  | undefined,
@@ -503,13 +511,17 @@ export type StaticParamList<
503
511
  ParamListForGroups<T['config']['groups']>
504
512
  >;
505
513
 
506
- export type StaticNavigation<NavigatorProps, GroupProps, ScreenProps> = {
507
- Navigator: React.ComponentType<NavigatorProps>;
508
- Group: React.ComponentType<GroupProps>;
509
- Screen: React.ComponentType<ScreenProps>;
514
+ type StaticNavigationBase = {
510
515
  config: StaticConfig<NavigatorTypeBagBase>;
511
516
  };
512
517
 
518
+ export type StaticNavigation<NavigatorProps, GroupProps, ScreenProps> =
519
+ StaticNavigationBase & {
520
+ Navigator: React.ComponentType<NavigatorProps>;
521
+ Group: React.ComponentType<GroupProps>;
522
+ Screen: React.ComponentType<ScreenProps>;
523
+ };
524
+
513
525
  const MemoizedScreen = React.memo(
514
526
  <T extends React.ComponentType<any>>({ component }: { component: T }) => {
515
527
  const route = useRoute();
@@ -589,10 +601,12 @@ const getItemsFromScreens = (
589
601
  * @param displayName Name of the component to be displayed in React DevTools.
590
602
  * @returns A component which renders the navigator.
591
603
  */
592
- export function createComponentForStaticNavigation(
593
- tree: StaticNavigation<any, any, any>,
604
+ export function createComponentForStaticNavigation<
605
+ T extends StaticNavigation<any, any, any>,
606
+ >(
607
+ tree: T,
594
608
  displayName: string
595
- ): React.ComponentType<{}> {
609
+ ): React.ComponentType<Omit<React.ComponentProps<T['Navigator']>, 'children'>> {
596
610
  const { Navigator, Group, Screen, config } = tree;
597
611
  const { screens, groups, ...rest } = config;
598
612
 
@@ -637,10 +651,27 @@ export function createComponentForStaticNavigation(
637
651
  }
638
652
  }
639
653
 
640
- const NavigatorComponent = () => {
654
+ const NavigatorComponent = ({ children: _, ...props }: typeof rest) => {
641
655
  const children = items.map((item) => item());
642
656
 
643
- return <Navigator {...rest}>{children}</Navigator>;
657
+ const screenOptions =
658
+ typeof props.screenOptions === 'function' ||
659
+ typeof rest.screenOptions === 'function'
660
+ ? (options: unknown) => ({
661
+ ...(typeof rest.screenOptions === 'function'
662
+ ? rest.screenOptions(options)
663
+ : rest.screenOptions),
664
+ ...(typeof props.screenOptions === 'function'
665
+ ? props.screenOptions(options)
666
+ : props.screenOptions),
667
+ })
668
+ : { ...rest.screenOptions, ...props.screenOptions };
669
+
670
+ return (
671
+ <Navigator {...rest} {...props} screenOptions={screenOptions}>
672
+ {children}
673
+ </Navigator>
674
+ );
644
675
  };
645
676
 
646
677
  NavigatorComponent.displayName = displayName;
@@ -699,7 +730,7 @@ type TreeForPathConfig = {
699
730
  export function createPathConfigForStaticNavigation(
700
731
  tree: TreeForPathConfig,
701
732
  options?: {
702
- initialRouteName?: string;
733
+ initialRouteName?: string | undefined;
703
734
  },
704
735
  auto?: boolean
705
736
  ): PathConfigMap<ParamListBase> | undefined {
@@ -708,7 +739,7 @@ export function createPathConfigForStaticNavigation(
708
739
 
709
740
  const createPathConfigForTree = (
710
741
  t: TreeForPathConfig,
711
- o: { initialRouteName?: string } | undefined,
742
+ o: { initialRouteName?: string | undefined } | undefined,
712
743
  // If a screen is a leaf node, but inside a screen with path,
713
744
  // It should not be used for initial detection
714
745
  skipInitialDetection: boolean
@@ -2,10 +2,10 @@ import type { InitialState } from '@react-navigation/routers';
2
2
 
3
3
  type Result =
4
4
  | {
5
- key?: string;
5
+ key?: string | undefined;
6
6
  name: string;
7
- params?: object;
8
- path?: string;
7
+ params?: object | undefined;
8
+ path?: string | undefined;
9
9
  }
10
10
  | undefined;
11
11
 
@@ -10,12 +10,12 @@ import type {
10
10
  import type { NavigatorScreenParams, PathConfig, PathConfigMap } from './types';
11
11
 
12
12
  type ConfigItem = {
13
- initialRouteName?: string;
14
- screens?: Record<string, ConfigItem>;
13
+ initialRouteName?: string | undefined;
14
+ screens?: Record<string, ConfigItem> | undefined;
15
15
  };
16
16
 
17
17
  type Options = {
18
- initialRouteName?: string;
18
+ initialRouteName?: string | undefined;
19
19
  screens: PathConfigMap<object>;
20
20
  };
21
21
 
@@ -23,8 +23,8 @@ type NavigateAction<State extends NavigationState> = {
23
23
  type: 'NAVIGATE';
24
24
  payload: {
25
25
  name: string;
26
- params?: NavigatorScreenParams<State>;
27
- path?: string;
26
+ params?: NavigatorScreenParams<State> | undefined;
27
+ path?: string | undefined;
28
28
  };
29
29
  };
30
30
 
@@ -69,8 +69,8 @@ export function getActionFromState(
69
69
  | {
70
70
  name: string;
71
71
  params: NavigatorScreenParams<ParamListBase>;
72
- path?: string;
73
- pop?: boolean;
72
+ path?: string | undefined;
73
+ pop?: boolean | undefined;
74
74
  }
75
75
  | undefined = route
76
76
  ? { name: route.name, path: route.path, params }
@@ -6,12 +6,13 @@ import type {
6
6
  import * as queryString from 'query-string';
7
7
 
8
8
  import { getPatternParts, type PatternPart } from './getPatternParts';
9
+ import { getStateFromRouteParams } from './getStateFromRouteParams';
9
10
  import type { PathConfig, PathConfigMap } from './types';
10
11
  import { validatePathConfig } from './validatePathConfig';
11
12
 
12
13
  type Options<ParamList extends {}> = {
13
- path?: string;
14
- initialRouteName?: string;
14
+ path?: string | undefined;
15
+ initialRouteName?: string | undefined;
15
16
  screens: PathConfigMap<ParamList>;
16
17
  };
17
18
 
@@ -20,12 +21,14 @@ type State = NavigationState | Omit<PartialState<NavigationState>, 'stale'>;
20
21
  type StringifyConfig = Record<string, ((value: unknown) => string) | undefined>;
21
22
 
22
23
  type ConfigItem = {
23
- parts?: PatternPart[];
24
- stringify?: StringifyConfig;
25
- screens?: Record<string, ConfigItem>;
24
+ parts?: PatternPart[] | undefined;
25
+ stringify?: StringifyConfig | undefined;
26
+ screens?: Record<string, ConfigItem> | undefined;
26
27
  };
27
28
 
28
- const getActiveRoute = (state: State): { name: string; params?: object } => {
29
+ const getActiveRoute = (
30
+ state: State
31
+ ): { name: string; params?: object | undefined } => {
29
32
  const route =
30
33
  typeof state.index === 'number'
31
34
  ? state.routes[state.index]
@@ -57,6 +60,46 @@ const getNormalizedConfigs = (options?: Options<{}>) => {
57
60
  return normalizedConfigs;
58
61
  };
59
62
 
63
+ const getTransformedState = (
64
+ state: State,
65
+ configs: Record<string, ConfigItem> | undefined
66
+ ): Omit<PartialState<NavigationState>, 'stale'> => {
67
+ const routes = state.routes.map(
68
+ (route): Omit<PartialState<NavigationState>, 'stale'>['routes'][number] => {
69
+ if (
70
+ route.state ||
71
+ (configs?.[route.name]?.screens &&
72
+ route.params &&
73
+ (('screen' in route.params &&
74
+ typeof route.params.screen === 'string' &&
75
+ configs[route.name].screens?.[route.params.screen]) ||
76
+ 'state' in route.params))
77
+ ) {
78
+ const nestedState: State | undefined =
79
+ route.state ?? getStateFromRouteParams(route.params);
80
+
81
+ if (nestedState) {
82
+ return {
83
+ ...route,
84
+ state: getTransformedState(
85
+ nestedState,
86
+ configs?.[route.name]?.screens
87
+ ),
88
+ };
89
+ }
90
+ }
91
+
92
+ // @ts-expect-error route.state is handled in previous condition
93
+ return route;
94
+ }
95
+ );
96
+
97
+ return {
98
+ ...state,
99
+ routes,
100
+ };
101
+ };
102
+
60
103
  /**
61
104
  * Utility to serialize a navigation state object to a path string.
62
105
  *
@@ -101,9 +144,10 @@ export function getPathFromState<ParamList extends {}>(
101
144
  }
102
145
 
103
146
  const configs = getNormalizedConfigs(options);
147
+ const transformedState = getTransformedState(state, configs);
104
148
 
105
149
  let path = '/';
106
- let current: State | undefined = state;
150
+ let current: State | undefined = transformedState;
107
151
 
108
152
  const allParams: Record<string, string> = {};
109
153
 
@@ -118,7 +162,7 @@ export function getPathFromState<ParamList extends {}>(
118
162
  let focusedParams: Record<string, string> | undefined;
119
163
  let currentOptions = configs;
120
164
 
121
- const focusedRoute = getActiveRoute(state);
165
+ const focusedRoute = getActiveRoute(transformedState);
122
166
 
123
167
  // Keep all the route names that appeared during going deeper in config in case the pattern is resolved to undefined
124
168
  const nestedRouteNames = [];