@react-navigation/core 7.0.0-alpha.5 → 7.0.0-alpha.7
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/commonjs/BaseNavigationContainer.js +6 -1
- package/lib/commonjs/BaseNavigationContainer.js.map +1 -1
- package/lib/commonjs/index.js +27 -3
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/theming/ThemeContext.js +12 -0
- package/lib/commonjs/theming/ThemeContext.js.map +1 -0
- package/lib/commonjs/theming/ThemeProvider.js +20 -0
- package/lib/commonjs/theming/ThemeProvider.js.map +1 -0
- package/lib/commonjs/theming/useTheme.js +18 -0
- package/lib/commonjs/theming/useTheme.js.map +1 -0
- package/lib/commonjs/types.js.map +1 -1
- package/lib/commonjs/useDescriptors.js +79 -16
- package/lib/commonjs/useDescriptors.js.map +1 -1
- package/lib/commonjs/useNavigationBuilder.js +10 -3
- package/lib/commonjs/useNavigationBuilder.js.map +1 -1
- package/lib/commonjs/useNavigationCache.js +55 -14
- package/lib/commonjs/useNavigationCache.js.map +1 -1
- package/lib/commonjs/useOnAction.js +3 -1
- package/lib/commonjs/useOnAction.js.map +1 -1
- package/lib/commonjs/usePreventRemove.js +2 -2
- package/lib/commonjs/usePreventRemove.js.map +1 -1
- package/lib/module/BaseNavigationContainer.js +6 -1
- package/lib/module/BaseNavigationContainer.js.map +1 -1
- package/lib/module/index.js +4 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/theming/ThemeContext.js +4 -0
- package/lib/module/theming/ThemeContext.js.map +1 -0
- package/lib/module/theming/ThemeProvider.js +12 -0
- package/lib/module/theming/ThemeProvider.js.map +1 -0
- package/lib/module/theming/useTheme.js +10 -0
- package/lib/module/theming/useTheme.js.map +1 -0
- package/lib/module/types.js.map +1 -1
- package/lib/module/useDescriptors.js +79 -16
- package/lib/module/useDescriptors.js.map +1 -1
- package/lib/module/useNavigationBuilder.js +10 -3
- package/lib/module/useNavigationBuilder.js.map +1 -1
- package/lib/module/useNavigationCache.js +55 -14
- package/lib/module/useNavigationCache.js.map +1 -1
- package/lib/module/useOnAction.js +3 -1
- package/lib/module/useOnAction.js.map +1 -1
- package/lib/module/usePreventRemove.js +1 -1
- package/lib/module/usePreventRemove.js.map +1 -1
- package/lib/typescript/src/BaseNavigationContainer.d.ts +1 -0
- package/lib/typescript/src/BaseNavigationContainer.d.ts.map +1 -1
- package/lib/typescript/src/NavigationStateContext.d.ts +2 -18
- package/lib/typescript/src/NavigationStateContext.d.ts.map +1 -1
- package/lib/typescript/src/findFocusedRoute.d.ts +1 -9
- package/lib/typescript/src/findFocusedRoute.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +4 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/theming/ThemeContext.d.ts +3 -0
- package/lib/typescript/src/theming/ThemeContext.d.ts.map +1 -0
- package/lib/typescript/src/theming/ThemeProvider.d.ts +8 -0
- package/lib/typescript/src/theming/ThemeProvider.d.ts.map +1 -0
- package/lib/typescript/src/theming/useTheme.d.ts +2 -0
- package/lib/typescript/src/theming/useTheme.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +47 -1
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/useDescriptors.d.ts +106 -54
- package/lib/typescript/src/useDescriptors.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationBuilder.d.ts +57 -64
- package/lib/typescript/src/useNavigationBuilder.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationCache.d.ts +52 -2
- package/lib/typescript/src/useNavigationCache.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationHelpers.d.ts +8 -55
- package/lib/typescript/src/useNavigationHelpers.d.ts.map +1 -1
- package/lib/typescript/src/useOnAction.d.ts.map +1 -1
- package/lib/typescript/src/usePreventRemove.d.ts +1 -1
- package/lib/typescript/src/usePreventRemove.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/BaseNavigationContainer.tsx +6 -1
- package/src/index.tsx +4 -1
- package/src/theming/ThemeContext.tsx +7 -0
- package/src/theming/ThemeProvider.tsx +14 -0
- package/src/theming/useTheme.tsx +15 -0
- package/src/types.tsx +66 -1
- package/src/useDescriptors.tsx +148 -34
- package/src/useNavigationBuilder.tsx +18 -4
- package/src/useNavigationCache.tsx +84 -23
- package/src/useOnAction.tsx +6 -1
- package/src/usePreventRemove.tsx +1 -1
package/src/useDescriptors.tsx
CHANGED
|
@@ -2,6 +2,7 @@ import type {
|
|
|
2
2
|
NavigationAction,
|
|
3
3
|
NavigationState,
|
|
4
4
|
ParamListBase,
|
|
5
|
+
PartialState,
|
|
5
6
|
Router,
|
|
6
7
|
} from '@react-navigation/routers';
|
|
7
8
|
import * as React from 'react';
|
|
@@ -14,6 +15,7 @@ import {
|
|
|
14
15
|
import { NavigationContext } from './NavigationContext';
|
|
15
16
|
import { NavigationRouteContext } from './NavigationRouteContext';
|
|
16
17
|
import { SceneView } from './SceneView';
|
|
18
|
+
import { ThemeContext } from './theming/ThemeContext';
|
|
17
19
|
import type {
|
|
18
20
|
Descriptor,
|
|
19
21
|
EventMapBase,
|
|
@@ -33,14 +35,23 @@ export type ScreenConfigWithParent<
|
|
|
33
35
|
> = {
|
|
34
36
|
keys: (string | undefined)[];
|
|
35
37
|
options: (ScreenOptionsOrCallback<ScreenOptions> | undefined)[] | undefined;
|
|
38
|
+
layout: ScreenLayout | undefined;
|
|
36
39
|
props: RouteConfig<ParamListBase, string, State, ScreenOptions, EventMap>;
|
|
37
40
|
};
|
|
38
41
|
|
|
42
|
+
type ScreenLayout = (props: {
|
|
43
|
+
route: RouteProp<ParamListBase, string>;
|
|
44
|
+
navigation: any;
|
|
45
|
+
theme: ReactNavigation.Theme;
|
|
46
|
+
children: React.ReactElement;
|
|
47
|
+
}) => React.ReactElement;
|
|
48
|
+
|
|
39
49
|
type ScreenOptionsOrCallback<ScreenOptions extends {}> =
|
|
40
50
|
| ScreenOptions
|
|
41
51
|
| ((props: {
|
|
42
52
|
route: RouteProp<ParamListBase, string>;
|
|
43
53
|
navigation: any;
|
|
54
|
+
theme: ReactNavigation.Theme;
|
|
44
55
|
}) => ScreenOptions);
|
|
45
56
|
|
|
46
57
|
type Options<
|
|
@@ -54,7 +65,8 @@ type Options<
|
|
|
54
65
|
ScreenConfigWithParent<State, ScreenOptions, EventMap>
|
|
55
66
|
>;
|
|
56
67
|
navigation: NavigationHelpers<ParamListBase>;
|
|
57
|
-
screenOptions
|
|
68
|
+
screenOptions: ScreenOptionsOrCallback<ScreenOptions> | undefined;
|
|
69
|
+
screenLayout: ScreenLayout | undefined;
|
|
58
70
|
onAction: (action: NavigationAction) => boolean;
|
|
59
71
|
getState: () => State;
|
|
60
72
|
setState: (state: State) => void;
|
|
@@ -83,6 +95,7 @@ export function useDescriptors<
|
|
|
83
95
|
screens,
|
|
84
96
|
navigation,
|
|
85
97
|
screenOptions,
|
|
98
|
+
screenLayout,
|
|
86
99
|
onAction,
|
|
87
100
|
getState,
|
|
88
101
|
setState,
|
|
@@ -92,6 +105,7 @@ export function useDescriptors<
|
|
|
92
105
|
router,
|
|
93
106
|
emitter,
|
|
94
107
|
}: Options<State, ScreenOptions, EventMap>) {
|
|
108
|
+
const theme = React.useContext(ThemeContext);
|
|
95
109
|
const [options, setOptions] = React.useState<Record<string, ScreenOptions>>(
|
|
96
110
|
{}
|
|
97
111
|
);
|
|
@@ -122,7 +136,12 @@ export function useDescriptors<
|
|
|
122
136
|
]
|
|
123
137
|
);
|
|
124
138
|
|
|
125
|
-
const navigations = useNavigationCache<
|
|
139
|
+
const { base, navigations } = useNavigationCache<
|
|
140
|
+
State,
|
|
141
|
+
ScreenOptions,
|
|
142
|
+
EventMap,
|
|
143
|
+
ActionHelpers
|
|
144
|
+
>({
|
|
126
145
|
state,
|
|
127
146
|
getState,
|
|
128
147
|
navigation,
|
|
@@ -133,27 +152,20 @@ export function useDescriptors<
|
|
|
133
152
|
|
|
134
153
|
const routes = useRouteCache(state.routes);
|
|
135
154
|
|
|
136
|
-
|
|
137
|
-
|
|
155
|
+
const getOptions = (
|
|
156
|
+
route: RouteProp<ParamListBase, string>,
|
|
157
|
+
navigation: NavigationProp<
|
|
158
|
+
ParamListBase,
|
|
138
159
|
string,
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
ScreenOptions,
|
|
147
|
-
EventMap
|
|
148
|
-
> &
|
|
149
|
-
ActionHelpers,
|
|
150
|
-
RouteProp<ParamListBase>
|
|
151
|
-
>
|
|
152
|
-
>
|
|
153
|
-
>((acc, route, i) => {
|
|
160
|
+
string | undefined,
|
|
161
|
+
State,
|
|
162
|
+
ScreenOptions,
|
|
163
|
+
EventMap
|
|
164
|
+
>,
|
|
165
|
+
overrides: Record<string, ScreenOptions>
|
|
166
|
+
) => {
|
|
154
167
|
const config = screens[route.name];
|
|
155
168
|
const screen = config.props;
|
|
156
|
-
const navigation = navigations[route.key];
|
|
157
169
|
|
|
158
170
|
const optionsList = [
|
|
159
171
|
// The default `screenOptions` passed to the navigator
|
|
@@ -165,18 +177,35 @@ export function useDescriptors<
|
|
|
165
177
|
// The `options` prop passed to `Screen` elements,
|
|
166
178
|
screen.options,
|
|
167
179
|
// The options set via `navigation.setOptions`
|
|
168
|
-
|
|
180
|
+
overrides,
|
|
169
181
|
];
|
|
170
182
|
|
|
171
|
-
|
|
183
|
+
return optionsList.reduce<ScreenOptions>(
|
|
172
184
|
(acc, curr) =>
|
|
173
185
|
Object.assign(
|
|
174
186
|
acc,
|
|
175
187
|
// @ts-expect-error: we check for function but TS still complains
|
|
176
|
-
typeof curr !== 'function' ? curr : curr({ route, navigation })
|
|
188
|
+
typeof curr !== 'function' ? curr : curr({ route, navigation, theme })
|
|
177
189
|
),
|
|
178
190
|
{} as ScreenOptions
|
|
179
191
|
);
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
const render = (
|
|
195
|
+
route: RouteProp<ParamListBase, string>,
|
|
196
|
+
navigation: NavigationProp<
|
|
197
|
+
ParamListBase,
|
|
198
|
+
string,
|
|
199
|
+
string | undefined,
|
|
200
|
+
State,
|
|
201
|
+
ScreenOptions,
|
|
202
|
+
EventMap
|
|
203
|
+
>,
|
|
204
|
+
customOptions: ScreenOptions,
|
|
205
|
+
routeState: NavigationState | PartialState<NavigationState> | undefined
|
|
206
|
+
) => {
|
|
207
|
+
const config = screens[route.name];
|
|
208
|
+
const screen = config.props;
|
|
180
209
|
|
|
181
210
|
const clearOptions = () =>
|
|
182
211
|
setOptions((o) => {
|
|
@@ -189,24 +218,74 @@ export function useDescriptors<
|
|
|
189
218
|
return o;
|
|
190
219
|
});
|
|
191
220
|
|
|
192
|
-
const
|
|
221
|
+
const layout =
|
|
222
|
+
// The `layout` prop passed to `Screen` elements,
|
|
223
|
+
screen.layout ??
|
|
224
|
+
// The `screenLayout` props passed to `Group` elements
|
|
225
|
+
config.layout ??
|
|
226
|
+
// The default `screenLayout` passed to the navigator
|
|
227
|
+
screenLayout;
|
|
228
|
+
|
|
229
|
+
let element = (
|
|
230
|
+
<SceneView
|
|
231
|
+
navigation={navigation}
|
|
232
|
+
route={route}
|
|
233
|
+
screen={screen}
|
|
234
|
+
routeState={routeState}
|
|
235
|
+
getState={getState}
|
|
236
|
+
setState={setState}
|
|
237
|
+
options={customOptions}
|
|
238
|
+
clearOptions={clearOptions}
|
|
239
|
+
/>
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
if (layout != null) {
|
|
243
|
+
element = layout({
|
|
244
|
+
route,
|
|
245
|
+
navigation,
|
|
246
|
+
// @ts-expect-error: in practice `theme` will be defined
|
|
247
|
+
theme,
|
|
248
|
+
children: element,
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return (
|
|
193
253
|
<NavigationBuilderContext.Provider key={route.key} value={context}>
|
|
194
254
|
<NavigationContext.Provider value={navigation}>
|
|
195
255
|
<NavigationRouteContext.Provider value={route}>
|
|
196
|
-
|
|
197
|
-
navigation={navigation}
|
|
198
|
-
route={route}
|
|
199
|
-
screen={screen}
|
|
200
|
-
routeState={state.routes[i].state}
|
|
201
|
-
getState={getState}
|
|
202
|
-
setState={setState}
|
|
203
|
-
options={customOptions}
|
|
204
|
-
clearOptions={clearOptions}
|
|
205
|
-
/>
|
|
256
|
+
{element}
|
|
206
257
|
</NavigationRouteContext.Provider>
|
|
207
258
|
</NavigationContext.Provider>
|
|
208
259
|
</NavigationBuilderContext.Provider>
|
|
209
260
|
);
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
const descriptors = routes.reduce<
|
|
264
|
+
Record<
|
|
265
|
+
string,
|
|
266
|
+
Descriptor<
|
|
267
|
+
ScreenOptions,
|
|
268
|
+
NavigationProp<
|
|
269
|
+
ParamListBase,
|
|
270
|
+
string,
|
|
271
|
+
string | undefined,
|
|
272
|
+
State,
|
|
273
|
+
ScreenOptions,
|
|
274
|
+
EventMap
|
|
275
|
+
> &
|
|
276
|
+
ActionHelpers,
|
|
277
|
+
RouteProp<ParamListBase>
|
|
278
|
+
>
|
|
279
|
+
>
|
|
280
|
+
>((acc, route, i) => {
|
|
281
|
+
const navigation = navigations[route.key];
|
|
282
|
+
const customOptions = getOptions(route, navigation, options[route.key]);
|
|
283
|
+
const element = render(
|
|
284
|
+
route,
|
|
285
|
+
navigation,
|
|
286
|
+
customOptions,
|
|
287
|
+
state.routes[i].state
|
|
288
|
+
);
|
|
210
289
|
|
|
211
290
|
acc[route.key] = {
|
|
212
291
|
route,
|
|
@@ -220,4 +299,39 @@ export function useDescriptors<
|
|
|
220
299
|
|
|
221
300
|
return acc;
|
|
222
301
|
}, {});
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Create a descriptor object for a route.
|
|
305
|
+
*
|
|
306
|
+
* @param route Route object for which the descriptor should be created
|
|
307
|
+
* @param placeholder Whether the descriptor should be a placeholder, e.g. for a route not yet in the state
|
|
308
|
+
* @returns Descriptor object
|
|
309
|
+
*/
|
|
310
|
+
const describe = (route: RouteProp<ParamListBase>, placeholder: boolean) => {
|
|
311
|
+
if (!placeholder) {
|
|
312
|
+
if (!(route.key in descriptors)) {
|
|
313
|
+
throw new Error(`Couldn't find a route with the key ${route.key}.`);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return descriptors[route.key];
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
const navigation = base;
|
|
320
|
+
const customOptions = getOptions(route, navigation, {});
|
|
321
|
+
const element = render(route, navigation, customOptions, undefined);
|
|
322
|
+
|
|
323
|
+
return {
|
|
324
|
+
route,
|
|
325
|
+
navigation,
|
|
326
|
+
render() {
|
|
327
|
+
return element;
|
|
328
|
+
},
|
|
329
|
+
options: customOptions as ScreenOptions,
|
|
330
|
+
};
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
return {
|
|
334
|
+
describe,
|
|
335
|
+
descriptors,
|
|
336
|
+
};
|
|
223
337
|
}
|
|
@@ -72,7 +72,8 @@ const getRouteConfigsFromChildren = <
|
|
|
72
72
|
State,
|
|
73
73
|
ScreenOptions,
|
|
74
74
|
EventMap
|
|
75
|
-
>['options']
|
|
75
|
+
>['options'],
|
|
76
|
+
groupLayout?: ScreenConfigWithParent<State, ScreenOptions, EventMap>['layout']
|
|
76
77
|
) => {
|
|
77
78
|
const configs = React.Children.toArray(children).reduce<
|
|
78
79
|
ScreenConfigWithParent<State, ScreenOptions, EventMap>[]
|
|
@@ -95,6 +96,7 @@ const getRouteConfigsFromChildren = <
|
|
|
95
96
|
acc.push({
|
|
96
97
|
keys: [groupKey, child.props.navigationKey],
|
|
97
98
|
options: groupOptions,
|
|
99
|
+
layout: groupLayout,
|
|
98
100
|
props: child.props as RouteConfig<
|
|
99
101
|
ParamListBase,
|
|
100
102
|
string,
|
|
@@ -103,6 +105,7 @@ const getRouteConfigsFromChildren = <
|
|
|
103
105
|
EventMap
|
|
104
106
|
>,
|
|
105
107
|
});
|
|
108
|
+
|
|
106
109
|
return acc;
|
|
107
110
|
}
|
|
108
111
|
|
|
@@ -125,7 +128,8 @@ const getRouteConfigsFromChildren = <
|
|
|
125
128
|
? groupOptions
|
|
126
129
|
: groupOptions != null
|
|
127
130
|
? [...groupOptions, child.props.screenOptions]
|
|
128
|
-
: [child.props.screenOptions]
|
|
131
|
+
: [child.props.screenOptions],
|
|
132
|
+
child.props.screenLayout ?? groupLayout
|
|
129
133
|
)
|
|
130
134
|
);
|
|
131
135
|
return acc;
|
|
@@ -259,7 +263,15 @@ export function useNavigationBuilder<
|
|
|
259
263
|
| NavigatorRoute
|
|
260
264
|
| undefined;
|
|
261
265
|
|
|
262
|
-
const {
|
|
266
|
+
const {
|
|
267
|
+
children,
|
|
268
|
+
layout,
|
|
269
|
+
screenOptions,
|
|
270
|
+
screenLayout,
|
|
271
|
+
screenListeners,
|
|
272
|
+
...rest
|
|
273
|
+
} = options;
|
|
274
|
+
|
|
263
275
|
const { current: router } = React.useRef<Router<State, any>>(
|
|
264
276
|
createRouter(rest as unknown as RouterOptions)
|
|
265
277
|
);
|
|
@@ -679,7 +691,7 @@ export function useNavigationBuilder<
|
|
|
679
691
|
getStateListeners: keyedListeners.getState,
|
|
680
692
|
});
|
|
681
693
|
|
|
682
|
-
const descriptors = useDescriptors<
|
|
694
|
+
const { describe, descriptors } = useDescriptors<
|
|
683
695
|
State,
|
|
684
696
|
ActionHelpers,
|
|
685
697
|
ScreenOptions,
|
|
@@ -689,6 +701,7 @@ export function useNavigationBuilder<
|
|
|
689
701
|
screens,
|
|
690
702
|
navigation,
|
|
691
703
|
screenOptions,
|
|
704
|
+
screenLayout,
|
|
692
705
|
onAction,
|
|
693
706
|
getState,
|
|
694
707
|
setState,
|
|
@@ -727,6 +740,7 @@ export function useNavigationBuilder<
|
|
|
727
740
|
return {
|
|
728
741
|
state,
|
|
729
742
|
navigation,
|
|
743
|
+
describe,
|
|
730
744
|
descriptors,
|
|
731
745
|
NavigationContent,
|
|
732
746
|
};
|
|
@@ -29,22 +29,25 @@ type Options<
|
|
|
29
29
|
emitter: NavigationEventEmitter<EventMap>;
|
|
30
30
|
};
|
|
31
31
|
|
|
32
|
-
type
|
|
32
|
+
type NavigationItem<
|
|
33
33
|
State extends NavigationState,
|
|
34
34
|
ScreenOptions extends {},
|
|
35
35
|
EventMap extends Record<string, any>,
|
|
36
|
-
> =
|
|
36
|
+
> = NavigationProp<
|
|
37
|
+
ParamListBase,
|
|
37
38
|
string,
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
State,
|
|
43
|
-
ScreenOptions,
|
|
44
|
-
EventMap
|
|
45
|
-
>
|
|
39
|
+
string | undefined,
|
|
40
|
+
State,
|
|
41
|
+
ScreenOptions,
|
|
42
|
+
EventMap
|
|
46
43
|
>;
|
|
47
44
|
|
|
45
|
+
type NavigationCache<
|
|
46
|
+
State extends NavigationState,
|
|
47
|
+
ScreenOptions extends {},
|
|
48
|
+
EventMap extends Record<string, any>,
|
|
49
|
+
> = Record<string, NavigationItem<State, ScreenOptions, EventMap>>;
|
|
50
|
+
|
|
48
51
|
/**
|
|
49
52
|
* Hook to cache navigation objects for each screen in the navigator.
|
|
50
53
|
* It's important to cache them to make sure navigation objects don't change between renders.
|
|
@@ -54,6 +57,7 @@ export function useNavigationCache<
|
|
|
54
57
|
State extends NavigationState,
|
|
55
58
|
ScreenOptions extends {},
|
|
56
59
|
EventMap extends Record<string, any>,
|
|
60
|
+
ActionHelpers extends Record<string, () => void>,
|
|
57
61
|
>({
|
|
58
62
|
state,
|
|
59
63
|
getState,
|
|
@@ -64,20 +68,72 @@ export function useNavigationCache<
|
|
|
64
68
|
}: Options<State, ScreenOptions, EventMap>) {
|
|
65
69
|
const { stackRef } = React.useContext(NavigationBuilderContext);
|
|
66
70
|
|
|
71
|
+
const base = React.useMemo((): NavigationItem<
|
|
72
|
+
State,
|
|
73
|
+
ScreenOptions,
|
|
74
|
+
EventMap
|
|
75
|
+
> &
|
|
76
|
+
ActionHelpers => {
|
|
77
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
78
|
+
const { emit, ...rest } = navigation;
|
|
79
|
+
|
|
80
|
+
const actions = {
|
|
81
|
+
...router.actionCreators,
|
|
82
|
+
...CommonActions,
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const dispatch = () => {
|
|
86
|
+
throw new Error(
|
|
87
|
+
'Actions cannot be dispatched from a placeholder screen.'
|
|
88
|
+
);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const helpers = Object.keys(actions).reduce<Record<string, () => void>>(
|
|
92
|
+
(acc, name) => {
|
|
93
|
+
acc[name] = dispatch;
|
|
94
|
+
|
|
95
|
+
return acc;
|
|
96
|
+
},
|
|
97
|
+
{}
|
|
98
|
+
) as ActionHelpers;
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
...rest,
|
|
102
|
+
...helpers,
|
|
103
|
+
addListener: () => {
|
|
104
|
+
// Event listeners are not supported for placeholder screens
|
|
105
|
+
|
|
106
|
+
return () => {
|
|
107
|
+
// Empty function
|
|
108
|
+
};
|
|
109
|
+
},
|
|
110
|
+
removeListener: () => {
|
|
111
|
+
// Event listeners are not supported for placeholder screens
|
|
112
|
+
},
|
|
113
|
+
dispatch,
|
|
114
|
+
getParent: (id?: string) => {
|
|
115
|
+
if (id !== undefined && id === rest.getId()) {
|
|
116
|
+
return base;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return rest.getParent(id);
|
|
120
|
+
},
|
|
121
|
+
setOptions: () => {
|
|
122
|
+
throw new Error('Options cannot be set from a placeholder screen.');
|
|
123
|
+
},
|
|
124
|
+
isFocused: () => false,
|
|
125
|
+
};
|
|
126
|
+
}, [navigation, router.actionCreators]);
|
|
127
|
+
|
|
67
128
|
// Cache object which holds navigation objects for each screen
|
|
68
129
|
// We use `React.useMemo` instead of `React.useRef` coz we want to invalidate it when deps change
|
|
69
130
|
// In reality, these deps will rarely change, if ever
|
|
70
131
|
const cache = React.useMemo(
|
|
71
132
|
() => ({ current: {} as NavigationCache<State, ScreenOptions, EventMap> }),
|
|
72
133
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
73
|
-
[getState, navigation, setOptions,
|
|
134
|
+
[base, getState, navigation, setOptions, emitter]
|
|
74
135
|
);
|
|
75
136
|
|
|
76
|
-
const actions = {
|
|
77
|
-
...router.actionCreators,
|
|
78
|
-
...CommonActions,
|
|
79
|
-
};
|
|
80
|
-
|
|
81
137
|
cache.current = state.routes.reduce<
|
|
82
138
|
NavigationCache<State, ScreenOptions, EventMap>
|
|
83
139
|
>((acc, route) => {
|
|
@@ -91,9 +147,6 @@ export function useNavigationCache<
|
|
|
91
147
|
// If a cached navigation object already exists, reuse it
|
|
92
148
|
acc[route.key] = previous;
|
|
93
149
|
} else {
|
|
94
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
95
|
-
const { emit, ...rest } = navigation;
|
|
96
|
-
|
|
97
150
|
const dispatch = (thunk: Thunk) => {
|
|
98
151
|
const action = typeof thunk === 'function' ? thunk(getState()) : thunk;
|
|
99
152
|
|
|
@@ -124,6 +177,11 @@ export function useNavigationCache<
|
|
|
124
177
|
}
|
|
125
178
|
};
|
|
126
179
|
|
|
180
|
+
const actions = {
|
|
181
|
+
...router.actionCreators,
|
|
182
|
+
...CommonActions,
|
|
183
|
+
};
|
|
184
|
+
|
|
127
185
|
const helpers = Object.keys(actions).reduce<Record<string, () => void>>(
|
|
128
186
|
(acc, name) => {
|
|
129
187
|
acc[name] = (...args: any) =>
|
|
@@ -138,19 +196,19 @@ export function useNavigationCache<
|
|
|
138
196
|
);
|
|
139
197
|
|
|
140
198
|
acc[route.key] = {
|
|
141
|
-
...
|
|
199
|
+
...base,
|
|
142
200
|
...helpers,
|
|
143
201
|
// FIXME: too much work to fix the types for now
|
|
144
202
|
...(emitter.create(route.key) as any),
|
|
145
203
|
dispatch: (thunk: Thunk) => withStack(() => dispatch(thunk)),
|
|
146
204
|
getParent: (id?: string) => {
|
|
147
|
-
if (id !== undefined && id ===
|
|
205
|
+
if (id !== undefined && id === base.getId()) {
|
|
148
206
|
// If the passed id is the same as the current navigation id,
|
|
149
207
|
// we return the cached navigation object for the relevant route
|
|
150
208
|
return acc[route.key];
|
|
151
209
|
}
|
|
152
210
|
|
|
153
|
-
return
|
|
211
|
+
return base.getParent(id);
|
|
154
212
|
},
|
|
155
213
|
setOptions: (options: object) => {
|
|
156
214
|
setOptions((o) => ({
|
|
@@ -175,5 +233,8 @@ export function useNavigationCache<
|
|
|
175
233
|
return acc;
|
|
176
234
|
}, {});
|
|
177
235
|
|
|
178
|
-
return
|
|
236
|
+
return {
|
|
237
|
+
base,
|
|
238
|
+
navigations: cache.current,
|
|
239
|
+
};
|
|
179
240
|
}
|
package/src/useOnAction.tsx
CHANGED
|
@@ -131,7 +131,12 @@ export function useOnAction({
|
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
if (
|
|
134
|
+
if (
|
|
135
|
+
typeof action.target === 'string' ||
|
|
136
|
+
// For backward compatibility
|
|
137
|
+
action.type === 'NAVIGATE_DEPRECATED' ||
|
|
138
|
+
navigationInChildEnabled
|
|
139
|
+
) {
|
|
135
140
|
// If the action wasn't handled by current navigator or a parent navigator, let children handle it
|
|
136
141
|
// Handling this when target isn't specified is deprecated and will be removed in the future
|
|
137
142
|
for (let i = actionListeners.length - 1; i >= 0; i--) {
|
package/src/usePreventRemove.tsx
CHANGED
|
@@ -14,7 +14,7 @@ import { useRoute } from './useRoute';
|
|
|
14
14
|
* @param preventRemove Boolean indicating whether to prevent screen from being removed.
|
|
15
15
|
* @param callback Function which is executed when screen was prevented from being removed.
|
|
16
16
|
*/
|
|
17
|
-
export function
|
|
17
|
+
export function usePreventRemove(
|
|
18
18
|
preventRemove: boolean,
|
|
19
19
|
callback: (options: { data: { action: NavigationAction } }) => void
|
|
20
20
|
) {
|