@react-navigation/core 7.14.0 → 8.0.0-alpha.1
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.
- package/lib/module/BaseNavigationContainer.js +4 -9
- package/lib/module/BaseNavigationContainer.js.map +1 -1
- package/lib/module/NavigationIndependentTree.js +12 -7
- package/lib/module/NavigationIndependentTree.js.map +1 -1
- package/lib/module/NavigationProvider.js +49 -0
- package/lib/module/NavigationProvider.js.map +1 -0
- package/lib/module/PreventRemoveProvider.js +1 -1
- package/lib/module/PreventRemoveProvider.js.map +1 -1
- package/lib/module/SceneView.js.map +1 -1
- package/lib/module/StaticNavigation.js +32 -21
- package/lib/module/StaticNavigation.js.map +1 -1
- package/lib/module/createNavigationContainerRef.js.map +1 -1
- package/lib/module/getActionFromState.js +3 -2
- package/lib/module/getActionFromState.js.map +1 -1
- package/lib/module/getPathFromState.js +1 -1
- package/lib/module/getPathFromState.js.map +1 -1
- package/lib/module/getStateFromPath.js +3 -3
- package/lib/module/getStateFromPath.js.map +1 -1
- package/lib/module/index.js +1 -2
- package/lib/module/index.js.map +1 -1
- package/lib/module/theming/ThemeContext.js.map +1 -1
- package/lib/module/theming/ThemeProvider.js.map +1 -1
- package/lib/module/theming/useTheme.js +1 -1
- package/lib/module/theming/useTheme.js.map +1 -1
- package/lib/module/types.js +41 -0
- package/lib/module/types.js.map +1 -1
- package/lib/module/useChildListeners.js +2 -4
- package/lib/module/useChildListeners.js.map +1 -1
- package/lib/module/useDescriptors.js +5 -9
- package/lib/module/useDescriptors.js.map +1 -1
- package/lib/module/useEventEmitter.js +9 -20
- package/lib/module/useEventEmitter.js.map +1 -1
- package/lib/module/useFocusEvents.js +1 -1
- package/lib/module/useFocusEvents.js.map +1 -1
- package/lib/module/useNavigation.js +31 -8
- package/lib/module/useNavigation.js.map +1 -1
- package/lib/module/useNavigationBuilder.js +10 -12
- package/lib/module/useNavigationBuilder.js.map +1 -1
- package/lib/module/useNavigationCache.js +18 -11
- package/lib/module/useNavigationCache.js.map +1 -1
- package/lib/module/useNavigationHelpers.js +2 -14
- package/lib/module/useNavigationHelpers.js.map +1 -1
- package/lib/module/useNavigationState.js +42 -9
- package/lib/module/useNavigationState.js.map +1 -1
- package/lib/module/useOnAction.js +2 -7
- package/lib/module/useOnAction.js.map +1 -1
- package/lib/module/useOnGetState.js +1 -1
- package/lib/module/useOnGetState.js.map +1 -1
- package/lib/module/useOnPreventRemove.js +1 -1
- package/lib/module/useOnPreventRemove.js.map +1 -1
- package/lib/module/useRoute.js +23 -5
- package/lib/module/useRoute.js.map +1 -1
- package/lib/module/useScheduleUpdate.js +1 -2
- package/lib/module/useScheduleUpdate.js.map +1 -1
- package/lib/module/useSyncState.js +25 -9
- package/lib/module/useSyncState.js.map +1 -1
- package/lib/module/utilities.js +2 -0
- package/lib/module/utilities.js.map +1 -0
- package/lib/typescript/src/BaseNavigationContainer.d.ts.map +1 -1
- package/lib/typescript/src/NavigationIndependentTree.d.ts.map +1 -1
- package/lib/typescript/src/NavigationProvider.d.ts +44 -0
- package/lib/typescript/src/NavigationProvider.d.ts.map +1 -0
- package/lib/typescript/src/SceneView.d.ts +1 -1
- package/lib/typescript/src/SceneView.d.ts.map +1 -1
- package/lib/typescript/src/StaticNavigation.d.ts +231 -80
- package/lib/typescript/src/StaticNavigation.d.ts.map +1 -1
- package/lib/typescript/src/createNavigationContainerRef.d.ts +2 -2
- package/lib/typescript/src/createNavigationContainerRef.d.ts.map +1 -1
- package/lib/typescript/src/getStateFromPath.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +2 -3
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/theming/ThemeContext.d.ts +2 -1
- package/lib/typescript/src/theming/ThemeContext.d.ts.map +1 -1
- package/lib/typescript/src/theming/ThemeProvider.d.ts +2 -1
- package/lib/typescript/src/theming/ThemeProvider.d.ts.map +1 -1
- package/lib/typescript/src/theming/useTheme.d.ts +1 -1
- package/lib/typescript/src/theming/useTheme.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +188 -133
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/useChildListeners.d.ts.map +1 -1
- package/lib/typescript/src/useDescriptors.d.ts +27 -109
- package/lib/typescript/src/useDescriptors.d.ts.map +1 -1
- package/lib/typescript/src/useEventEmitter.d.ts.map +1 -1
- package/lib/typescript/src/useNavigation.d.ts +7 -5
- package/lib/typescript/src/useNavigation.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationBuilder.d.ts +25 -114
- package/lib/typescript/src/useNavigationBuilder.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationCache.d.ts +8 -22
- package/lib/typescript/src/useNavigationCache.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationContainerRef.d.ts +2 -2
- package/lib/typescript/src/useNavigationContainerRef.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationHelpers.d.ts +3 -11
- package/lib/typescript/src/useNavigationHelpers.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationState.d.ts +10 -3
- package/lib/typescript/src/useNavigationState.d.ts.map +1 -1
- package/lib/typescript/src/useOnAction.d.ts.map +1 -1
- package/lib/typescript/src/useRoute.d.ts +8 -2
- package/lib/typescript/src/useRoute.d.ts.map +1 -1
- package/lib/typescript/src/useRouteCache.d.ts +12 -3
- package/lib/typescript/src/useRouteCache.d.ts.map +1 -1
- package/lib/typescript/src/useScheduleUpdate.d.ts.map +1 -1
- package/lib/typescript/src/useSyncState.d.ts.map +1 -1
- package/lib/typescript/src/utilities.d.ts +99 -0
- package/lib/typescript/src/utilities.d.ts.map +1 -0
- package/package.json +7 -7
- package/src/BaseNavigationContainer.tsx +3 -9
- package/src/NavigationIndependentTree.tsx +17 -9
- package/src/NavigationProvider.tsx +64 -0
- package/src/PreventRemoveProvider.tsx +1 -1
- package/src/SceneView.tsx +1 -7
- package/src/StaticNavigation.tsx +372 -134
- package/src/createNavigationContainerRef.tsx +2 -1
- package/src/getActionFromState.tsx +4 -2
- package/src/getPathFromState.tsx +6 -5
- package/src/getStateFromPath.tsx +11 -11
- package/src/index.tsx +8 -4
- package/src/theming/ThemeContext.tsx +3 -3
- package/src/theming/ThemeProvider.tsx +2 -1
- package/src/theming/useTheme.tsx +1 -1
- package/src/types.tsx +392 -243
- package/src/useChildListeners.tsx +3 -2
- package/src/useDescriptors.tsx +11 -17
- package/src/useEventEmitter.tsx +14 -31
- package/src/useFocusEvents.tsx +1 -1
- package/src/useNavigation.tsx +57 -14
- package/src/useNavigationBuilder.tsx +10 -13
- package/src/useNavigationCache.tsx +40 -18
- package/src/useNavigationContainerRef.tsx +2 -2
- package/src/useNavigationHelpers.tsx +2 -19
- package/src/useNavigationState.tsx +90 -19
- package/src/useOnAction.tsx +1 -12
- package/src/useOnGetState.tsx +1 -1
- package/src/useOnPreventRemove.tsx +1 -1
- package/src/useRoute.tsx +52 -7
- package/src/useScheduleUpdate.tsx +1 -2
- package/src/useSyncState.tsx +28 -13
- package/src/utilities.tsx +122 -0
- package/lib/module/DeprecatedNavigationInChildContext.js +0 -9
- package/lib/module/DeprecatedNavigationInChildContext.js.map +0 -1
- package/lib/module/NavigationContext.js +0 -8
- package/lib/module/NavigationContext.js.map +0 -1
- package/lib/module/NavigationRouteContext.js +0 -9
- package/lib/module/NavigationRouteContext.js.map +0 -1
- package/lib/module/useClientLayoutEffect.js +0 -9
- package/lib/module/useClientLayoutEffect.js.map +0 -1
- package/lib/typescript/src/DeprecatedNavigationInChildContext.d.ts +0 -6
- package/lib/typescript/src/DeprecatedNavigationInChildContext.d.ts.map +0 -1
- package/lib/typescript/src/NavigationContext.d.ts +0 -8
- package/lib/typescript/src/NavigationContext.d.ts.map +0 -1
- package/lib/typescript/src/NavigationRouteContext.d.ts +0 -7
- package/lib/typescript/src/NavigationRouteContext.d.ts.map +0 -1
- package/lib/typescript/src/useClientLayoutEffect.d.ts +0 -6
- package/lib/typescript/src/useClientLayoutEffect.d.ts.map +0 -1
- package/src/DeprecatedNavigationInChildContext.tsx +0 -6
- package/src/NavigationContext.tsx +0 -11
- package/src/NavigationRouteContext.tsx +0 -9
- package/src/useClientLayoutEffect.tsx +0 -10
|
@@ -6,18 +6,19 @@ import type { ListenerMap } from './NavigationBuilderContext';
|
|
|
6
6
|
* Hook which lets child navigators add action listeners.
|
|
7
7
|
*/
|
|
8
8
|
export function useChildListeners() {
|
|
9
|
-
const
|
|
9
|
+
const listeners = React.useRef<{
|
|
10
10
|
[K in keyof ListenerMap]: ListenerMap[K][];
|
|
11
11
|
}>({
|
|
12
12
|
action: [],
|
|
13
13
|
focus: [],
|
|
14
|
-
});
|
|
14
|
+
}).current;
|
|
15
15
|
|
|
16
16
|
const addListener = React.useCallback(
|
|
17
17
|
<T extends keyof ListenerMap>(type: T, listener: ListenerMap[T]) => {
|
|
18
18
|
listeners[type].push(listener);
|
|
19
19
|
|
|
20
20
|
let removed = false;
|
|
21
|
+
|
|
21
22
|
return () => {
|
|
22
23
|
const index = listeners[type].indexOf(listener);
|
|
23
24
|
|
package/src/useDescriptors.tsx
CHANGED
|
@@ -12,8 +12,7 @@ import {
|
|
|
12
12
|
type AddListener,
|
|
13
13
|
NavigationBuilderContext,
|
|
14
14
|
} from './NavigationBuilderContext';
|
|
15
|
-
import {
|
|
16
|
-
import { NavigationRouteContext } from './NavigationRouteContext';
|
|
15
|
+
import { NavigationProvider } from './NavigationProvider';
|
|
17
16
|
import { SceneView } from './SceneView';
|
|
18
17
|
import { ThemeContext } from './theming/ThemeContext';
|
|
19
18
|
import type {
|
|
@@ -23,6 +22,7 @@ import type {
|
|
|
23
22
|
NavigationProp,
|
|
24
23
|
RouteConfig,
|
|
25
24
|
RouteProp,
|
|
25
|
+
Theme,
|
|
26
26
|
} from './types';
|
|
27
27
|
import type { NavigationEventEmitter } from './useEventEmitter';
|
|
28
28
|
import { useNavigationCache } from './useNavigationCache';
|
|
@@ -50,7 +50,7 @@ type ScreenLayout<ScreenOptions extends {}> = (props: {
|
|
|
50
50
|
route: RouteProp<ParamListBase, string>;
|
|
51
51
|
options: ScreenOptions;
|
|
52
52
|
navigation: any;
|
|
53
|
-
theme:
|
|
53
|
+
theme: Theme;
|
|
54
54
|
children: React.ReactElement;
|
|
55
55
|
}) => React.ReactElement;
|
|
56
56
|
|
|
@@ -59,7 +59,7 @@ type ScreenOptionsOrCallback<ScreenOptions extends {}> =
|
|
|
59
59
|
| ((props: {
|
|
60
60
|
route: RouteProp<ParamListBase, string>;
|
|
61
61
|
navigation: any;
|
|
62
|
-
theme:
|
|
62
|
+
theme: Theme;
|
|
63
63
|
}) => ScreenOptions);
|
|
64
64
|
|
|
65
65
|
type Options<
|
|
@@ -95,7 +95,7 @@ type Options<
|
|
|
95
95
|
*/
|
|
96
96
|
export function useDescriptors<
|
|
97
97
|
State extends NavigationState,
|
|
98
|
-
ActionHelpers extends Record<string, () => void>,
|
|
98
|
+
ActionHelpers extends Record<string, (...args: any) => void>,
|
|
99
99
|
ScreenOptions extends {},
|
|
100
100
|
EventMap extends EventMapBase,
|
|
101
101
|
>({
|
|
@@ -173,7 +173,6 @@ export function useDescriptors<
|
|
|
173
173
|
navigation: NavigationProp<
|
|
174
174
|
ParamListBase,
|
|
175
175
|
string,
|
|
176
|
-
string | undefined,
|
|
177
176
|
State,
|
|
178
177
|
ScreenOptions,
|
|
179
178
|
EventMap
|
|
@@ -212,7 +211,6 @@ export function useDescriptors<
|
|
|
212
211
|
navigation: NavigationProp<
|
|
213
212
|
ParamListBase,
|
|
214
213
|
string,
|
|
215
|
-
string | undefined,
|
|
216
214
|
State,
|
|
217
215
|
ScreenOptions,
|
|
218
216
|
EventMap
|
|
@@ -268,11 +266,9 @@ export function useDescriptors<
|
|
|
268
266
|
|
|
269
267
|
return (
|
|
270
268
|
<NavigationBuilderContext.Provider key={route.key} value={context}>
|
|
271
|
-
<
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
</NavigationRouteContext.Provider>
|
|
275
|
-
</NavigationContext.Provider>
|
|
269
|
+
<NavigationProvider navigation={navigation} route={route}>
|
|
270
|
+
{element}
|
|
271
|
+
</NavigationProvider>
|
|
276
272
|
</NavigationBuilderContext.Provider>
|
|
277
273
|
);
|
|
278
274
|
};
|
|
@@ -285,12 +281,11 @@ export function useDescriptors<
|
|
|
285
281
|
NavigationProp<
|
|
286
282
|
ParamListBase,
|
|
287
283
|
string,
|
|
288
|
-
string | undefined,
|
|
289
284
|
State,
|
|
290
285
|
ScreenOptions,
|
|
291
|
-
EventMap
|
|
292
|
-
|
|
293
|
-
|
|
286
|
+
EventMap,
|
|
287
|
+
ActionHelpers
|
|
288
|
+
>,
|
|
294
289
|
RouteProp<ParamListBase>
|
|
295
290
|
>
|
|
296
291
|
>
|
|
@@ -306,7 +301,6 @@ export function useDescriptors<
|
|
|
306
301
|
|
|
307
302
|
acc[route.key] = {
|
|
308
303
|
route,
|
|
309
|
-
// @ts-expect-error: it's missing action helpers, fix later
|
|
310
304
|
navigation,
|
|
311
305
|
render() {
|
|
312
306
|
return element;
|
package/src/useEventEmitter.tsx
CHANGED
|
@@ -7,7 +7,7 @@ export type NavigationEventEmitter<T extends Record<string, any>> =
|
|
|
7
7
|
create: (target: string) => EventConsumer<T>;
|
|
8
8
|
};
|
|
9
9
|
|
|
10
|
-
type Listeners = (
|
|
10
|
+
type Listeners = Set<(e: any) => void>;
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Hook to manage the event system used by the navigator to notify screens of various events.
|
|
@@ -27,34 +27,18 @@ export function useEventEmitter<T extends Record<string, any>>(
|
|
|
27
27
|
|
|
28
28
|
const create = React.useCallback((target: string) => {
|
|
29
29
|
const removeListener = (type: string, callback: (data: any) => void) => {
|
|
30
|
-
const callbacks = listeners.current[type]
|
|
31
|
-
? listeners.current[type][target]
|
|
32
|
-
: undefined;
|
|
30
|
+
const callbacks = listeners.current[type]?.[target];
|
|
33
31
|
|
|
34
|
-
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const index = callbacks.indexOf(callback);
|
|
39
|
-
|
|
40
|
-
if (index > -1) {
|
|
41
|
-
callbacks.splice(index, 1);
|
|
42
|
-
}
|
|
32
|
+
callbacks?.delete(callback);
|
|
43
33
|
};
|
|
44
34
|
|
|
45
35
|
const addListener = (type: string, callback: (data: any) => void) => {
|
|
46
|
-
listeners.current[type]
|
|
47
|
-
listeners.current[type][target]
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return () =>
|
|
52
|
-
// Prevent removing other listeners when unsubscribing same listener multiple times
|
|
53
|
-
if (!removed) {
|
|
54
|
-
removed = true;
|
|
55
|
-
removeListener(type, callback);
|
|
56
|
-
}
|
|
57
|
-
};
|
|
36
|
+
listeners.current[type] ??= {};
|
|
37
|
+
listeners.current[type][target] ??= new Set();
|
|
38
|
+
|
|
39
|
+
listeners.current[type][target].add(callback);
|
|
40
|
+
|
|
41
|
+
return () => removeListener(type, callback);
|
|
58
42
|
};
|
|
59
43
|
|
|
60
44
|
return {
|
|
@@ -78,12 +62,11 @@ export function useEventEmitter<T extends Record<string, any>>(
|
|
|
78
62
|
const items = listeners.current[type] || {};
|
|
79
63
|
|
|
80
64
|
// Copy the current list of callbacks in case they are mutated during execution
|
|
81
|
-
const callbacks =
|
|
82
|
-
target
|
|
83
|
-
?
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
.filter((cb, i, self) => self.lastIndexOf(cb) === i);
|
|
65
|
+
const callbacks = new Set(
|
|
66
|
+
Object.values(target ? { [target]: items[target] } : items).flatMap(
|
|
67
|
+
(t) => (t ? Array.from(t) : [])
|
|
68
|
+
)
|
|
69
|
+
);
|
|
87
70
|
|
|
88
71
|
const event: EventArg<any, any, any> = {
|
|
89
72
|
get type() {
|
package/src/useFocusEvents.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { NavigationState } from '@react-navigation/routers';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
|
|
4
|
-
import { NavigationContext } from './
|
|
4
|
+
import { NavigationContext } from './NavigationProvider';
|
|
5
5
|
import type { EventMapCore } from './types';
|
|
6
6
|
import type { NavigationEventEmitter } from './useEventEmitter';
|
|
7
7
|
|
package/src/useNavigation.tsx
CHANGED
|
@@ -1,29 +1,72 @@
|
|
|
1
|
-
import { type NavigationState } from '@react-navigation/routers';
|
|
2
1
|
import * as React from 'react';
|
|
3
2
|
|
|
4
3
|
import { NavigationContainerRefContext } from './NavigationContainerRefContext';
|
|
5
|
-
import {
|
|
6
|
-
|
|
4
|
+
import {
|
|
5
|
+
NavigationContext,
|
|
6
|
+
NavigationRouteNameContext,
|
|
7
|
+
} from './NavigationProvider';
|
|
8
|
+
import type {
|
|
9
|
+
GenericNavigation,
|
|
10
|
+
NavigationListForNavigator,
|
|
11
|
+
NavigationListForNested,
|
|
12
|
+
RootNavigator,
|
|
13
|
+
RootParamList,
|
|
14
|
+
} from './types';
|
|
7
15
|
|
|
8
16
|
/**
|
|
9
17
|
* Hook to access the navigation prop of the parent screen anywhere.
|
|
10
18
|
*
|
|
19
|
+
* If the route name of the current or one of the parents is specified,
|
|
20
|
+
* the navigation prop for that route is returned.
|
|
21
|
+
*
|
|
11
22
|
* @returns Navigation prop of the parent screen.
|
|
12
23
|
*/
|
|
24
|
+
export function useNavigation(): GenericNavigation<RootParamList>;
|
|
25
|
+
export function useNavigation<
|
|
26
|
+
const Navigator = RootNavigator,
|
|
27
|
+
>(): NavigationListForNavigator<Navigator>[keyof NavigationListForNavigator<Navigator>];
|
|
13
28
|
export function useNavigation<
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
>():
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
29
|
+
const Navigator = RootNavigator,
|
|
30
|
+
const RouteName extends
|
|
31
|
+
keyof NavigationListForNested<Navigator> = keyof NavigationListForNested<Navigator>,
|
|
32
|
+
>(name: RouteName): NavigationListForNested<Navigator>[RouteName];
|
|
33
|
+
export function useNavigation(name?: string): unknown {
|
|
34
|
+
const root = React.use(NavigationContainerRefContext);
|
|
35
|
+
const navigation = React.use(NavigationContext);
|
|
36
|
+
|
|
37
|
+
if (name === undefined) {
|
|
38
|
+
if (navigation === undefined && root === undefined) {
|
|
39
|
+
throw new Error(
|
|
40
|
+
"Couldn't find a navigation object. Is your component inside NavigationContainer?"
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return navigation ?? root;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const routeName = React.use(NavigationRouteNameContext);
|
|
48
|
+
|
|
49
|
+
// Generally, this condition isn't needed as `getParent(name)` works for current screen
|
|
50
|
+
// However, it'll throw if the hook is used in a preloaded screen
|
|
51
|
+
if (routeName === name) {
|
|
52
|
+
if (navigation === undefined) {
|
|
53
|
+
throw new Error(
|
|
54
|
+
`Couldn't find a navigation object for '${name}'. This is not expected.`
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return navigation;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// We get parent first so that `getParent(name)` is not called in preloaded screens
|
|
62
|
+
// It's ok since `getParent` also works for current screen, so parent is not skipped
|
|
63
|
+
const parent = navigation?.getParent()?.getParent(name);
|
|
64
|
+
|
|
65
|
+
if (parent === undefined) {
|
|
22
66
|
throw new Error(
|
|
23
|
-
|
|
67
|
+
`Couldn't find a navigation object for '${name}' in current or any parent screens. Is your component inside the correct screen?`
|
|
24
68
|
);
|
|
25
69
|
}
|
|
26
70
|
|
|
27
|
-
|
|
28
|
-
return (navigation ?? root) as unknown as T;
|
|
71
|
+
return parent;
|
|
29
72
|
}
|
|
@@ -21,7 +21,7 @@ import { isArrayEqual } from './isArrayEqual';
|
|
|
21
21
|
import { isRecordEqual } from './isRecordEqual';
|
|
22
22
|
import { NavigationHelpersContext } from './NavigationHelpersContext';
|
|
23
23
|
import { NavigationMetaContext } from './NavigationMetaContext';
|
|
24
|
-
import { NavigationRouteContext } from './
|
|
24
|
+
import { NavigationRouteContext } from './NavigationProvider';
|
|
25
25
|
import { NavigationStateContext } from './NavigationStateContext';
|
|
26
26
|
import { PreventRemoveProvider } from './PreventRemoveProvider';
|
|
27
27
|
import { Screen } from './Screen';
|
|
@@ -35,7 +35,6 @@ import {
|
|
|
35
35
|
} from './types';
|
|
36
36
|
import { UnhandledActionContext } from './UnhandledActionContext';
|
|
37
37
|
import { useChildListeners } from './useChildListeners';
|
|
38
|
-
import { useClientLayoutEffect } from './useClientLayoutEffect';
|
|
39
38
|
import { useComponent } from './useComponent';
|
|
40
39
|
import { useCurrentRender } from './useCurrentRender';
|
|
41
40
|
import { type ScreenConfigWithParent, useDescriptors } from './useDescriptors';
|
|
@@ -311,7 +310,6 @@ export function useNavigationBuilder<
|
|
|
311
310
|
createRouter: RouterFactory<State, NavigationAction, RouterOptions>,
|
|
312
311
|
options: DefaultNavigatorOptions<
|
|
313
312
|
ParamListBase,
|
|
314
|
-
string | undefined,
|
|
315
313
|
State,
|
|
316
314
|
ScreenOptions,
|
|
317
315
|
EventMap,
|
|
@@ -331,7 +329,7 @@ export function useNavigationBuilder<
|
|
|
331
329
|
screenOptions,
|
|
332
330
|
screenLayout,
|
|
333
331
|
screenListeners,
|
|
334
|
-
|
|
332
|
+
router: routerOverrides,
|
|
335
333
|
...rest
|
|
336
334
|
} = options;
|
|
337
335
|
|
|
@@ -355,8 +353,8 @@ export function useNavigationBuilder<
|
|
|
355
353
|
|
|
356
354
|
const original = createRouter(rest as unknown as RouterOptions);
|
|
357
355
|
|
|
358
|
-
if (
|
|
359
|
-
const overrides =
|
|
356
|
+
if (routerOverrides != null) {
|
|
357
|
+
const overrides = routerOverrides(original);
|
|
360
358
|
|
|
361
359
|
return {
|
|
362
360
|
...original,
|
|
@@ -520,7 +518,7 @@ export function useNavigationBuilder<
|
|
|
520
518
|
);
|
|
521
519
|
|
|
522
520
|
if (
|
|
523
|
-
options.
|
|
521
|
+
options.routeNamesChangeBehavior === 'lastUnhandled' &&
|
|
524
522
|
doesStateHaveOnlyInvalidRoutes(stateBeforeInitialization)
|
|
525
523
|
) {
|
|
526
524
|
return [stateBeforeInitialization, hydratedState, true];
|
|
@@ -553,7 +551,7 @@ export function useNavigationBuilder<
|
|
|
553
551
|
// It's possible that they were absent due to conditional render
|
|
554
552
|
// Store this state so we can reuse it if the routes change later
|
|
555
553
|
if (
|
|
556
|
-
options.
|
|
554
|
+
options.routeNamesChangeBehavior === 'lastUnhandled' &&
|
|
557
555
|
stateBeforeInitialization &&
|
|
558
556
|
unhandledState !== stateBeforeInitialization
|
|
559
557
|
) {
|
|
@@ -621,7 +619,7 @@ export function useNavigationBuilder<
|
|
|
621
619
|
route.params !== previousParams
|
|
622
620
|
) {
|
|
623
621
|
if (
|
|
624
|
-
options.
|
|
622
|
+
options.routeNamesChangeBehavior === 'lastUnhandled' &&
|
|
625
623
|
doesStateHaveOnlyInvalidRoutes(route.params.state)
|
|
626
624
|
) {
|
|
627
625
|
if (route.params.state !== unhandledState) {
|
|
@@ -637,7 +635,7 @@ export function useNavigationBuilder<
|
|
|
637
635
|
route.params !== previousParams)
|
|
638
636
|
) {
|
|
639
637
|
if (
|
|
640
|
-
options.
|
|
638
|
+
options.routeNamesChangeBehavior === 'lastUnhandled' &&
|
|
641
639
|
!routeNames.includes(route.params.screen)
|
|
642
640
|
) {
|
|
643
641
|
const state = getStateFromParams(route.params);
|
|
@@ -730,7 +728,7 @@ export function useNavigationBuilder<
|
|
|
730
728
|
|
|
731
729
|
stateRef.current = state;
|
|
732
730
|
|
|
733
|
-
|
|
731
|
+
React.useLayoutEffect(() => {
|
|
734
732
|
stateRef.current = null;
|
|
735
733
|
});
|
|
736
734
|
|
|
@@ -833,7 +831,7 @@ export function useNavigationBuilder<
|
|
|
833
831
|
|
|
834
832
|
const onUnhandledAction = useLatestCallback((action: NavigationAction) => {
|
|
835
833
|
if (
|
|
836
|
-
options.
|
|
834
|
+
options.routeNamesChangeBehavior === 'lastUnhandled' &&
|
|
837
835
|
action.type === 'NAVIGATE' &&
|
|
838
836
|
action.payload != null &&
|
|
839
837
|
'name' in action.payload &&
|
|
@@ -871,7 +869,6 @@ export function useNavigationBuilder<
|
|
|
871
869
|
NavigationAction,
|
|
872
870
|
EventMap
|
|
873
871
|
>({
|
|
874
|
-
id: options.id,
|
|
875
872
|
onAction,
|
|
876
873
|
onUnhandledAction,
|
|
877
874
|
getState,
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
import * as React from 'react';
|
|
9
9
|
|
|
10
10
|
import { NavigationBuilderContext } from './NavigationBuilderContext';
|
|
11
|
+
import { NavigationContext } from './NavigationProvider';
|
|
11
12
|
import type { NavigationHelpers, NavigationProp } from './types';
|
|
12
13
|
import type { NavigationEventEmitter } from './useEventEmitter';
|
|
13
14
|
|
|
@@ -33,20 +34,25 @@ type NavigationItem<
|
|
|
33
34
|
State extends NavigationState,
|
|
34
35
|
ScreenOptions extends {},
|
|
35
36
|
EventMap extends Record<string, any>,
|
|
37
|
+
ActionHelpers extends Record<string, (...args: any) => void>,
|
|
36
38
|
> = NavigationProp<
|
|
37
39
|
ParamListBase,
|
|
38
40
|
string,
|
|
39
|
-
string | undefined,
|
|
40
41
|
State,
|
|
41
42
|
ScreenOptions,
|
|
42
|
-
EventMap
|
|
43
|
+
EventMap,
|
|
44
|
+
ActionHelpers
|
|
43
45
|
>;
|
|
44
46
|
|
|
45
47
|
type NavigationCache<
|
|
46
48
|
State extends NavigationState,
|
|
47
49
|
ScreenOptions extends {},
|
|
48
50
|
EventMap extends Record<string, any>,
|
|
49
|
-
|
|
51
|
+
ActionHelpers extends Record<string, (...args: any) => void>,
|
|
52
|
+
> = Record<
|
|
53
|
+
string,
|
|
54
|
+
NavigationItem<State, ScreenOptions, EventMap, ActionHelpers>
|
|
55
|
+
>;
|
|
50
56
|
|
|
51
57
|
/**
|
|
52
58
|
* Hook to cache navigation objects for each screen in the navigator.
|
|
@@ -57,7 +63,7 @@ export function useNavigationCache<
|
|
|
57
63
|
State extends NavigationState,
|
|
58
64
|
ScreenOptions extends {},
|
|
59
65
|
EventMap extends Record<string, any>,
|
|
60
|
-
ActionHelpers extends Record<string, () => void>,
|
|
66
|
+
ActionHelpers extends Record<string, (...args: any) => void>,
|
|
61
67
|
>({
|
|
62
68
|
state,
|
|
63
69
|
getState,
|
|
@@ -66,12 +72,14 @@ export function useNavigationCache<
|
|
|
66
72
|
router,
|
|
67
73
|
emitter,
|
|
68
74
|
}: Options<State, ScreenOptions, EventMap>) {
|
|
75
|
+
const parentNavigationHelpers = React.useContext(NavigationContext);
|
|
69
76
|
const { stackRef } = React.useContext(NavigationBuilderContext);
|
|
70
77
|
|
|
71
78
|
const base = React.useMemo((): NavigationItem<
|
|
72
79
|
State,
|
|
73
80
|
ScreenOptions,
|
|
74
|
-
EventMap
|
|
81
|
+
EventMap,
|
|
82
|
+
ActionHelpers
|
|
75
83
|
> &
|
|
76
84
|
ActionHelpers => {
|
|
77
85
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@@ -97,6 +105,7 @@ export function useNavigationCache<
|
|
|
97
105
|
{}
|
|
98
106
|
) as ActionHelpers;
|
|
99
107
|
|
|
108
|
+
// @ts-expect-error: type of getParent does not match
|
|
100
109
|
return {
|
|
101
110
|
...rest,
|
|
102
111
|
...helpers,
|
|
@@ -111,31 +120,40 @@ export function useNavigationCache<
|
|
|
111
120
|
// Event listeners are not supported for placeholder screens
|
|
112
121
|
},
|
|
113
122
|
dispatch,
|
|
114
|
-
getParent: (
|
|
115
|
-
if (
|
|
116
|
-
|
|
123
|
+
getParent: (routeName) => {
|
|
124
|
+
if (routeName !== undefined) {
|
|
125
|
+
throw new Error(
|
|
126
|
+
'Getting parent by route name is not supported from a placeholder screen.'
|
|
127
|
+
);
|
|
117
128
|
}
|
|
118
129
|
|
|
119
|
-
return
|
|
130
|
+
return parentNavigationHelpers;
|
|
120
131
|
},
|
|
121
132
|
setOptions: () => {
|
|
122
133
|
throw new Error('Options cannot be set from a placeholder screen.');
|
|
123
134
|
},
|
|
124
135
|
isFocused: () => false,
|
|
125
136
|
};
|
|
126
|
-
}, [navigation, router.actionCreators]);
|
|
137
|
+
}, [parentNavigationHelpers, navigation, router.actionCreators]);
|
|
127
138
|
|
|
128
139
|
// Cache object which holds navigation objects for each screen
|
|
129
140
|
// We use `React.useMemo` instead of `React.useRef` coz we want to invalidate it when deps change
|
|
130
141
|
// In reality, these deps will rarely change, if ever
|
|
131
142
|
const cache = React.useMemo(
|
|
132
|
-
() => ({
|
|
143
|
+
() => ({
|
|
144
|
+
current: {} as NavigationCache<
|
|
145
|
+
State,
|
|
146
|
+
ScreenOptions,
|
|
147
|
+
EventMap,
|
|
148
|
+
ActionHelpers
|
|
149
|
+
>,
|
|
150
|
+
}),
|
|
133
151
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
134
|
-
[base, getState, navigation, setOptions, emitter]
|
|
152
|
+
[base, getState, parentNavigationHelpers, navigation, setOptions, emitter]
|
|
135
153
|
);
|
|
136
154
|
|
|
137
155
|
cache.current = state.routes.reduce<
|
|
138
|
-
NavigationCache<State, ScreenOptions, EventMap>
|
|
156
|
+
NavigationCache<State, ScreenOptions, EventMap, ActionHelpers>
|
|
139
157
|
>((acc, route) => {
|
|
140
158
|
const previous = cache.current[route.key];
|
|
141
159
|
|
|
@@ -201,14 +219,18 @@ export function useNavigationCache<
|
|
|
201
219
|
// FIXME: too much work to fix the types for now
|
|
202
220
|
...(emitter.create(route.key) as any),
|
|
203
221
|
dispatch: (thunk: Thunk) => withStack(() => dispatch(thunk)),
|
|
204
|
-
getParent: (
|
|
205
|
-
if (
|
|
206
|
-
// If the passed
|
|
207
|
-
// we return the cached navigation object for the
|
|
222
|
+
getParent: (routeName) => {
|
|
223
|
+
if (routeName === route.name) {
|
|
224
|
+
// If the passed route name is the same as the current route's name,
|
|
225
|
+
// we return the cached navigation object for the route
|
|
208
226
|
return acc[route.key];
|
|
209
227
|
}
|
|
210
228
|
|
|
211
|
-
|
|
229
|
+
if (routeName !== undefined) {
|
|
230
|
+
return parentNavigationHelpers?.getParent(routeName);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return parentNavigationHelpers;
|
|
212
234
|
},
|
|
213
235
|
setOptions: (options: object) => {
|
|
214
236
|
setOptions((o) => ({
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
|
|
3
3
|
import { createNavigationContainerRef } from './createNavigationContainerRef';
|
|
4
|
-
import type { NavigationContainerRefWithCurrent } from './types';
|
|
4
|
+
import type { NavigationContainerRefWithCurrent, RootParamList } from './types';
|
|
5
5
|
|
|
6
6
|
export function useNavigationContainerRef<
|
|
7
|
-
ParamList extends {} =
|
|
7
|
+
ParamList extends {} = RootParamList,
|
|
8
8
|
>(): NavigationContainerRefWithCurrent<ParamList> {
|
|
9
9
|
const navigation =
|
|
10
10
|
React.useRef<NavigationContainerRefWithCurrent<ParamList> | null>(null);
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from '@react-navigation/routers';
|
|
8
8
|
import * as React from 'react';
|
|
9
9
|
|
|
10
|
-
import { NavigationContext } from './
|
|
10
|
+
import { NavigationContext } from './NavigationProvider';
|
|
11
11
|
import { type NavigationHelpers, PrivateValueStore } from './types';
|
|
12
12
|
import type { NavigationEventEmitter } from './useEventEmitter';
|
|
13
13
|
|
|
@@ -16,7 +16,6 @@ import type { NavigationEventEmitter } from './useEventEmitter';
|
|
|
16
16
|
PrivateValueStore;
|
|
17
17
|
|
|
18
18
|
type Options<State extends NavigationState, Action extends NavigationAction> = {
|
|
19
|
-
id: string | undefined;
|
|
20
19
|
onAction: (action: NavigationAction) => boolean;
|
|
21
20
|
onUnhandledAction: (action: NavigationAction) => void;
|
|
22
21
|
getState: () => State;
|
|
@@ -31,11 +30,10 @@ type Options<State extends NavigationState, Action extends NavigationAction> = {
|
|
|
31
30
|
*/
|
|
32
31
|
export function useNavigationHelpers<
|
|
33
32
|
State extends NavigationState,
|
|
34
|
-
ActionHelpers extends Record<string, () => void>,
|
|
33
|
+
ActionHelpers extends Record<string, (...args: any) => void>,
|
|
35
34
|
Action extends NavigationAction,
|
|
36
35
|
EventMap extends Record<string, any>,
|
|
37
36
|
>({
|
|
38
|
-
id: navigatorId,
|
|
39
37
|
onAction,
|
|
40
38
|
onUnhandledAction,
|
|
41
39
|
getState,
|
|
@@ -88,20 +86,6 @@ export function useNavigationHelpers<
|
|
|
88
86
|
false
|
|
89
87
|
);
|
|
90
88
|
},
|
|
91
|
-
getId: () => navigatorId,
|
|
92
|
-
getParent: (id?: string) => {
|
|
93
|
-
if (id !== undefined) {
|
|
94
|
-
let current = navigationHelpers;
|
|
95
|
-
|
|
96
|
-
while (current && id !== current.getId()) {
|
|
97
|
-
current = current.getParent();
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return current;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return parentNavigationHelpers;
|
|
104
|
-
},
|
|
105
89
|
getState: (): State => {
|
|
106
90
|
// FIXME: Workaround for when the state is read during render
|
|
107
91
|
// By this time, we haven't committed the new state yet
|
|
@@ -124,7 +108,6 @@ export function useNavigationHelpers<
|
|
|
124
108
|
getState,
|
|
125
109
|
onAction,
|
|
126
110
|
onUnhandledAction,
|
|
127
|
-
navigatorId,
|
|
128
111
|
stateRef,
|
|
129
112
|
]);
|
|
130
113
|
}
|