@react-navigation/core 7.13.6 → 8.0.0-alpha.0

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 (157) hide show
  1. package/lib/module/BaseNavigationContainer.js +4 -9
  2. package/lib/module/BaseNavigationContainer.js.map +1 -1
  3. package/lib/module/NavigationIndependentTree.js +12 -7
  4. package/lib/module/NavigationIndependentTree.js.map +1 -1
  5. package/lib/module/NavigationProvider.js +49 -0
  6. package/lib/module/NavigationProvider.js.map +1 -0
  7. package/lib/module/PreventRemoveProvider.js +1 -1
  8. package/lib/module/PreventRemoveProvider.js.map +1 -1
  9. package/lib/module/SceneView.js.map +1 -1
  10. package/lib/module/StaticNavigation.js +32 -21
  11. package/lib/module/StaticNavigation.js.map +1 -1
  12. package/lib/module/createNavigationContainerRef.js.map +1 -1
  13. package/lib/module/getActionFromState.js +3 -2
  14. package/lib/module/getActionFromState.js.map +1 -1
  15. package/lib/module/getPathFromState.js +1 -1
  16. package/lib/module/getPathFromState.js.map +1 -1
  17. package/lib/module/getStateFromPath.js +3 -3
  18. package/lib/module/getStateFromPath.js.map +1 -1
  19. package/lib/module/index.js +1 -2
  20. package/lib/module/index.js.map +1 -1
  21. package/lib/module/theming/ThemeContext.js.map +1 -1
  22. package/lib/module/theming/ThemeProvider.js.map +1 -1
  23. package/lib/module/theming/useTheme.js +1 -1
  24. package/lib/module/theming/useTheme.js.map +1 -1
  25. package/lib/module/types.js +41 -0
  26. package/lib/module/types.js.map +1 -1
  27. package/lib/module/useChildListeners.js +2 -4
  28. package/lib/module/useChildListeners.js.map +1 -1
  29. package/lib/module/useDescriptors.js +5 -9
  30. package/lib/module/useDescriptors.js.map +1 -1
  31. package/lib/module/useEventEmitter.js +9 -20
  32. package/lib/module/useEventEmitter.js.map +1 -1
  33. package/lib/module/useFocusEvents.js +1 -1
  34. package/lib/module/useFocusEvents.js.map +1 -1
  35. package/lib/module/useNavigation.js +31 -8
  36. package/lib/module/useNavigation.js.map +1 -1
  37. package/lib/module/useNavigationBuilder.js +10 -12
  38. package/lib/module/useNavigationBuilder.js.map +1 -1
  39. package/lib/module/useNavigationCache.js +18 -11
  40. package/lib/module/useNavigationCache.js.map +1 -1
  41. package/lib/module/useNavigationHelpers.js +2 -14
  42. package/lib/module/useNavigationHelpers.js.map +1 -1
  43. package/lib/module/useNavigationState.js +42 -9
  44. package/lib/module/useNavigationState.js.map +1 -1
  45. package/lib/module/useOnAction.js +2 -7
  46. package/lib/module/useOnAction.js.map +1 -1
  47. package/lib/module/useOnGetState.js +1 -1
  48. package/lib/module/useOnGetState.js.map +1 -1
  49. package/lib/module/useOnPreventRemove.js +1 -1
  50. package/lib/module/useOnPreventRemove.js.map +1 -1
  51. package/lib/module/useRoute.js +23 -5
  52. package/lib/module/useRoute.js.map +1 -1
  53. package/lib/module/useScheduleUpdate.js +1 -2
  54. package/lib/module/useScheduleUpdate.js.map +1 -1
  55. package/lib/module/useSyncState.js +25 -9
  56. package/lib/module/useSyncState.js.map +1 -1
  57. package/lib/module/utilities.js +2 -0
  58. package/lib/module/utilities.js.map +1 -0
  59. package/lib/typescript/src/BaseNavigationContainer.d.ts.map +1 -1
  60. package/lib/typescript/src/NavigationIndependentTree.d.ts.map +1 -1
  61. package/lib/typescript/src/NavigationProvider.d.ts +44 -0
  62. package/lib/typescript/src/NavigationProvider.d.ts.map +1 -0
  63. package/lib/typescript/src/SceneView.d.ts +1 -1
  64. package/lib/typescript/src/SceneView.d.ts.map +1 -1
  65. package/lib/typescript/src/StaticNavigation.d.ts +231 -80
  66. package/lib/typescript/src/StaticNavigation.d.ts.map +1 -1
  67. package/lib/typescript/src/createNavigationContainerRef.d.ts +2 -2
  68. package/lib/typescript/src/createNavigationContainerRef.d.ts.map +1 -1
  69. package/lib/typescript/src/getStateFromPath.d.ts.map +1 -1
  70. package/lib/typescript/src/index.d.ts +2 -3
  71. package/lib/typescript/src/index.d.ts.map +1 -1
  72. package/lib/typescript/src/theming/ThemeContext.d.ts +2 -1
  73. package/lib/typescript/src/theming/ThemeContext.d.ts.map +1 -1
  74. package/lib/typescript/src/theming/ThemeProvider.d.ts +2 -1
  75. package/lib/typescript/src/theming/ThemeProvider.d.ts.map +1 -1
  76. package/lib/typescript/src/theming/useTheme.d.ts +1 -1
  77. package/lib/typescript/src/theming/useTheme.d.ts.map +1 -1
  78. package/lib/typescript/src/types.d.ts +188 -133
  79. package/lib/typescript/src/types.d.ts.map +1 -1
  80. package/lib/typescript/src/useChildListeners.d.ts.map +1 -1
  81. package/lib/typescript/src/useDescriptors.d.ts +27 -109
  82. package/lib/typescript/src/useDescriptors.d.ts.map +1 -1
  83. package/lib/typescript/src/useEventEmitter.d.ts.map +1 -1
  84. package/lib/typescript/src/useNavigation.d.ts +7 -5
  85. package/lib/typescript/src/useNavigation.d.ts.map +1 -1
  86. package/lib/typescript/src/useNavigationBuilder.d.ts +25 -114
  87. package/lib/typescript/src/useNavigationBuilder.d.ts.map +1 -1
  88. package/lib/typescript/src/useNavigationCache.d.ts +8 -22
  89. package/lib/typescript/src/useNavigationCache.d.ts.map +1 -1
  90. package/lib/typescript/src/useNavigationContainerRef.d.ts +2 -2
  91. package/lib/typescript/src/useNavigationContainerRef.d.ts.map +1 -1
  92. package/lib/typescript/src/useNavigationHelpers.d.ts +3 -11
  93. package/lib/typescript/src/useNavigationHelpers.d.ts.map +1 -1
  94. package/lib/typescript/src/useNavigationState.d.ts +10 -3
  95. package/lib/typescript/src/useNavigationState.d.ts.map +1 -1
  96. package/lib/typescript/src/useOnAction.d.ts.map +1 -1
  97. package/lib/typescript/src/useRoute.d.ts +8 -2
  98. package/lib/typescript/src/useRoute.d.ts.map +1 -1
  99. package/lib/typescript/src/useRouteCache.d.ts +12 -3
  100. package/lib/typescript/src/useRouteCache.d.ts.map +1 -1
  101. package/lib/typescript/src/useScheduleUpdate.d.ts.map +1 -1
  102. package/lib/typescript/src/useSyncState.d.ts.map +1 -1
  103. package/lib/typescript/src/utilities.d.ts +99 -0
  104. package/lib/typescript/src/utilities.d.ts.map +1 -0
  105. package/package.json +10 -10
  106. package/src/BaseNavigationContainer.tsx +3 -9
  107. package/src/NavigationIndependentTree.tsx +17 -9
  108. package/src/NavigationProvider.tsx +64 -0
  109. package/src/PreventRemoveProvider.tsx +1 -1
  110. package/src/SceneView.tsx +1 -7
  111. package/src/StaticNavigation.tsx +372 -134
  112. package/src/createNavigationContainerRef.tsx +2 -1
  113. package/src/getActionFromState.tsx +4 -2
  114. package/src/getPathFromState.tsx +6 -5
  115. package/src/getStateFromPath.tsx +11 -11
  116. package/src/index.tsx +8 -4
  117. package/src/theming/ThemeContext.tsx +3 -3
  118. package/src/theming/ThemeProvider.tsx +2 -1
  119. package/src/theming/useTheme.tsx +1 -1
  120. package/src/types.tsx +392 -243
  121. package/src/useChildListeners.tsx +3 -2
  122. package/src/useDescriptors.tsx +11 -17
  123. package/src/useEventEmitter.tsx +14 -31
  124. package/src/useFocusEvents.tsx +1 -1
  125. package/src/useNavigation.tsx +57 -14
  126. package/src/useNavigationBuilder.tsx +10 -13
  127. package/src/useNavigationCache.tsx +40 -18
  128. package/src/useNavigationContainerRef.tsx +2 -2
  129. package/src/useNavigationHelpers.tsx +2 -19
  130. package/src/useNavigationState.tsx +90 -19
  131. package/src/useOnAction.tsx +1 -12
  132. package/src/useOnGetState.tsx +1 -1
  133. package/src/useOnPreventRemove.tsx +1 -1
  134. package/src/useRoute.tsx +52 -7
  135. package/src/useScheduleUpdate.tsx +1 -2
  136. package/src/useSyncState.tsx +28 -13
  137. package/src/utilities.tsx +122 -0
  138. package/lib/module/DeprecatedNavigationInChildContext.js +0 -9
  139. package/lib/module/DeprecatedNavigationInChildContext.js.map +0 -1
  140. package/lib/module/NavigationContext.js +0 -8
  141. package/lib/module/NavigationContext.js.map +0 -1
  142. package/lib/module/NavigationRouteContext.js +0 -9
  143. package/lib/module/NavigationRouteContext.js.map +0 -1
  144. package/lib/module/useClientLayoutEffect.js +0 -9
  145. package/lib/module/useClientLayoutEffect.js.map +0 -1
  146. package/lib/typescript/src/DeprecatedNavigationInChildContext.d.ts +0 -6
  147. package/lib/typescript/src/DeprecatedNavigationInChildContext.d.ts.map +0 -1
  148. package/lib/typescript/src/NavigationContext.d.ts +0 -8
  149. package/lib/typescript/src/NavigationContext.d.ts.map +0 -1
  150. package/lib/typescript/src/NavigationRouteContext.d.ts +0 -7
  151. package/lib/typescript/src/NavigationRouteContext.d.ts.map +0 -1
  152. package/lib/typescript/src/useClientLayoutEffect.d.ts +0 -6
  153. package/lib/typescript/src/useClientLayoutEffect.d.ts.map +0 -1
  154. package/src/DeprecatedNavigationInChildContext.tsx +0 -6
  155. package/src/NavigationContext.tsx +0 -11
  156. package/src/NavigationRouteContext.tsx +0 -9
  157. package/src/useClientLayoutEffect.tsx +0 -10
