UNPKG

3.71 kBJavaScriptView Raw
1import * as React from 'react';
2import NavigationBuilderContext from './NavigationBuilderContext';
3import NavigationContext from './NavigationContext';
4import NavigationRouteContext from './NavigationRouteContext';
5import SceneView from './SceneView';
6import useNavigationCache from './useNavigationCache';
7import useRouteCache from './useRouteCache';
8
9/**
10 * Hook to create descriptor objects for the child routes.
11 *
12 * A descriptor object provides 3 things:
13 * - Helper method to render a screen
14 * - Options specified by the screen for the navigator
15 * - Navigation object intended for the route
16 */
17export default function useDescriptors(_ref) {
18 let {
19 state,
20 screens,
21 navigation,
22 screenOptions,
23 defaultScreenOptions,
24 onAction,
25 getState,
26 setState,
27 addListener,
28 addKeyedListener,
29 onRouteFocus,
30 router,
31 emitter
32 } = _ref;
33 const [options, setOptions] = React.useState({});
34 const {
35 onDispatchAction,
36 onOptionsChange,
37 stackRef
38 } = React.useContext(NavigationBuilderContext);
39 const context = React.useMemo(() => ({
40 navigation,
41 onAction,
42 addListener,
43 addKeyedListener,
44 onRouteFocus,
45 onDispatchAction,
46 onOptionsChange,
47 stackRef
48 }), [navigation, onAction, addListener, addKeyedListener, onRouteFocus, onDispatchAction, onOptionsChange, stackRef]);
49 const navigations = useNavigationCache({
50 state,
51 getState,
52 navigation,
53 setOptions,
54 router,
55 emitter
56 });
57 const routes = useRouteCache(state.routes);
58 return routes.reduce((acc, route, i) => {
59 const config = screens[route.name];
60 const screen = config.props;
61 const navigation = navigations[route.key];
62 const optionsList = [// The default `screenOptions` passed to the navigator
63 screenOptions, // The `screenOptions` props passed to `Group` elements
64 ...(config.options ? config.options.filter(Boolean) : []), // The `options` prop passed to `Screen` elements,
65 screen.options, // The options set via `navigation.setOptions`
66 options[route.key]];
67 const customOptions = optionsList.reduce((acc, curr) => Object.assign(acc, typeof curr !== 'function' ? curr : curr({
68 route,
69 navigation
70 })), {});
71 const mergedOptions = { ...(typeof defaultScreenOptions === 'function' ? // @ts-expect-error: ts gives incorrect error here
72 defaultScreenOptions({
73 route,
74 navigation,
75 options: customOptions
76 }) : defaultScreenOptions),
77 ...customOptions
78 };
79
80 const clearOptions = () => setOptions(o => {
81 if (route.key in o) {
82 // eslint-disable-next-line @typescript-eslint/no-unused-vars
83 const {
84 [route.key]: _,
85 ...rest
86 } = o;
87 return rest;
88 }
89
90 return o;
91 });
92
93 acc[route.key] = {
94 route,
95 // @ts-expect-error: it's missing action helpers, fix later
96 navigation,
97
98 render() {
99 return /*#__PURE__*/React.createElement(NavigationBuilderContext.Provider, {
100 key: route.key,
101 value: context
102 }, /*#__PURE__*/React.createElement(NavigationContext.Provider, {
103 value: navigation
104 }, /*#__PURE__*/React.createElement(NavigationRouteContext.Provider, {
105 value: route
106 }, /*#__PURE__*/React.createElement(SceneView, {
107 navigation: navigation,
108 route: route,
109 screen: screen,
110 routeState: state.routes[i].state,
111 getState: getState,
112 setState: setState,
113 options: mergedOptions,
114 clearOptions: clearOptions
115 }))));
116 },
117
118 options: mergedOptions
119 };
120 return acc;
121 }, {});
122}
123//# sourceMappingURL=useDescriptors.js.map
\No newline at end of file