@react-navigation/core 8.0.0-alpha.2 → 8.0.0-alpha.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/module/BaseNavigationContainer.js +20 -9
- package/lib/module/BaseNavigationContainer.js.map +1 -1
- package/lib/module/ConsumedParamsContext.js +5 -0
- package/lib/module/ConsumedParamsContext.js.map +1 -0
- package/lib/module/NavigationBuilderContext.js +1 -0
- package/lib/module/NavigationBuilderContext.js.map +1 -1
- package/lib/module/NavigationIndependentTree.js +8 -4
- package/lib/module/NavigationIndependentTree.js.map +1 -1
- package/lib/module/NavigationProvider.js +14 -3
- package/lib/module/NavigationProvider.js.map +1 -1
- package/lib/module/NavigationStateContext.js.map +1 -1
- package/lib/module/PreventRemoveProvider.js +3 -3
- package/lib/module/PreventRemoveProvider.js.map +1 -1
- package/lib/module/SceneView.js +46 -56
- package/lib/module/SceneView.js.map +1 -1
- package/lib/module/StaticNavigation.js +166 -46
- package/lib/module/StaticNavigation.js.map +1 -1
- package/lib/module/checkSerializable.js +11 -4
- package/lib/module/checkSerializable.js.map +1 -1
- package/lib/module/createNavigatorFactory.js +27 -5
- package/lib/module/createNavigatorFactory.js.map +1 -1
- package/lib/module/findFocusedRoute.js +7 -4
- package/lib/module/findFocusedRoute.js.map +1 -1
- package/lib/module/getActionFromState.js +40 -14
- package/lib/module/getActionFromState.js.map +1 -1
- package/lib/module/getPathFromState.js +48 -11
- package/lib/module/getPathFromState.js.map +1 -1
- package/lib/module/getPatternParts.js +3 -0
- package/lib/module/getPatternParts.js.map +1 -1
- package/lib/module/getStateFromPath.js +353 -166
- package/lib/module/getStateFromPath.js.map +1 -1
- package/lib/module/getStateFromRouteParams.js +24 -0
- package/lib/module/getStateFromRouteParams.js.map +1 -0
- package/lib/module/index.js +3 -4
- package/lib/module/index.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 +15 -0
- package/lib/module/types.js.map +1 -1
- package/lib/module/useDescriptors.js +18 -9
- package/lib/module/useDescriptors.js.map +1 -1
- package/lib/module/useEventEmitter.js +43 -31
- package/lib/module/useEventEmitter.js.map +1 -1
- package/lib/module/useFocusEvents.js +6 -2
- package/lib/module/useFocusEvents.js.map +1 -1
- package/lib/module/useFocusedListenersChildrenAdapter.js +2 -2
- package/lib/module/useFocusedListenersChildrenAdapter.js.map +1 -1
- package/lib/module/useIsFocused.js +7 -12
- package/lib/module/useIsFocused.js.map +1 -1
- package/lib/module/useNavigation.js.map +1 -1
- package/lib/module/useNavigationBuilder.js +144 -86
- package/lib/module/useNavigationBuilder.js.map +1 -1
- package/lib/module/useNavigationCache.js +3 -3
- package/lib/module/useNavigationCache.js.map +1 -1
- package/lib/module/useNavigationHelpers.js +1 -1
- package/lib/module/useNavigationHelpers.js.map +1 -1
- package/lib/module/useNavigationIndependentTree.js +1 -1
- package/lib/module/useNavigationIndependentTree.js.map +1 -1
- package/lib/module/useNavigationState.js +6 -4
- package/lib/module/useNavigationState.js.map +1 -1
- package/lib/module/useOnAction.js +3 -3
- package/lib/module/useOnAction.js.map +1 -1
- package/lib/module/useOnGetState.js +6 -3
- package/lib/module/useOnGetState.js.map +1 -1
- package/lib/module/useOnPreventRemove.js +3 -3
- package/lib/module/useOnPreventRemove.js.map +1 -1
- package/lib/module/useOnRouteFocus.js +1 -1
- package/lib/module/useOnRouteFocus.js.map +1 -1
- package/lib/module/useOptionsGetters.js +7 -4
- package/lib/module/useOptionsGetters.js.map +1 -1
- package/lib/module/usePreventRemove.js +1 -1
- package/lib/module/usePreventRemove.js.map +1 -1
- package/lib/module/usePreventRemoveContext.js +1 -1
- package/lib/module/usePreventRemoveContext.js.map +1 -1
- package/lib/module/useRegisterNavigator.js +2 -2
- package/lib/module/useRegisterNavigator.js.map +1 -1
- package/lib/module/useRoute.js.map +1 -1
- package/lib/module/useRouteCache.js +2 -1
- package/lib/module/useRouteCache.js.map +1 -1
- package/lib/module/useScheduleUpdate.js +1 -1
- package/lib/module/useScheduleUpdate.js.map +1 -1
- package/lib/module/useStateForPath.js +1 -1
- package/lib/module/useStateForPath.js.map +1 -1
- package/lib/module/validatePathConfig.js +2 -1
- package/lib/module/validatePathConfig.js.map +1 -1
- package/lib/typescript/src/BaseNavigationContainer.d.ts +6 -3
- package/lib/typescript/src/BaseNavigationContainer.d.ts.map +1 -1
- package/lib/typescript/src/ConsumedParamsContext.d.ts +8 -0
- package/lib/typescript/src/ConsumedParamsContext.d.ts.map +1 -0
- package/lib/typescript/src/EnsureSingleNavigator.d.ts +1 -1
- package/lib/typescript/src/EnsureSingleNavigator.d.ts.map +1 -1
- package/lib/typescript/src/Group.d.ts +1 -1
- package/lib/typescript/src/Group.d.ts.map +1 -1
- package/lib/typescript/src/NavigationBuilderContext.d.ts +12 -6
- package/lib/typescript/src/NavigationBuilderContext.d.ts.map +1 -1
- package/lib/typescript/src/NavigationContainerRefContext.d.ts +1 -1
- package/lib/typescript/src/NavigationContainerRefContext.d.ts.map +1 -1
- package/lib/typescript/src/NavigationFocusedRouteStateContext.d.ts +4 -4
- package/lib/typescript/src/NavigationFocusedRouteStateContext.d.ts.map +1 -1
- package/lib/typescript/src/NavigationHelpersContext.d.ts +1 -1
- package/lib/typescript/src/NavigationHelpersContext.d.ts.map +1 -1
- package/lib/typescript/src/NavigationIndependentTree.d.ts +1 -1
- package/lib/typescript/src/NavigationIndependentTree.d.ts.map +1 -1
- package/lib/typescript/src/NavigationProvider.d.ts +10 -10
- package/lib/typescript/src/NavigationProvider.d.ts.map +1 -1
- package/lib/typescript/src/NavigationStateContext.d.ts +3 -3
- package/lib/typescript/src/NavigationStateContext.d.ts.map +1 -1
- package/lib/typescript/src/PreventRemoveProvider.d.ts +1 -1
- package/lib/typescript/src/PreventRemoveProvider.d.ts.map +1 -1
- package/lib/typescript/src/SceneView.d.ts +3 -2
- package/lib/typescript/src/SceneView.d.ts.map +1 -1
- package/lib/typescript/src/Screen.d.ts +1 -1
- package/lib/typescript/src/Screen.d.ts.map +1 -1
- package/lib/typescript/src/StaticContainer.d.ts +1 -1
- package/lib/typescript/src/StaticContainer.d.ts.map +1 -1
- package/lib/typescript/src/StaticNavigation.d.ts +123 -92
- package/lib/typescript/src/StaticNavigation.d.ts.map +1 -1
- package/lib/typescript/src/checkSerializable.d.ts +5 -3
- package/lib/typescript/src/checkSerializable.d.ts.map +1 -1
- package/lib/typescript/src/createNavigationContainerRef.d.ts +1 -1
- package/lib/typescript/src/createNavigationContainerRef.d.ts.map +1 -1
- package/lib/typescript/src/createNavigatorFactory.d.ts +17 -5
- package/lib/typescript/src/createNavigatorFactory.d.ts.map +1 -1
- package/lib/typescript/src/findFocusedRoute.d.ts +3 -3
- package/lib/typescript/src/findFocusedRoute.d.ts.map +1 -1
- package/lib/typescript/src/getActionFromState.d.ts +4 -4
- package/lib/typescript/src/getActionFromState.d.ts.map +1 -1
- package/lib/typescript/src/getPathFromState.d.ts +3 -3
- package/lib/typescript/src/getPathFromState.d.ts.map +1 -1
- package/lib/typescript/src/getPatternParts.d.ts +1 -0
- package/lib/typescript/src/getPatternParts.d.ts.map +1 -1
- package/lib/typescript/src/getStateFromPath.d.ts +5 -5
- package/lib/typescript/src/getStateFromPath.d.ts.map +1 -1
- package/lib/typescript/src/getStateFromRouteParams.d.ts +3 -0
- package/lib/typescript/src/getStateFromRouteParams.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +34 -33
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/theming/ThemeContext.d.ts +1 -1
- package/lib/typescript/src/theming/ThemeContext.d.ts.map +1 -1
- package/lib/typescript/src/theming/ThemeProvider.d.ts +2 -2
- 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 +215 -131
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/useChildListeners.d.ts +3 -3
- package/lib/typescript/src/useChildListeners.d.ts.map +1 -1
- package/lib/typescript/src/useComponent.d.ts +1 -1
- package/lib/typescript/src/useComponent.d.ts.map +1 -1
- package/lib/typescript/src/useDescriptors.d.ts +7 -7
- package/lib/typescript/src/useDescriptors.d.ts.map +1 -1
- package/lib/typescript/src/useEventEmitter.d.ts +1 -1
- package/lib/typescript/src/useEventEmitter.d.ts.map +1 -1
- package/lib/typescript/src/useFocusEvents.d.ts +2 -2
- package/lib/typescript/src/useFocusEvents.d.ts.map +1 -1
- package/lib/typescript/src/useFocusedListenersChildrenAdapter.d.ts +2 -2
- package/lib/typescript/src/useFocusedListenersChildrenAdapter.d.ts.map +1 -1
- package/lib/typescript/src/useIsFocused.d.ts +3 -0
- package/lib/typescript/src/useIsFocused.d.ts.map +1 -1
- package/lib/typescript/src/useKeyedChildListeners.d.ts +3 -3
- package/lib/typescript/src/useKeyedChildListeners.d.ts.map +1 -1
- package/lib/typescript/src/useNavigation.d.ts +5 -3
- package/lib/typescript/src/useNavigation.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationBuilder.d.ts +24 -24
- package/lib/typescript/src/useNavigationBuilder.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationCache.d.ts +3 -3
- package/lib/typescript/src/useNavigationCache.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationContainerRef.d.ts +1 -1
- package/lib/typescript/src/useNavigationContainerRef.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationHelpers.d.ts +19 -19
- package/lib/typescript/src/useNavigationHelpers.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationState.d.ts +2 -2
- package/lib/typescript/src/useNavigationState.d.ts.map +1 -1
- package/lib/typescript/src/useOnAction.d.ts +9 -9
- package/lib/typescript/src/useOnAction.d.ts.map +1 -1
- package/lib/typescript/src/useOnGetState.d.ts +1 -1
- package/lib/typescript/src/useOnGetState.d.ts.map +1 -1
- package/lib/typescript/src/useOnPreventRemove.d.ts +3 -3
- package/lib/typescript/src/useOnPreventRemove.d.ts.map +1 -1
- package/lib/typescript/src/useOnRouteFocus.d.ts +6 -6
- package/lib/typescript/src/useOnRouteFocus.d.ts.map +1 -1
- package/lib/typescript/src/useOptionsGetters.d.ts +1 -1
- package/lib/typescript/src/useOptionsGetters.d.ts.map +1 -1
- package/lib/typescript/src/usePreventRemoveContext.d.ts +1 -1
- package/lib/typescript/src/useRoute.d.ts +2 -2
- package/lib/typescript/src/useRoute.d.ts.map +1 -1
- package/lib/typescript/src/useRouteCache.d.ts +4 -4
- package/lib/typescript/src/useRouteCache.d.ts.map +1 -1
- package/lib/typescript/src/useScheduleUpdate.d.ts.map +1 -1
- package/lib/typescript/src/useStateForPath.d.ts +1 -1
- package/lib/typescript/src/useStateForPath.d.ts.map +1 -1
- package/lib/typescript/src/utilities.d.ts +45 -5
- package/lib/typescript/src/utilities.d.ts.map +1 -1
- package/lib/typescript/src/validatePathConfig.d.ts.map +1 -1
- package/package.json +23 -20
- package/src/BaseNavigationContainer.tsx +337 -326
- package/src/ConsumedParamsContext.tsx +10 -0
- package/src/NavigationBuilderContext.tsx +14 -8
- package/src/NavigationFocusedRouteStateContext.tsx +4 -4
- package/src/NavigationIndependentTree.tsx +8 -5
- package/src/NavigationProvider.tsx +17 -3
- package/src/NavigationStateContext.tsx +5 -6
- package/src/PreventRemoveProvider.tsx +3 -3
- package/src/SceneView.tsx +58 -56
- package/src/StaticNavigation.tsx +488 -250
- package/src/checkSerializable.tsx +22 -12
- package/src/createNavigatorFactory.tsx +83 -8
- package/src/findFocusedRoute.tsx +13 -8
- package/src/getActionFromState.tsx +68 -39
- package/src/getPathFromState.tsx +91 -27
- package/src/getPatternParts.tsx +8 -0
- package/src/getStateFromPath.tsx +555 -180
- package/src/getStateFromRouteParams.tsx +60 -0
- package/src/index.tsx +47 -5
- package/src/theming/useTheme.tsx +1 -1
- package/src/types.tsx +541 -338
- package/src/useDescriptors.tsx +27 -12
- package/src/useEventEmitter.tsx +45 -36
- package/src/useFocusEvents.tsx +8 -2
- package/src/useFocusedListenersChildrenAdapter.tsx +2 -2
- package/src/useIsFocused.tsx +14 -21
- package/src/useNavigation.tsx +8 -4
- package/src/useNavigationBuilder.tsx +220 -132
- package/src/useNavigationCache.tsx +6 -6
- package/src/useNavigationHelpers.tsx +1 -1
- package/src/useNavigationIndependentTree.tsx +1 -1
- package/src/useNavigationState.tsx +11 -7
- package/src/useOnAction.tsx +10 -10
- package/src/useOnGetState.tsx +5 -3
- package/src/useOnPreventRemove.tsx +3 -3
- package/src/useOnRouteFocus.tsx +10 -12
- package/src/useOptionsGetters.tsx +7 -4
- package/src/usePreventRemove.tsx +1 -1
- package/src/usePreventRemoveContext.tsx +1 -1
- package/src/useRegisterNavigator.tsx +2 -2
- package/src/useRoute.tsx +4 -2
- package/src/useRouteCache.tsx +2 -1
- package/src/useScheduleUpdate.tsx +1 -3
- package/src/useStateForPath.tsx +1 -1
- package/src/utilities.tsx +101 -5
- package/src/validatePathConfig.tsx +1 -0
- package/lib/module/CurrentRenderContext.js +0 -10
- package/lib/module/CurrentRenderContext.js.map +0 -1
- package/lib/module/useCurrentRender.js +0 -19
- package/lib/module/useCurrentRender.js.map +0 -1
- package/lib/typescript/src/CurrentRenderContext.d.ts +0 -9
- package/lib/typescript/src/CurrentRenderContext.d.ts.map +0 -1
- package/lib/typescript/src/useCurrentRender.d.ts +0 -14
- package/lib/typescript/src/useCurrentRender.d.ts.map +0 -1
- package/src/CurrentRenderContext.tsx +0 -9
- package/src/useCurrentRender.tsx +0 -31
|
@@ -3,7 +3,6 @@ import {
|
|
|
3
3
|
type InitialState,
|
|
4
4
|
type NavigationAction,
|
|
5
5
|
type NavigationState,
|
|
6
|
-
type ParamListBase,
|
|
7
6
|
type PartialState,
|
|
8
7
|
type Route,
|
|
9
8
|
} from '@react-navigation/routers';
|
|
@@ -24,6 +23,7 @@ import type {
|
|
|
24
23
|
NavigationContainerEventMap,
|
|
25
24
|
NavigationContainerProps,
|
|
26
25
|
NavigationContainerRef,
|
|
26
|
+
RootParamList,
|
|
27
27
|
} from './types';
|
|
28
28
|
import { UnhandledActionContext } from './UnhandledActionContext';
|
|
29
29
|
import { useChildListeners } from './useChildListeners';
|
|
@@ -38,6 +38,10 @@ type State = NavigationState | PartialState<NavigationState> | undefined;
|
|
|
38
38
|
const serializableWarnings: string[] = [];
|
|
39
39
|
const duplicateNameWarnings: string[] = [];
|
|
40
40
|
|
|
41
|
+
type Props<ParamList extends {}> = NavigationContainerProps & {
|
|
42
|
+
ref?: React.Ref<NavigationContainerRef<ParamList>>;
|
|
43
|
+
};
|
|
44
|
+
|
|
41
45
|
/**
|
|
42
46
|
* Remove `key` and `routeNames` from the state objects recursively to get partial state.
|
|
43
47
|
*
|
|
@@ -80,382 +84,389 @@ const getPartialState = (
|
|
|
80
84
|
* @param props.children Child elements to render the content.
|
|
81
85
|
* @param props.ref Ref object which refers to the navigation object containing helper methods.
|
|
82
86
|
*/
|
|
83
|
-
export
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
"Looks like you have nested a 'NavigationContainer' inside another. Normally you need only one container at the root of the app, so this was probably an error. If this was intentional, wrap the container in 'NavigationIndependentTree' explicitly. Note that this will make the child navigators disconnected from the parent and you won't be able to navigate between them."
|
|
101
|
-
);
|
|
102
|
-
}
|
|
87
|
+
export function BaseNavigationContainer<ParamList extends {} = RootParamList>({
|
|
88
|
+
initialState,
|
|
89
|
+
onStateChange,
|
|
90
|
+
onReady,
|
|
91
|
+
onUnhandledAction,
|
|
92
|
+
theme,
|
|
93
|
+
children,
|
|
94
|
+
ref,
|
|
95
|
+
}: Props<ParamList>) {
|
|
96
|
+
const parent = React.use(NavigationStateContext);
|
|
97
|
+
const independent = useNavigationIndependentTree();
|
|
98
|
+
|
|
99
|
+
if (!parent.isDefault && !independent) {
|
|
100
|
+
throw new Error(
|
|
101
|
+
"Looks like you have nested a 'NavigationContainer' inside another. Normally you need only one container at the root of the app, so this was probably an error. If this was intentional, wrap the container in 'NavigationIndependentTree' explicitly. Note that this will make the child navigators disconnected from the parent and you won't be able to navigate between them."
|
|
102
|
+
);
|
|
103
|
+
}
|
|
103
104
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
105
|
+
const { state, getState, setState, scheduleUpdate, flushUpdates } =
|
|
106
|
+
useSyncState<State>(() =>
|
|
107
|
+
getPartialState(initialState == null ? undefined : initialState)
|
|
108
|
+
);
|
|
108
109
|
|
|
109
|
-
|
|
110
|
+
const isFirstMountRef = React.useRef<boolean>(true);
|
|
110
111
|
|
|
111
|
-
|
|
112
|
+
const navigatorKeyRef = React.useRef<string | undefined>(undefined);
|
|
112
113
|
|
|
113
|
-
|
|
114
|
+
const getKey = React.useCallback(() => navigatorKeyRef.current, []);
|
|
114
115
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
const setKey = React.useCallback((key: string) => {
|
|
117
|
+
navigatorKeyRef.current = key;
|
|
118
|
+
}, []);
|
|
118
119
|
|
|
119
|
-
|
|
120
|
+
const { listeners, addListener } = useChildListeners();
|
|
120
121
|
|
|
121
|
-
|
|
122
|
+
const { keyedListeners, addKeyedListener } = useKeyedChildListeners();
|
|
122
123
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
} else {
|
|
132
|
-
listeners.focus[0]((navigation) => navigation.dispatch(action));
|
|
133
|
-
}
|
|
124
|
+
const dispatch = useLatestCallback(
|
|
125
|
+
(
|
|
126
|
+
action: NavigationAction | ((state: NavigationState) => NavigationAction)
|
|
127
|
+
) => {
|
|
128
|
+
if (listeners.focus[0] == null) {
|
|
129
|
+
console.error(NOT_INITIALIZED_ERROR);
|
|
130
|
+
} else {
|
|
131
|
+
listeners.focus[0]((navigation) => navigation.dispatch(action));
|
|
134
132
|
}
|
|
133
|
+
}
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
const canGoBack = useLatestCallback(() => {
|
|
137
|
+
if (listeners.focus[0] == null) {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const { result, handled } = listeners.focus[0]((navigation) =>
|
|
142
|
+
navigation.canGoBack()
|
|
135
143
|
);
|
|
136
144
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
145
|
+
if (handled) {
|
|
146
|
+
return result;
|
|
147
|
+
} else {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
});
|
|
141
151
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
);
|
|
152
|
+
const resetRoot = useLatestCallback(
|
|
153
|
+
(state: PartialState<NavigationState> | NavigationState) => {
|
|
154
|
+
const target = state?.key ?? keyedListeners.getState.root?.().key;
|
|
155
|
+
const listener = listeners.focus[0];
|
|
145
156
|
|
|
146
|
-
if (
|
|
147
|
-
|
|
157
|
+
if (target == null || listener == null) {
|
|
158
|
+
console.error(NOT_INITIALIZED_ERROR);
|
|
148
159
|
} else {
|
|
149
|
-
|
|
160
|
+
listener((navigation) =>
|
|
161
|
+
navigation.dispatch({
|
|
162
|
+
...CommonActions.reset(state),
|
|
163
|
+
target,
|
|
164
|
+
})
|
|
165
|
+
);
|
|
150
166
|
}
|
|
151
|
-
}
|
|
167
|
+
}
|
|
168
|
+
);
|
|
152
169
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
if (target == null) {
|
|
158
|
-
console.error(NOT_INITIALIZED_ERROR);
|
|
159
|
-
} else {
|
|
160
|
-
listeners.focus[0]((navigation) =>
|
|
161
|
-
navigation.dispatch({
|
|
162
|
-
...CommonActions.reset(state),
|
|
163
|
-
target,
|
|
164
|
-
})
|
|
165
|
-
);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
);
|
|
170
|
+
const getRootState = useLatestCallback(() => {
|
|
171
|
+
return keyedListeners.getState.root?.();
|
|
172
|
+
});
|
|
169
173
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
});
|
|
174
|
+
const getCurrentRoute = useLatestCallback(() => {
|
|
175
|
+
const state = getRootState();
|
|
173
176
|
|
|
174
|
-
|
|
175
|
-
|
|
177
|
+
if (state == null) {
|
|
178
|
+
return undefined;
|
|
179
|
+
}
|
|
176
180
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
181
|
+
const route = findFocusedRoute(state);
|
|
182
|
+
|
|
183
|
+
return route as Route<string> | undefined;
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
const isReady = useLatestCallback(() => listeners.focus[0] != null);
|
|
187
|
+
|
|
188
|
+
const emitter = useEventEmitter<NavigationContainerEventMap>();
|
|
189
|
+
|
|
190
|
+
const { addOptionsGetter, getCurrentOptions } = useOptionsGetters({});
|
|
191
|
+
|
|
192
|
+
const navigation: NavigationContainerRef<ParamList> = React.useMemo(
|
|
193
|
+
() => ({
|
|
194
|
+
...Object.keys(CommonActions).reduce<any>((acc, name) => {
|
|
195
|
+
acc[name] = (...args: any[]) =>
|
|
196
|
+
// @ts-expect-error: this is ok
|
|
197
|
+
dispatch(CommonActions[name](...args));
|
|
198
|
+
return acc;
|
|
199
|
+
}, {}),
|
|
200
|
+
...emitter.create('root'),
|
|
201
|
+
dispatch,
|
|
202
|
+
resetRoot,
|
|
203
|
+
isFocused: () => true,
|
|
204
|
+
canGoBack,
|
|
205
|
+
getParent: () => undefined,
|
|
206
|
+
getState,
|
|
207
|
+
getRootState,
|
|
208
|
+
getCurrentRoute,
|
|
209
|
+
getCurrentOptions,
|
|
210
|
+
isReady,
|
|
211
|
+
setOptions: () => {
|
|
212
|
+
throw new Error('Cannot call setOptions outside a screen');
|
|
213
|
+
},
|
|
214
|
+
}),
|
|
215
|
+
[
|
|
216
|
+
canGoBack,
|
|
217
|
+
dispatch,
|
|
218
|
+
emitter,
|
|
219
|
+
getCurrentOptions,
|
|
220
|
+
getCurrentRoute,
|
|
221
|
+
getRootState,
|
|
222
|
+
getState,
|
|
223
|
+
isReady,
|
|
224
|
+
resetRoot,
|
|
225
|
+
]
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
React.useImperativeHandle(ref, () => navigation, [navigation]);
|
|
229
|
+
|
|
230
|
+
const onDispatchAction = useLatestCallback(
|
|
231
|
+
(action: NavigationAction, noop: boolean) => {
|
|
232
|
+
emitter.emit({
|
|
233
|
+
type: '__unsafe_action__',
|
|
234
|
+
data: { action, noop, stack: stackRef.current },
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
const onEmitEvent = useLatestCallback(
|
|
240
|
+
(event: {
|
|
241
|
+
type: string;
|
|
242
|
+
defaultPrevented: boolean | undefined;
|
|
243
|
+
target: string | undefined;
|
|
244
|
+
data: unknown;
|
|
245
|
+
}) => {
|
|
246
|
+
emitter.emit({
|
|
247
|
+
type: '__unsafe_event__',
|
|
248
|
+
data: event,
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
);
|
|
180
252
|
|
|
181
|
-
|
|
253
|
+
const lastEmittedOptionsRef = React.useRef<object | undefined>(undefined);
|
|
182
254
|
|
|
183
|
-
|
|
184
|
-
|
|
255
|
+
const onOptionsChange = useLatestCallback((options: object) => {
|
|
256
|
+
if (lastEmittedOptionsRef.current === options) {
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
185
259
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
260
|
+
lastEmittedOptionsRef.current = options;
|
|
261
|
+
|
|
262
|
+
emitter.emit({
|
|
263
|
+
type: 'options',
|
|
264
|
+
data: { options },
|
|
265
|
+
});
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
const stackRef = React.useRef<string | undefined>(undefined);
|
|
269
|
+
|
|
270
|
+
const builderContext = React.useMemo(
|
|
271
|
+
() => ({
|
|
272
|
+
addListener,
|
|
273
|
+
addKeyedListener,
|
|
274
|
+
onDispatchAction,
|
|
275
|
+
onEmitEvent,
|
|
276
|
+
onOptionsChange,
|
|
277
|
+
scheduleUpdate,
|
|
278
|
+
flushUpdates,
|
|
279
|
+
stackRef,
|
|
280
|
+
}),
|
|
281
|
+
[
|
|
282
|
+
addListener,
|
|
283
|
+
addKeyedListener,
|
|
284
|
+
onDispatchAction,
|
|
285
|
+
onEmitEvent,
|
|
286
|
+
onOptionsChange,
|
|
287
|
+
scheduleUpdate,
|
|
288
|
+
flushUpdates,
|
|
289
|
+
]
|
|
290
|
+
);
|
|
291
|
+
|
|
292
|
+
const isInitialRef = React.useRef(true);
|
|
293
|
+
|
|
294
|
+
const getIsInitial = React.useCallback(() => isInitialRef.current, []);
|
|
295
|
+
|
|
296
|
+
const context = React.useMemo(
|
|
297
|
+
() => ({
|
|
298
|
+
state,
|
|
299
|
+
getState,
|
|
300
|
+
setState,
|
|
301
|
+
getKey,
|
|
302
|
+
setKey,
|
|
303
|
+
getIsInitial,
|
|
304
|
+
addOptionsGetter,
|
|
305
|
+
}),
|
|
306
|
+
[state, getState, setState, getKey, setKey, getIsInitial, addOptionsGetter]
|
|
307
|
+
);
|
|
227
308
|
|
|
228
|
-
|
|
309
|
+
const onReadyRef = React.useRef(onReady);
|
|
310
|
+
const onStateChangeRef = React.useRef(onStateChange);
|
|
229
311
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
});
|
|
236
|
-
}
|
|
237
|
-
);
|
|
312
|
+
React.useEffect(() => {
|
|
313
|
+
isInitialRef.current = false;
|
|
314
|
+
onStateChangeRef.current = onStateChange;
|
|
315
|
+
onReadyRef.current = onReady;
|
|
316
|
+
});
|
|
238
317
|
|
|
239
|
-
|
|
318
|
+
const onReadyCalledRef = React.useRef(false);
|
|
240
319
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
320
|
+
React.useEffect(() => {
|
|
321
|
+
if (!onReadyCalledRef.current && isReady()) {
|
|
322
|
+
onReadyCalledRef.current = true;
|
|
323
|
+
onReadyRef.current?.();
|
|
324
|
+
emitter.emit({ type: 'ready' });
|
|
325
|
+
}
|
|
326
|
+
}, [state, isReady, emitter]);
|
|
245
327
|
|
|
246
|
-
|
|
328
|
+
React.useEffect(() => {
|
|
329
|
+
const hydratedState = getRootState();
|
|
247
330
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
});
|
|
252
|
-
});
|
|
331
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
332
|
+
if (hydratedState !== undefined) {
|
|
333
|
+
const serializableResult = checkSerializable(hydratedState);
|
|
253
334
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
const builderContext = React.useMemo(
|
|
257
|
-
() => ({
|
|
258
|
-
addListener,
|
|
259
|
-
addKeyedListener,
|
|
260
|
-
onDispatchAction,
|
|
261
|
-
onOptionsChange,
|
|
262
|
-
scheduleUpdate,
|
|
263
|
-
flushUpdates,
|
|
264
|
-
stackRef,
|
|
265
|
-
}),
|
|
266
|
-
[
|
|
267
|
-
addListener,
|
|
268
|
-
addKeyedListener,
|
|
269
|
-
onDispatchAction,
|
|
270
|
-
onOptionsChange,
|
|
271
|
-
scheduleUpdate,
|
|
272
|
-
flushUpdates,
|
|
273
|
-
]
|
|
274
|
-
);
|
|
335
|
+
if (!serializableResult.serializable) {
|
|
336
|
+
const { location, reason } = serializableResult;
|
|
275
337
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
const context = React.useMemo(
|
|
281
|
-
() => ({
|
|
282
|
-
state,
|
|
283
|
-
getState,
|
|
284
|
-
setState,
|
|
285
|
-
getKey,
|
|
286
|
-
setKey,
|
|
287
|
-
getIsInitial,
|
|
288
|
-
addOptionsGetter,
|
|
289
|
-
}),
|
|
290
|
-
[
|
|
291
|
-
state,
|
|
292
|
-
getState,
|
|
293
|
-
setState,
|
|
294
|
-
getKey,
|
|
295
|
-
setKey,
|
|
296
|
-
getIsInitial,
|
|
297
|
-
addOptionsGetter,
|
|
298
|
-
]
|
|
299
|
-
);
|
|
338
|
+
let path = '';
|
|
339
|
+
let pointer: Record<any, any> = hydratedState;
|
|
340
|
+
let params = false;
|
|
300
341
|
|
|
301
|
-
|
|
302
|
-
|
|
342
|
+
for (let i = 0; i < location.length; i++) {
|
|
343
|
+
const curr = location[i];
|
|
344
|
+
const prev = location[i - 1];
|
|
303
345
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
onReadyRef.current = onReady;
|
|
308
|
-
});
|
|
346
|
+
if (curr == null) {
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
309
349
|
|
|
310
|
-
|
|
350
|
+
pointer = pointer[curr];
|
|
311
351
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
let params = false;
|
|
333
|
-
|
|
334
|
-
for (let i = 0; i < location.length; i++) {
|
|
335
|
-
const curr = location[i];
|
|
336
|
-
const prev = location[i - 1];
|
|
337
|
-
|
|
338
|
-
pointer = pointer[curr];
|
|
339
|
-
|
|
340
|
-
if (!params && curr === 'state') {
|
|
341
|
-
continue;
|
|
342
|
-
} else if (!params && curr === 'routes') {
|
|
343
|
-
if (path) {
|
|
344
|
-
path += ' > ';
|
|
345
|
-
}
|
|
346
|
-
} else if (
|
|
347
|
-
!params &&
|
|
348
|
-
typeof curr === 'number' &&
|
|
349
|
-
prev === 'routes'
|
|
350
|
-
) {
|
|
351
|
-
path += pointer?.name;
|
|
352
|
-
} else if (!params) {
|
|
353
|
-
path += ` > ${curr}`;
|
|
354
|
-
params = true;
|
|
352
|
+
if (!params && curr === 'state') {
|
|
353
|
+
continue;
|
|
354
|
+
} else if (!params && curr === 'routes') {
|
|
355
|
+
if (path) {
|
|
356
|
+
path += ' > ';
|
|
357
|
+
}
|
|
358
|
+
} else if (
|
|
359
|
+
!params &&
|
|
360
|
+
typeof curr === 'number' &&
|
|
361
|
+
prev === 'routes'
|
|
362
|
+
) {
|
|
363
|
+
path += pointer?.name;
|
|
364
|
+
} else if (!params) {
|
|
365
|
+
path += ` > ${curr}`;
|
|
366
|
+
params = true;
|
|
367
|
+
} else {
|
|
368
|
+
if (typeof curr === 'number' || /^[0-9]+$/.test(curr)) {
|
|
369
|
+
path += `[${curr}]`;
|
|
370
|
+
} else if (/^[a-z$_]+$/i.test(curr)) {
|
|
371
|
+
path += `.${curr}`;
|
|
355
372
|
} else {
|
|
356
|
-
|
|
357
|
-
path += `[${curr}]`;
|
|
358
|
-
} else if (/^[a-z$_]+$/i.test(curr)) {
|
|
359
|
-
path += `.${curr}`;
|
|
360
|
-
} else {
|
|
361
|
-
path += `[${JSON.stringify(curr)}]`;
|
|
362
|
-
}
|
|
373
|
+
path += `[${JSON.stringify(curr)}]`;
|
|
363
374
|
}
|
|
364
375
|
}
|
|
376
|
+
}
|
|
365
377
|
|
|
366
|
-
|
|
378
|
+
const message = `Non-serializable values were found in the navigation state. Check:\n\n${path} (${reason})\n\nThis can break usage such as persisting and restoring state. This might happen if you passed non-serializable values such as function, class instances etc. in params. If you need to use components with callbacks in your options, you can use 'navigation.setOptions' instead. See https://reactnavigation.org/docs/troubleshooting#i-get-the-warning-non-serializable-values-were-found-in-the-navigation-state for more details.`;
|
|
367
379
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
}
|
|
380
|
+
if (!serializableWarnings.includes(message)) {
|
|
381
|
+
serializableWarnings.push(message);
|
|
382
|
+
console.warn(message);
|
|
372
383
|
}
|
|
384
|
+
}
|
|
373
385
|
|
|
374
|
-
|
|
375
|
-
|
|
386
|
+
const duplicateRouteNamesResult =
|
|
387
|
+
checkDuplicateRouteNames(hydratedState);
|
|
376
388
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
389
|
+
if (duplicateRouteNamesResult.length) {
|
|
390
|
+
const message = `Found screens with the same name nested inside one another. Check:\n${duplicateRouteNamesResult.map(
|
|
391
|
+
(locations) => `\n${locations.join(', ')}`
|
|
392
|
+
)}\n\nThis can cause confusing behavior during navigation. Consider using unique names for each screen instead.`;
|
|
381
393
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
}
|
|
394
|
+
if (!duplicateNameWarnings.includes(message)) {
|
|
395
|
+
duplicateNameWarnings.push(message);
|
|
396
|
+
console.warn(message);
|
|
386
397
|
}
|
|
387
398
|
}
|
|
388
399
|
}
|
|
400
|
+
}
|
|
389
401
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
if (!isFirstMountRef.current && onStateChangeRef.current) {
|
|
393
|
-
onStateChangeRef.current(hydratedState);
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
isFirstMountRef.current = false;
|
|
397
|
-
}, [getRootState, emitter, state]);
|
|
402
|
+
emitter.emit({ type: 'state', data: { state } });
|
|
398
403
|
|
|
399
|
-
|
|
400
|
-
(
|
|
401
|
-
|
|
402
|
-
return;
|
|
403
|
-
}
|
|
404
|
+
if (!isFirstMountRef.current && onStateChangeRef.current) {
|
|
405
|
+
onStateChangeRef.current(hydratedState);
|
|
406
|
+
}
|
|
404
407
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
let message = `The action '${action.type}'${
|
|
408
|
-
payload ? ` with payload ${JSON.stringify(action.payload)}` : ''
|
|
409
|
-
} was not handled by any navigator.`;
|
|
410
|
-
|
|
411
|
-
switch (action.type) {
|
|
412
|
-
case 'PRELOAD':
|
|
413
|
-
case 'NAVIGATE':
|
|
414
|
-
case 'PUSH':
|
|
415
|
-
case 'REPLACE':
|
|
416
|
-
case 'POP_TO':
|
|
417
|
-
case 'JUMP_TO':
|
|
418
|
-
if (payload?.name) {
|
|
419
|
-
message += `\n\nDo you have a screen named '${payload.name}'?\n\nIf you're trying to navigate to a screen in a nested navigator, see https://reactnavigation.org/docs/nesting-navigators#navigating-to-a-screen-in-a-nested-navigator.\n\nIf you're using conditional rendering, navigation will happen automatically and you shouldn't navigate manually, see.`;
|
|
420
|
-
} else {
|
|
421
|
-
message += `\n\nYou need to pass the name of the screen to navigate to.\n\nSee https://reactnavigation.org/docs/navigation-actions for usage.`;
|
|
422
|
-
}
|
|
408
|
+
isFirstMountRef.current = false;
|
|
409
|
+
}, [getRootState, emitter, state]);
|
|
423
410
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
break;
|
|
430
|
-
case 'OPEN_DRAWER':
|
|
431
|
-
case 'CLOSE_DRAWER':
|
|
432
|
-
case 'TOGGLE_DRAWER':
|
|
433
|
-
message += `\n\nIs your screen inside a Drawer navigator?`;
|
|
434
|
-
break;
|
|
435
|
-
}
|
|
411
|
+
const defaultOnUnhandledAction = useLatestCallback(
|
|
412
|
+
(action: NavigationAction) => {
|
|
413
|
+
if (process.env.NODE_ENV === 'production') {
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
436
416
|
|
|
437
|
-
|
|
417
|
+
const payload: Record<string, any> | undefined = action.payload;
|
|
418
|
+
|
|
419
|
+
let message = `The action '${action.type}'${
|
|
420
|
+
payload ? ` with payload ${JSON.stringify(action.payload)}` : ''
|
|
421
|
+
} was not handled by any navigator.`;
|
|
422
|
+
|
|
423
|
+
switch (action.type) {
|
|
424
|
+
case 'PRELOAD':
|
|
425
|
+
case 'NAVIGATE':
|
|
426
|
+
case 'PUSH':
|
|
427
|
+
case 'REPLACE':
|
|
428
|
+
case 'POP_TO':
|
|
429
|
+
case 'JUMP_TO':
|
|
430
|
+
if (payload?.name) {
|
|
431
|
+
message += `\n\nDo you have a screen named '${payload.name}'?\n\nIf you're trying to navigate to a screen in a nested navigator, see https://reactnavigation.org/docs/nesting-navigators#navigating-to-a-screen-in-a-nested-navigator.\n\nIf you're using conditional rendering, navigation will happen automatically and you shouldn't navigate manually, see.`;
|
|
432
|
+
} else {
|
|
433
|
+
message += `\n\nYou need to pass the name of the screen to navigate to.\n\nSee https://reactnavigation.org/docs/navigation-actions for usage.`;
|
|
434
|
+
}
|
|
438
435
|
|
|
439
|
-
|
|
436
|
+
break;
|
|
437
|
+
case 'GO_BACK':
|
|
438
|
+
case 'POP':
|
|
439
|
+
case 'POP_TO_TOP':
|
|
440
|
+
message += `\n\nIs there any screen to go back to?`;
|
|
441
|
+
break;
|
|
442
|
+
case 'OPEN_DRAWER':
|
|
443
|
+
case 'CLOSE_DRAWER':
|
|
444
|
+
case 'TOGGLE_DRAWER':
|
|
445
|
+
message += `\n\nIs your screen inside a Drawer navigator?`;
|
|
446
|
+
break;
|
|
440
447
|
}
|
|
441
|
-
);
|
|
442
448
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
449
|
+
message += `\n\nThis is a development-only warning and won't be shown in production.`;
|
|
450
|
+
|
|
451
|
+
console.error(message);
|
|
452
|
+
}
|
|
453
|
+
);
|
|
454
|
+
|
|
455
|
+
return (
|
|
456
|
+
<NavigationIndependentTreeContext.Provider value={false}>
|
|
457
|
+
<NavigationContainerRefContext.Provider value={navigation}>
|
|
458
|
+
<NavigationBuilderContext.Provider value={builderContext}>
|
|
459
|
+
<NavigationStateContext.Provider value={context}>
|
|
460
|
+
<UnhandledActionContext.Provider
|
|
461
|
+
value={onUnhandledAction ?? defaultOnUnhandledAction}
|
|
462
|
+
>
|
|
463
|
+
<EnsureSingleNavigator>
|
|
464
|
+
<ThemeProvider value={theme}>{children}</ThemeProvider>
|
|
465
|
+
</EnsureSingleNavigator>
|
|
466
|
+
</UnhandledActionContext.Provider>
|
|
467
|
+
</NavigationStateContext.Provider>
|
|
468
|
+
</NavigationBuilderContext.Provider>
|
|
469
|
+
</NavigationContainerRefContext.Provider>
|
|
470
|
+
</NavigationIndependentTreeContext.Provider>
|
|
471
|
+
);
|
|
472
|
+
}
|