@@ -3,31 +3,106 @@ import * as React from 'react';
3
3
  import useLatestCallback from 'use-latest-callback';
4
4
  import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector';
5
5
 
6
- type Selector<ParamList extends ParamListBase, T> = (
7
- state: NavigationState<ParamList>
8
- ) => T;
6
+ import type {
7
+ NavigationListForNested,
8
+ NavigationProp,
9
+ RootNavigator,
10
+ } from './types';
11
+ import { useNavigation } from './useNavigation';
12
+
13
+ type NavigationStateListener = {
14
+ getState: () => NavigationState<ParamListBase>;
15
+ subscribe: (callback: () => void) => () => void;
16
+ };
17
+
18
+ type NavigationStateForNested<
19
+ Navigator,
20
+ RouteName extends keyof NavigationListForNested<Navigator>,
21
+ > = NavigationListForNested<Navigator>[RouteName] extends {
22
+ getState: () => infer State;
23
+ }
24
+ ? State
25
+ : never;
9
26
 
10
27
  /**
11
28
  * Hook to get a value from the current navigation state using a selector.
12
29
  *
13
- * @param selector Selector function to get a value from the state.
30
+ * If the route name of the current or one of the parents is specified,
31
+ * the navigation state of the navigator for that route is used.
32
+ *
33
+ * A selector function must be provided to select the desired value from the navigation state.
14
34
  */
