@react-navigation/core 7.13.7 → 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.
- 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
|
}
|
|
@@ -20,7 +20,7 @@ import { Group } from './Group';
|
|
|
20
20
|
import { isArrayEqual } from './isArrayEqual';
|
|
21
21
|
import { isRecordEqual } from './isRecordEqual';
|
|
22
22
|
import { NavigationHelpersContext } from './NavigationHelpersContext';
|
|
23
|
-
import { NavigationRouteContext } from './
|
|
23
|
+
import { NavigationRouteContext } from './NavigationProvider';
|
|
24
24
|
import { NavigationStateContext } from './NavigationStateContext';
|
|
25
25
|
import { PreventRemoveProvider } from './PreventRemoveProvider';
|
|
26
26
|
import { Screen } from './Screen';
|
|
@@ -34,7 +34,6 @@ import {
|
|
|
34
34
|
} from './types';
|
|
35
35
|
import { UnhandledActionContext } from './UnhandledActionContext';
|
|
36
36
|
import { useChildListeners } from './useChildListeners';
|
|
37
|
-
import { useClientLayoutEffect } from './useClientLayoutEffect';
|
|
38
37
|
import { useComponent } from './useComponent';
|
|
39
38
|
import { useCurrentRender } from './useCurrentRender';
|
|
40
39
|
import { type ScreenConfigWithParent, useDescriptors } from './useDescriptors';
|
|
@@ -310,7 +309,6 @@ export function useNavigationBuilder<
|
|
|
310
309
|
createRouter: RouterFactory<State, NavigationAction, RouterOptions>,
|
|
311
310
|
options: DefaultNavigatorOptions<
|
|
312
311
|
ParamListBase,
|
|
313
|
-
string | undefined,
|
|
314
312
|
State,
|
|
315
313
|
ScreenOptions,
|
|
316
314
|
EventMap,
|
|
@@ -330,7 +328,7 @@ export function useNavigationBuilder<
|
|
|
330
328
|
screenOptions,
|
|
331
329
|
screenLayout,
|
|
332
330
|
screenListeners,
|
|
333
|
-
|
|
331
|
+
router: routerOverrides,
|
|
334
332
|
...rest
|
|
335
333
|
} = options;
|
|
336
334
|
|
|
@@ -354,8 +352,8 @@ export function useNavigationBuilder<
|
|
|
354
352
|
|
|
355
353
|
const original = createRouter(rest as unknown as RouterOptions);
|
|
356
354
|
|
|
357
|
-
if (
|
|
358
|
-
const overrides =
|
|
355
|
+
if (routerOverrides != null) {
|
|
356
|
+
const overrides = routerOverrides(original);
|
|
359
357
|
|
|
360
358
|
return {
|
|
361
359
|
...original,
|
|
@@ -519,7 +517,7 @@ export function useNavigationBuilder<
|
|
|
519
517
|
);
|
|
520
518
|
|
|
521
519
|
if (
|
|
522
|
-
options.
|
|
520
|
+
options.routeNamesChangeBehavior === 'lastUnhandled' &&
|
|
523
521
|
doesStateHaveOnlyInvalidRoutes(stateBeforeInitialization)
|
|
524
522
|
) {
|
|
525
523
|
return [stateBeforeInitialization, hydratedState, true];
|
|
@@ -552,7 +550,7 @@ export function useNavigationBuilder<
|
|
|
552
550
|
// It's possible that they were absent due to conditional render
|
|
553
551
|
// Store this state so we can reuse it if the routes change later
|
|
554
552
|
if (
|
|
555
|
-
options.
|
|
553
|
+
options.routeNamesChangeBehavior === 'lastUnhandled' &&
|
|
556
554
|
stateBeforeInitialization &&
|
|
557
555
|
unhandledState !== stateBeforeInitialization
|
|
558
556
|
) {
|
|
@@ -620,7 +618,7 @@ export function useNavigationBuilder<
|
|
|
620
618
|
route.params !== previousParams
|
|
621
619
|
) {
|
|
622
620
|
if (
|
|
623
|
-
options.
|
|
621
|
+
options.routeNamesChangeBehavior === 'lastUnhandled' &&
|
|
624
622
|
doesStateHaveOnlyInvalidRoutes(route.params.state)
|
|
625
623
|
) {
|
|
626
624
|
if (route.params.state !== unhandledState) {
|
|
@@ -636,7 +634,7 @@ export function useNavigationBuilder<
|
|
|
636
634
|
route.params !== previousParams)
|
|
637
635
|
) {
|
|
638
636
|
if (
|
|
639
|
-
options.
|
|
637
|
+
options.routeNamesChangeBehavior === 'lastUnhandled' &&
|
|
640
638
|
!routeNames.includes(route.params.screen)
|
|
641
639
|
) {
|
|
642
640
|
const state = getStateFromParams(route.params);
|
|
@@ -729,7 +727,7 @@ export function useNavigationBuilder<
|
|
|
729
727
|
|
|
730
728
|
stateRef.current = state;
|
|
731
729
|
|
|
732
|
-
|
|
730
|
+
React.useLayoutEffect(() => {
|
|
733
731
|
stateRef.current = null;
|
|
734
732
|
});
|
|
735
733
|
|
|
@@ -832,7 +830,7 @@ export function useNavigationBuilder<
|
|
|
832
830
|
|
|
833
831
|
const onUnhandledAction = useLatestCallback((action: NavigationAction) => {
|
|
834
832
|
if (
|
|
835
|
-
options.
|
|
833
|
+
options.routeNamesChangeBehavior === 'lastUnhandled' &&
|
|
836
834
|
action.type === 'NAVIGATE' &&
|
|
837
835
|
action.payload != null &&
|
|
838
836
|
'name' in action.payload &&
|
|
@@ -870,7 +868,6 @@ export function useNavigationBuilder<
|
|
|
870
868
|
NavigationAction,
|
|
871
869
|
EventMap
|
|
872
870
|
>({
|
|
873
|
-
id: options.id,
|
|
874
871
|
onAction,
|
|
875
872
|
onUnhandledAction,
|
|
876
873
|
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
|
}
|