UNPKG

3.88 kBJavaScriptView Raw
1import { nanoid } from 'nanoid/non-secure';
2import * as React from 'react';
3import useLatestCallback from 'use-latest-callback';
4import NavigationHelpersContext from './NavigationHelpersContext';
5import NavigationRouteContext from './NavigationRouteContext';
6import PreventRemoveContext from './PreventRemoveContext';
7
8/**
9 * Util function to transform map of prevented routes to a simpler object.
10 */
11const transformPreventedRoutes = preventedRoutesMap => {
12 const preventedRoutesToTransform = [...preventedRoutesMap.values()];
13 const preventedRoutes = preventedRoutesToTransform.reduce((acc, _ref) => {
14 var _acc$routeKey;
15
16 let {
17 routeKey,
18 preventRemove
19 } = _ref;
20 acc[routeKey] = {
21 preventRemove: ((_acc$routeKey = acc[routeKey]) === null || _acc$routeKey === void 0 ? void 0 : _acc$routeKey.preventRemove) || preventRemove
22 };
23 return acc;
24 }, {});
25 return preventedRoutes;
26};
27/**
28 * Component used for managing which routes have to be prevented from removal in native-stack.
29 */
30
31
32export default function PreventRemoveProvider(_ref2) {
33 let {
34 children
35 } = _ref2;
36 const [parentId] = React.useState(() => nanoid());
37 const [preventedRoutesMap, setPreventedRoutesMap] = React.useState(new Map());
38 const navigation = React.useContext(NavigationHelpersContext);
39 const route = React.useContext(NavigationRouteContext);
40 const preventRemoveContextValue = React.useContext(PreventRemoveContext); // take `setPreventRemove` from parent context - if exist it means we're in a nested context
41
42 const setParentPrevented = preventRemoveContextValue === null || preventRemoveContextValue === void 0 ? void 0 : preventRemoveContextValue.setPreventRemove;
43 const setPreventRemove = useLatestCallback((id, routeKey, preventRemove) => {
44 if (preventRemove && (navigation == null || navigation !== null && navigation !== void 0 && navigation.getState().routes.every(route => route.key !== routeKey))) {
45 throw new Error(`Couldn't find a route with the key ${routeKey}. Is your component inside NavigationContent?`);
46 }
47
48 setPreventedRoutesMap(prevPrevented => {
49 var _prevPrevented$get, _prevPrevented$get2;
50
51 // values haven't changed - do nothing
52 if (routeKey === ((_prevPrevented$get = prevPrevented.get(id)) === null || _prevPrevented$get === void 0 ? void 0 : _prevPrevented$get.routeKey) && preventRemove === ((_prevPrevented$get2 = prevPrevented.get(id)) === null || _prevPrevented$get2 === void 0 ? void 0 : _prevPrevented$get2.preventRemove)) {
53 return prevPrevented;
54 }
55
56 const nextPrevented = new Map(prevPrevented);
57
58 if (preventRemove) {
59 nextPrevented.set(id, {
60 routeKey,
61 preventRemove
62 });
63 } else {
64 nextPrevented.delete(id);
65 }
66
67 return nextPrevented;
68 });
69 });
70 const isPrevented = [...preventedRoutesMap.values()].some(_ref3 => {
71 let {
72 preventRemove
73 } = _ref3;
74 return preventRemove;
75 });
76 React.useEffect(() => {
77 if ((route === null || route === void 0 ? void 0 : route.key) !== undefined && setParentPrevented !== undefined) {
78 // when route is defined (and setParentPrevented) it means we're in a nested stack
79 // route.key then will be the route key of parent
80 setParentPrevented(parentId, route.key, isPrevented);
81 return () => {
82 setParentPrevented(parentId, route.key, false);
83 };
84 }
85
86 return;
87 }, [parentId, isPrevented, route === null || route === void 0 ? void 0 : route.key, setParentPrevented]);
88 const value = React.useMemo(() => ({
89 setPreventRemove,
90 preventedRoutes: transformPreventedRoutes(preventedRoutesMap)
91 }), [setPreventRemove, preventedRoutesMap]);
92 return /*#__PURE__*/React.createElement(PreventRemoveContext.Provider, {
93 value: value
94 }, children);
95}
96//# sourceMappingURL=PreventRemoveProvider.js.map
\No newline at end of file