15
- export function useNavigationState<ParamList extends ParamListBase, T>(
16
- selector: Selector<ParamList, T>
17
- ): T {
18
- const stateListener = React.useContext(NavigationStateListenerContext);
35
+ export function useNavigationState<
36
+ const T,
37
+ const Navigator = RootNavigator,
38
+ const RouteName extends
39
+ keyof NavigationListForNested<Navigator> = keyof NavigationListForNested<Navigator>,
40
+ >(
41
+ routeName: RouteName,
42
+ selector: (state: NavigationStateForNested<Navigator, RouteName>) => T
43
+ ): T;
44
+ export function useNavigationState<T>(
45
+ selector: (state: NavigationState<ParamListBase>) => T
46
+ ): T;
47
+ export function useNavigationState(...args: unknown[]): unknown {
48
+ let navigation: NavigationProp<ParamListBase> | undefined,
49
+ stateListener: NavigationStateListener | undefined,
50
+ selector;
51
+
52
+ if (typeof args[0] === 'string') {
53
+ // `useNavigation` uses `use` internally, so it's fine to call it conditionally
54
+ // @ts-expect-error we can't specify the type here
55
+ // eslint-disable-next-line react-hooks/rules-of-hooks
56
+ navigation = useNavigation(args[0]);
57
+ selector = args[1];
58
+ } else {
59
+ selector = args[0];
60
+ }
61
+
62
+ if (navigation == null) {
63
+ stateListener = React.use(NavigationStateListenerContext);
64
+
65
+ if (stateListener == null) {
66
+ throw new Error(
67
+ "Couldn't get the navigation state. Is your component inside a navigator?"
68
+ );
69
+ }
70
+ }
71
+
72
+ const subscribe = React.useCallback(
73
+ (callback: () => void) => {
74
+ if (navigation) {
75
+ return navigation.addListener('state', callback);
76
+ } else if (stateListener) {
77
+ return stateListener.subscribe(callback);
78
+ } else {
79
+ throw new Error(
80
+ "Couldn't subscribe to navigation state changes. This is not expected."
81
+ );
82
+ }
83
+ },
84
+ [navigation, stateListener]
85
+ );
19
86
 
20
- if (stateListener == null) {
87
+ const getSnapshot = navigation
88
+ ? navigation.getState
89
+ : stateListener?.getState;
90
+
91
+ if (getSnapshot == null) {
92
+ throw new Error("Couldn't get the navigation state. This is not expected.");
93
+ }
94
+
95
+ if (typeof selector !== 'function') {
21
96
  throw new Error(
22
- "Couldn't get the navigation state. Is your component inside a navigator?"
97
+ `A selector function must be provided (got ${typeof selector}).`
23
98
  );
24
99
  }
25
100
 
26
101
  const value = useSyncExternalStoreWithSelector(
27
- stateListener.subscribe,
28
- // @ts-expect-error: this is unsafe, but needed to make the generic work
29
- stateListener.getState,
30
- stateListener.getState,
102
+ subscribe,
103
+ getSnapshot,
104
+ getSnapshot,
105
+ // @ts-expect-error we can't infer the type here
31
106
  selector
32
107
  );
33
108
 
@@ -73,9 +148,5 @@ export function NavigationStateListenerProvider({
73
148
  }
74
149
 
75
150
  const NavigationStateListenerContext = React.createContext<
76
- | {
77
- getState: () => NavigationState<ParamListBase>;
78
- subscribe: (callback: () => void) => () => void;
79
- }
80
- | undefined
151
+ NavigationStateListener | undefined
81
152
  >(undefined);
@@ -7,7 +7,6 @@ import type {
7
7
  } from '@react-navigation/routers';
8
8
  import * as React from 'react';
9
9
 
10
- import { DeprecatedNavigationInChildContext } from './DeprecatedNavigationInChildContext';
11
10
  import {
12
11
  type ChildActionListener,
13
12
  type ChildBeforeRemoveListener,
@@ -53,9 +52,6 @@ export function useOnAction({
53
52
  addListener: addListenerParent,
54
53
  onDispatchAction,
55
54
  } = React.useContext(NavigationBuilderContext);
56
- const navigationInChildEnabled = React.useContext(
57
- DeprecatedNavigationInChildContext
58
- );
59
55
 
60
56
  const routerConfigOptionsRef =
61
57
  React.useRef<RouterConfigOptions>(routerConfigOptions);
@@ -131,14 +127,8 @@ export function useOnAction({
131
127
  }
132
128
  }
133
129
 
134
- if (
135
- typeof action.target === 'string' ||
136
- // For backward compatibility
137
- action.type === 'NAVIGATE_DEPRECATED' ||
138
- navigationInChildEnabled
139
- ) {
130
+ if (typeof action.target === 'string') {
140
131
  // If the action wasn't handled by current navigator or a parent navigator, let children handle it
141
- // Handling this when target isn't specified is deprecated and will be removed in the future
142
132
  for (let i = actionListeners.length - 1; i >= 0; i--) {
143
133
  const listener = actionListeners[i];
144
134
 
@@ -155,7 +145,6 @@ export function useOnAction({
155
145
  beforeRemoveListeners,
156
146
  emitter,
157
147
  getState,
158
- navigationInChildEnabled,
159
148
  key,
160
149
  onActionParent,
161
150
  onDispatchAction,
@@ -6,7 +6,7 @@ import {
6
6
  type GetStateListener,
7
7
  NavigationBuilderContext,
8
8
  } from './NavigationBuilderContext';
9
- import { NavigationRouteContext } from './NavigationRouteContext';
9
+ import { NavigationRouteContext } from './NavigationProvider';
10
10
 
11
11
  type Options = {
12
12
  getState: () => NavigationState;
@@ -8,7 +8,7 @@ import {
8
8
  type ChildBeforeRemoveListener,
9
9
  NavigationBuilderContext,
10
10
  } from './NavigationBuilderContext';
11
- import { NavigationRouteContext } from './NavigationRouteContext';
11
+ import { NavigationRouteContext } from './NavigationProvider';
12
12
  import type { EventMapCore } from './types';
13
13
  import type { NavigationEventEmitter } from './useEventEmitter';
14
14
 
package/src/useRoute.tsx CHANGED
@@ -1,22 +1,67 @@
1
1
  import type { ParamListBase } from '@react-navigation/routers';
2
2
  import * as React from 'react';
3
3
 
4
- import { NavigationRouteContext } from './NavigationRouteContext';
5
- import type { RouteProp } from './types';
4
+ import {
5
+ NamedRouteContextListContext,
6
+ NavigationRouteContext,
7
+ } from './NavigationProvider';
8
+ import type { RootParamList, RouteForName, RouteProp } from './types';
9
+
10
+ /**
11
+ * Get all possible route names from a param list and its nested navigators.
12
+ */
13
+ type AllRouteNames<ParamList extends {}> = RouteForName<
14
+ ParamList,
15
+ string
16
+ >['name'];
6
17
 
7
18
  /**
8
19
  * Hook to access the route prop of the parent screen anywhere.
9
20
  *
10
21
  * @returns Route prop of the parent screen.
11
22
  */
12
- export function useRoute<T extends RouteProp<ParamListBase>>(): T {
13
- const route = React.useContext(NavigationRouteContext);
23
+ export function useRoute<
24
+ const ParamList extends {} = RootParamList,
25
+ const RouteName extends AllRouteNames<ParamList> = AllRouteNames<ParamList>,
26
+ >(name: RouteName): RouteForName<ParamList, RouteName>;
27
+ export function useRoute<
28
+ const ParamList extends {} = RootParamList,
29
+ >(): {} extends ParamList
30
+ ? RouteProp<ParamListBase>
31
+ : ParamList extends ParamListBase
32
+ ? RouteForName<ParamList, string>
33
+ : RouteProp<ParamListBase>;
34
+
35
+ export function useRoute(name?: string) {
36
+ if (name === undefined) {
37
+ const route = React.use(NavigationRouteContext);
38
+
39
+ if (route === undefined) {
40
+ throw new Error(
41
+ "Couldn't find a route object. Is your component inside a screen in a navigator?"
42
+ );
43
+ }
44
+
45
+ return route;
46
+ }
14
47
 
15
- if (route === undefined) {
48
+ const NamedRouteContextList = React.use(NamedRouteContextListContext);
49
+
50
+ if (NamedRouteContextList === undefined) {
16
51
  throw new Error(
17
- "Couldn't find a route object. Is your component inside a screen in a navigator?"
52
+ "Couldn't find a parent screen. Is your component inside a screen in a navigator?"
18
53
  );
19
54
  }
20
55
 
21
- return route as T;
56
+ const NamedRouteContext = NamedRouteContextList[name];
57
+
58
+ if (NamedRouteContext === undefined) {
59
+ throw new Error(
60
+ `Couldn't find a route named '${name}' in any of the parent screens. Is your component inside the correct screen?`
61
+ );
62
+ }
63
+
64
+ const route = React.use(NamedRouteContext);
65
+
66
+ return route;
22
67
  }
@@ -1,7 +1,6 @@
1
1
  import * as React from 'react';
2
2
 
3
3
  import { NavigationBuilderContext } from './NavigationBuilderContext';
4
- import { useClientLayoutEffect } from './useClientLayoutEffect';
5
4
 
6
5
  /**
7
6
  * When screen config changes, we want to update the navigator in the same update phase.
@@ -19,5 +18,5 @@ export function useScheduleUpdate(callback: () => void) {
19
18
  // However, since we are using sync store, it might be fine
20
19
  scheduleUpdate(callback);
21
20
 
22
- useClientLayoutEffect(flushUpdates);
21
+ React.useLayoutEffect(flushUpdates);
23
22
  }
@@ -2,9 +2,10 @@ import * as React from 'react';
2
2
  import useLatestCallback from 'use-latest-callback';
3
3
 
4
4
  import { deepFreeze } from './deepFreeze';
5
+ import { useLazyValue } from './useLazyValue';
5
6
 
6
7
  const createStore = <T,>(getInitialState: () => T) => {
7
- const listeners: (() => void)[] = [];
8
+ const listeners = new Set<() => void>();
8
9
 
9
10
  let initialized = false;
10
11
  let state: T;
@@ -33,14 +34,10 @@ const createStore = <T,>(getInitialState: () => T) => {
33
34
  };
34
35
 
35
36
  const subscribe = (callback: () => void) => {
36
- listeners.push(callback);
37
+ listeners.add(callback);
37
38
 
38
39
  return () => {
39
- const index = listeners.indexOf(callback);
40
-
41
- if (index > -1) {
42
- listeners.splice(index, 1);
43
- }
40
+ listeners.delete(callback);
44
41
  };
45
42
  };
46
43
 
@@ -64,15 +61,31 @@ const createStore = <T,>(getInitialState: () => T) => {
64
61
  };
65
62
 
66
63
  export function useSyncState<T>(getInitialState: () => T) {
67
- const store = React.useRef(createStore(getInitialState)).current;
64
+ const store = useLazyValue(() => createStore(getInitialState));
68
65
 
69
- const state = React.useSyncExternalStore(
70
- store.subscribe,
71
- store.getState,
72
- store.getState
66
+ // Use a reducer with `store.getState` to always have the latest state
67
+ const [state, rerender] = React.useReducer(
68
+ (_) => store.getState(),
69
+ undefined,
70
+ () => store.getState()
73
71
  );
74
72
 
75
- React.useDebugValue(state);
73
+ // Instead of subscribing with `useSyncExternalStore`,
74
+ // we add custom subscription logic in an effect.
75
+ // This means React isn't forced to re-render immediately
76
+ // and state updates work with `useTransition`.
77
+ // The disadvantage is that it can potentially cause tearing.
78
+ // However, since we subscribe to the store only once,
79
+ // and pass this value down, it should not happen in practice.
80
+ React.useEffect(() => {
81
+ const unsubscribe = store.subscribe(() => rerender());
82
+
83
+ // We need to rerender again after the effect runs
84
+ // So we handle store changes after render and before the effect
85
+ rerender();
86
+
87
+ return unsubscribe;
88
+ }, [store]);
76
89
 
77
90
  const pendingUpdatesRef = React.useRef<(() => void)[]>([]);
78
91
 
@@ -95,6 +108,8 @@ export function useSyncState<T>(getInitialState: () => T) {
95
108
  }
96
109
  });
97
110
 
111
+ React.useEffect(flushUpdates);
112
+
98
113
  return {
99
114
  state,
100
115
  getState: store.getState,
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Flatten a type to remove all type alias names, unions etc.
3
+ * This will show a plain object when hovering over the type.
4
+ */
5
+ export type FlatType<T> = { [K in keyof T]: T[K] } & {};
6
+
7
+ /**
8
+ * keyof T doesn't work for union types. We can use distributive conditional types instead.
9
+ * https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#distributive-conditional-types
10
+ */
11
+ export type KeysOf<T> = T extends {} ? keyof T : never;
12
+
13
+ /**
14
+ * Extract string keys from an object type.
15
+ */
16
+ export type KeyOf<T extends {}> = Extract<keyof T, string>;
17
+
18
+ /**
19
+ * We get a union type when using keyof, but we want an intersection instead.
20
+ * https://stackoverflow.com/a/50375286/1665026
21
+ */
22
+ export type UnionToIntersection<U> = (
23
+ U extends any ? (k: U) => void : never
24
+ ) extends (k: infer I) => void
25
+ ? I
26
+ : never;
27
+
28
+ export type UnknownToUndefined<T> = unknown extends T ? undefined : T;
29
+
30
+ /**
31
+ * Exclude undefined from a type.
32
+ * Similar to NonNullable but only excludes undefined, not null.
33
+ */
34
+ export type NotUndefined<T> = T extends undefined ? never : T;
35
+
36
+ export type AnyToUnknown<T> = 0 extends 1 & T ? unknown : T;
37
+
38
+ /**
39
+ * Check if a function type has arguments.
40
+ */
41
+ export type HasArguments<T extends (...args: any[]) => any> =
42
+ Parameters<T> extends []
43
+ ? false
44
+ : Parameters<T> extends [undefined?]
45
+ ? false
46
+ : true;
47
+
48
+ export type ValidPathPattern = `:${string}` | `${string}/:${string}`;
49
+
50
+ /**
51
+ * Strip regex pattern from a path param.
52
+ * e.g. `userId([a-z]+)` -> `userId`
53
+ */
54
+ type StripRegex<Param extends string> = Param extends `${infer Name}(${string})`
55
+ ? Name
56
+ : Param;
57
+
58
+ /**
59
+ * Extract a single path param from a segment.
60
+ * e.g. `:userId` -> `{ userId: string }`, `:id?` -> `{ id?: string }`
61
+ */
62
+ type ExtractSegmentParam<Segment extends string> =
63
+ Segment extends `:${infer Param}?`
64
+ ? { [K in StripRegex<Param>]?: string }
65
+ : Segment extends `:${infer Param}`
66
+ ? { [K in StripRegex<Param>]: string }
67
+ : {};
68
+
69
+ /**
70
+ * Extract path params from a path string.
71
+ * e.g. `/foo/:userId/:postId` -> `{ userId: string; postId: string }`
72
+ * Supports optional params with `?` suffix.
73
+ * Params must start with `:` at the beginning of a segment (after `/`).
74
+ */
75
+ export type ExtractParamStrings<Path extends string> =
76
+ Path extends `${infer Segment}/${infer Rest}`
77
+ ? ExtractSegmentParam<Segment> & ExtractParamStrings<Rest>
78
+ : ExtractSegmentParam<Path>;
79
+
80
+ /**
81
+ * Extract the parsed params type from base params and parse functions.
82
+ * Applies the return type of parse functions to the corresponding params.
83
+ */
84
+ export type ExtractParamsType<Params, Parse> = {
85
+ [K in keyof Params]: K extends keyof Parse
86
+ ? Parse[K] extends (value: string) => infer R
87
+ ? R
88
+ : Params[K]
89
+ : Params[K];
90
+ };
91
+
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;
98
+
99
+ /**
100
+ * Infer the parse functions from a linking config.
101
+ */
102
+ export type InferParse<T> = T extends { parse: infer P } ? P : {};
103
+
104
+ /**
105
+ * Infer the params type from a screen component or nested navigator.
106
+ */
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
+ }>
122
+ : undefined;
@@ -1,9 +0,0 @@
1
- "use strict";
2
-
3
- import * as React from 'react';
4
-
5
- /**
6
- * Context which enables deprecated bubbling to child navigators.
7
- */
8
- export const DeprecatedNavigationInChildContext = /*#__PURE__*/React.createContext(false);
9
- //# sourceMappingURL=DeprecatedNavigationInChildContext.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["React","DeprecatedNavigationInChildContext","createContext"],"sourceRoot":"../../src","sources":["DeprecatedNavigationInChildContext.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;;AAE9B;AACA;AACA;AACA,OAAO,MAAMC,kCAAkC,gBAAGD,KAAK,CAACE,aAAa,CAAC,KAAK,CAAC","ignoreList":[]}
@@ -1,8 +0,0 @@
1
- "use strict";
2
-
3
- import * as React from 'react';
4
- /**
5
- * Context which holds the navigation prop for a screen.
6
- */
7
- export const NavigationContext = /*#__PURE__*/React.createContext(undefined);
8
- //# sourceMappingURL=NavigationContext.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["React","NavigationContext","createContext","undefined"],"sourceRoot":"../../src","sources":["NavigationContext.tsx"],"mappings":";;AACA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAI9B;AACA;AACA;AACA,OAAO,MAAMC,iBAAiB,gBAAGD,KAAK,CAACE,aAAa,CAElDC,SAAS,CAAC","ignoreList":[]}
@@ -1,9 +0,0 @@
1
- "use strict";
2
-
3
- import * as React from 'react';
4
-
5
- /**
6
- * Context which holds the route prop for a screen.
7
- */
8
- export const NavigationRouteContext = /*#__PURE__*/React.createContext(undefined);
9
- //# sourceMappingURL=NavigationRouteContext.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["React","NavigationRouteContext","createContext","undefined"],"sourceRoot":"../../src","sources":["NavigationRouteContext.tsx"],"mappings":";;AACA,OAAO,KAAKA,KAAK,MAAM,OAAO;;AAE9B;AACA;AACA;AACA,OAAO,MAAMC,sBAAsB,gBAAGD,KAAK,CAACE,aAAa,CAEvDC,SAAS,CAAC","ignoreList":[]}
@@ -1,9 +0,0 @@
1
- "use strict";
2
-
3
- import * as React from 'react';
4
-
5
- /**
6
- * Use `useEffect` during SSR and `useLayoutEffect` in the Browser & React Native to avoid warnings.
7
- */
8
- export const useClientLayoutEffect = typeof document !== 'undefined' || typeof navigator !== 'undefined' && navigator.product === 'ReactNative' ? React.useLayoutEffect : React.useEffect;
9
- //# sourceMappingURL=useClientLayoutEffect.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["React","useClientLayoutEffect","document","navigator","product","useLayoutEffect","useEffect"],"sourceRoot":"../../src","sources":["useClientLayoutEffect.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;;AAE9B;AACA;AACA;AACA,OAAO,MAAMC,qBAAqB,GAChC,OAAOC,QAAQ,KAAK,WAAW,IAC9B,OAAOC,SAAS,KAAK,WAAW,IAAIA,SAAS,CAACC,OAAO,KAAK,aAAc,GACrEJ,KAAK,CAACK,eAAe,GACrBL,KAAK,CAACM,SAAS","ignoreList":[]}
@@ -1,6 +0,0 @@
1
- import * as React from 'react';
2
- /**
3
- * Context which enables deprecated bubbling to child navigators.
4
- */
5
- export declare const DeprecatedNavigationInChildContext: React.Context<boolean>;
6
- //# sourceMappingURL=DeprecatedNavigationInChildContext.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"DeprecatedNavigationInChildContext.d.ts","sourceRoot":"","sources":["../../../src/DeprecatedNavigationInChildContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B;;GAEG;AACH,eAAO,MAAM,kCAAkC,wBAA6B,CAAC"}
@@ -1,8 +0,0 @@
1
- import type { ParamListBase } from '@react-navigation/routers';
2
- import * as React from 'react';
3
- import type { NavigationProp } from './types';
4
- /**
5
- * Context which holds the navigation prop for a screen.
6
- */
7
- export declare const NavigationContext: React.Context<NavigationProp<ParamListBase> | undefined>;
8
- //# sourceMappingURL=NavigationContext.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"NavigationContext.d.ts","sourceRoot":"","sources":["../../../src/NavigationContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C;;GAEG;AACH,eAAO,MAAM,iBAAiB,0DAElB,CAAC"}
@@ -1,7 +0,0 @@
1
- import type { Route } from '@react-navigation/routers';
2
- import * as React from 'react';
3
- /**
4
- * Context which holds the route prop for a screen.
5
- */
6
- export declare const NavigationRouteContext: React.Context<Route<string> | undefined>;
7
- //# sourceMappingURL=NavigationRouteContext.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"NavigationRouteContext.d.ts","sourceRoot":"","sources":["../../../src/NavigationRouteContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B;;GAEG;AACH,eAAO,MAAM,sBAAsB,0CAEvB,CAAC"}
@@ -1,6 +0,0 @@
1
- import * as React from 'react';
2
- /**
3
- * Use `useEffect` during SSR and `useLayoutEffect` in the Browser & React Native to avoid warnings.
4
- */
5
- export declare const useClientLayoutEffect: typeof React.useEffect;
6
- //# sourceMappingURL=useClientLayoutEffect.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useClientLayoutEffect.d.ts","sourceRoot":"","sources":["../../../src/useClientLayoutEffect.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B;;GAEG;AACH,eAAO,MAAM,qBAAqB,wBAIb,CAAC"}
@@ -1,6 +0,0 @@
1
- import * as React from 'react';
2
-
3
- /**
4
- * Context which enables deprecated bubbling to child navigators.
5
- */
6
- export const DeprecatedNavigationInChildContext = React.createContext(false);
@@ -1,11 +0,0 @@
1
- import type { ParamListBase } from '@react-navigation/routers';
2
- import * as React from 'react';
3
-
4
- import type { NavigationProp } from './types';
5
-
6
- /**
7
- * Context which holds the navigation prop for a screen.
8
- */
9
- export const NavigationContext = React.createContext<
10
- NavigationProp<ParamListBase> | undefined
11
- >(undefined);
@@ -1,9 +0,0 @@
1
- import type { Route } from '@react-navigation/routers';
2
- import * as React from 'react';
3
-
4
- /**
5
- * Context which holds the route prop for a screen.
6
- */
7
- export const NavigationRouteContext = React.createContext<
8
- Route<string> | undefined
9
- >(undefined);
@@ -1,10 +0,0 @@
1
- import * as React from 'react';
2
-
3
- /**
4
- * Use `useEffect` during SSR and `useLayoutEffect` in the Browser & React Native to avoid warnings.
5
- */
6
- export const useClientLayoutEffect =
7
- typeof document !== 'undefined' ||
8
- (typeof navigator !== 'undefined' && navigator.product === 'ReactNative')
9
- ? React.useLayoutEffect
10
- : React.useEffect;