@react-navigation/stack 7.0.13 → 7.0.15

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.
@@ -1,18 +1,5 @@
1
1
  "use strict";
2
2
 
3
- function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
4
- function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
5
- function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
6
- function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
7
- function _possibleConstructorReturn(t, e) { if (e && ("object" == typeof e || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); }
8
- function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; }
9
- function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function () { return !!t; })(); }
10
- function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); }
11
- function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); }
12
- function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); }
13
- function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
14
- function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
15
- function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
16
3
  import { HeaderShownContext, SafeAreaProviderCompat } from '@react-navigation/elements';
17
4
  import { CommonActions, StackActions } from '@react-navigation/native';
18
5
  import * as React from 'react';
@@ -30,332 +17,320 @@ const GestureHandlerWrapper = GestureHandlerRootView ?? View;
30
17
  * We need to make sure that both values and order match.
31
18
  */
32
19
  const isArrayEqual = (a, b) => a.length === b.length && a.every((it, index) => it === b[index]);
33
- export let StackView = /*#__PURE__*/function (_React$Component) {
34
- function StackView(...args) {
35
- var _this;
36
- _classCallCheck(this, StackView);
37
- _this = _callSuper(this, StackView, [...args]);
38
- _defineProperty(_this, "state", {
39
- routes: [],
40
- previousRoutes: [],
41
- previousDescriptors: {},
42
- openingRouteKeys: [],
43
- closingRouteKeys: [],
44
- replacingRouteKeys: [],
45
- descriptors: {}
46
- });
47
- _defineProperty(_this, "getPreviousRoute", ({
48
- route
49
- }) => {
50
- const {
51
- closingRouteKeys,
52
- replacingRouteKeys
53
- } = _this.state;
54
- const routes = _this.state.routes.filter(r => r.key === route.key || !closingRouteKeys.includes(r.key) && !replacingRouteKeys.includes(r.key));
55
- const index = routes.findIndex(r => r.key === route.key);
56
- return routes[index - 1];
57
- });
58
- _defineProperty(_this, "renderHeader", props => {
59
- return /*#__PURE__*/_jsx(HeaderContainer, {
60
- ...props
61
- });
62
- });
63
- _defineProperty(_this, "handleOpenRoute", ({
64
- route
65
- }) => {
66
- const {
67
- state,
68
- navigation
69
- } = _this.props;
70
- const {
71
- closingRouteKeys,
72
- replacingRouteKeys
73
- } = _this.state;
74
- if (closingRouteKeys.some(key => key === route.key) && replacingRouteKeys.every(key => key !== route.key) && state.routeNames.includes(route.name) && !state.routes.some(r => r.key === route.key)) {
75
- // If route isn't present in current state, but was closing, assume that a close animation was cancelled
76
- // So we need to add this route back to the state
77
- navigation.dispatch(state => {
78
- const routes = [...state.routes.filter(r => r.key !== route.key), route];
79
- return CommonActions.reset({
80
- ...state,
81
- routes,
82
- index: routes.length - 1
83
- });
84
- });
85
- } else {
86
- _this.setState(state => ({
87
- routes: state.replacingRouteKeys.length ? state.routes.filter(r => !state.replacingRouteKeys.includes(r.key)) : state.routes,
88
- openingRouteKeys: state.openingRouteKeys.filter(key => key !== route.key),
89
- closingRouteKeys: state.closingRouteKeys.filter(key => key !== route.key),
90
- replacingRouteKeys: []
91
- }));
20
+ export class StackView extends React.Component {
21
+ static getDerivedStateFromProps(props, state) {
22
+ // If there was no change in routes, we don't need to compute anything
23
+ if ((props.state.routes === state.previousRoutes || isArrayEqual(props.state.routes.map(r => r.key), state.previousRoutes.map(r => r.key))) && state.routes.length) {
24
+ let routes = state.routes;
25
+ let previousRoutes = state.previousRoutes;
26
+ let descriptors = props.descriptors;
27
+ let previousDescriptors = state.previousDescriptors;
28
+ if (props.descriptors !== state.previousDescriptors) {
29
+ descriptors = state.routes.reduce((acc, route) => {
30
+ acc[route.key] = props.descriptors[route.key] || state.descriptors[route.key];
31
+ return acc;
32
+ }, {});
33
+ previousDescriptors = props.descriptors;
92
34
  }
93
- });
94
- _defineProperty(_this, "handleCloseRoute", ({
95
- route
96
- }) => {
97
- const {
98
- state,
99
- navigation
100
- } = _this.props;
101
- if (state.routes.some(r => r.key === route.key)) {
102
- // If a route exists in state, trigger a pop
103
- // This will happen in when the route was closed from the card component
104
- // e.g. When the close animation triggered from a gesture ends
105
- navigation.dispatch({
106
- ...StackActions.pop(),
107
- source: route.key,
108
- target: state.key
109
- });
110
- } else {
111
- // We need to clean up any state tracking the route and pop it immediately
112
- _this.setState(state => ({
113
- routes: state.routes.filter(r => r.key !== route.key),
114
- openingRouteKeys: state.openingRouteKeys.filter(key => key !== route.key),
115
- closingRouteKeys: state.closingRouteKeys.filter(key => key !== route.key)
116
- }));
35
+ if (props.state.routes !== state.previousRoutes) {
36
+ // if any route objects have changed, we should update them
37
+ const map = props.state.routes.reduce((acc, route) => {
38
+ acc[route.key] = route;
39
+ return acc;
40
+ }, {});
41
+ routes = state.routes.map(route => map[route.key] || route);
42
+ previousRoutes = props.state.routes;
117
43
  }
118
- });
119
- _defineProperty(_this, "handleTransitionStart", ({
120
- route
121
- }, closing) => _this.props.navigation.emit({
122
- type: 'transitionStart',
123
- data: {
124
- closing
125
- },
126
- target: route.key
127
- }));
128
- _defineProperty(_this, "handleTransitionEnd", ({
129
- route
130
- }, closing) => _this.props.navigation.emit({
131
- type: 'transitionEnd',
132
- data: {
133
- closing
134
- },
135
- target: route.key
136
- }));
137
- _defineProperty(_this, "handleGestureStart", ({
138
- route
139
- }) => {
140
- _this.props.navigation.emit({
141
- type: 'gestureStart',
142
- target: route.key
143
- });
144
- });
145
- _defineProperty(_this, "handleGestureEnd", ({
146
- route
147
- }) => {
148
- _this.props.navigation.emit({
149
- type: 'gestureEnd',
150
- target: route.key
151
- });
152
- });
153
- _defineProperty(_this, "handleGestureCancel", ({
154
- route
155
- }) => {
156
- _this.props.navigation.emit({
157
- type: 'gestureCancel',
158
- target: route.key
159
- });
160
- });
161
- return _this;
162
- }
163
- _inherits(StackView, _React$Component);
164
- return _createClass(StackView, [{
165
- key: "render",
166
- value: function render() {
167
- const {
168
- state,
169
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
170
- descriptors: _,
171
- ...rest
172
- } = this.props;
173
- const {
44
+ return {
174
45
  routes,
46
+ previousRoutes,
175
47
  descriptors,
176
- openingRouteKeys,
177
- closingRouteKeys
178
- } = this.state;
179
- const preloadedDescriptors = state.preloadedRoutes.reduce((acc, route) => {
180
- acc[route.key] = acc[route.key] || this.props.describe(route, true);
181
- return acc;
182
- }, {});
183
- return /*#__PURE__*/_jsx(GestureHandlerWrapper, {
184
- style: styles.container,
185
- children: /*#__PURE__*/_jsx(SafeAreaProviderCompat, {
186
- children: /*#__PURE__*/_jsx(SafeAreaInsetsContext.Consumer, {
187
- children: insets => /*#__PURE__*/_jsx(ModalPresentationContext.Consumer, {
188
- children: isParentModal => /*#__PURE__*/_jsx(HeaderShownContext.Consumer, {
189
- children: isParentHeaderShown => /*#__PURE__*/_jsx(CardStack, {
190
- insets: insets,
191
- isParentHeaderShown: isParentHeaderShown,
192
- isParentModal: isParentModal,
193
- getPreviousRoute: this.getPreviousRoute,
194
- routes: routes,
195
- openingRouteKeys: openingRouteKeys,
196
- closingRouteKeys: closingRouteKeys,
197
- onOpenRoute: this.handleOpenRoute,
198
- onCloseRoute: this.handleCloseRoute,
199
- onTransitionStart: this.handleTransitionStart,
200
- onTransitionEnd: this.handleTransitionEnd,
201
- renderHeader: this.renderHeader,
202
- state: state,
203
- descriptors: descriptors,
204
- onGestureStart: this.handleGestureStart,
205
- onGestureEnd: this.handleGestureEnd,
206
- onGestureCancel: this.handleGestureCancel,
207
- preloadedDescriptors: preloadedDescriptors,
208
- ...rest
209
- })
210
- })
211
- })
212
- })
213
- })
214
- });
48
+ previousDescriptors
49
+ };
215
50
  }
216
- }], [{
217
- key: "getDerivedStateFromProps",
218
- value: function getDerivedStateFromProps(props, state) {
219
- // If there was no change in routes, we don't need to compute anything
220
- if ((props.state.routes === state.previousRoutes || isArrayEqual(props.state.routes.map(r => r.key), state.previousRoutes.map(r => r.key))) && state.routes.length) {
221
- let routes = state.routes;
222
- let previousRoutes = state.previousRoutes;
223
- let descriptors = props.descriptors;
224
- let previousDescriptors = state.previousDescriptors;
225
- if (props.descriptors !== state.previousDescriptors) {
226
- descriptors = state.routes.reduce((acc, route) => {
227
- acc[route.key] = props.descriptors[route.key] || state.descriptors[route.key];
228
- return acc;
229
- }, {});
230
- previousDescriptors = props.descriptors;
231
- }
232
- if (props.state.routes !== state.previousRoutes) {
233
- // if any route objects have changed, we should update them
234
- const map = props.state.routes.reduce((acc, route) => {
235
- acc[route.key] = route;
236
- return acc;
237
- }, {});
238
- routes = state.routes.map(route => map[route.key] || route);
239
- previousRoutes = props.state.routes;
240
- }
241
- return {
242
- routes,
243
- previousRoutes,
244
- descriptors,
245
- previousDescriptors
246
- };
247
- }
248
51
 
249
- // Here we determine which routes were added or removed to animate them
250
- // We keep a copy of the route being removed in local state to be able to animate it
52
+ // Here we determine which routes were added or removed to animate them
53
+ // We keep a copy of the route being removed in local state to be able to animate it
251
54
 
252
- let routes = props.state.index < props.state.routes.length - 1 ?
253
- // Remove any extra routes from the state
254
- // The last visible route should be the focused route, i.e. at current index
255
- props.state.routes.slice(0, props.state.index + 1) : props.state.routes;
55
+ let routes = props.state.index < props.state.routes.length - 1 ?
56
+ // Remove any extra routes from the state
57
+ // The last visible route should be the focused route, i.e. at current index
58
+ props.state.routes.slice(0, props.state.index + 1) : props.state.routes;
256
59
 
257
- // Now we need to determine which routes were added and removed
258
- const {
259
- previousRoutes
260
- } = state;
261
- let {
262
- openingRouteKeys,
263
- closingRouteKeys,
264
- replacingRouteKeys
265
- } = state;
266
- const previousFocusedRoute = previousRoutes[previousRoutes.length - 1];
267
- const nextFocusedRoute = routes[routes.length - 1];
268
- const isAnimationEnabled = key => {
269
- const descriptor = props.descriptors[key] || state.descriptors[key];
270
- return descriptor ? descriptor.options.animation !== 'none' : true;
271
- };
272
- const getAnimationTypeForReplace = key => {
273
- const descriptor = props.descriptors[key] || state.descriptors[key];
274
- return descriptor.options.animationTypeForReplace ?? 'push';
275
- };
276
- if (previousFocusedRoute && previousFocusedRoute.key !== nextFocusedRoute.key) {
277
- // We only need to animate routes if the focused route changed
278
- // Animating previous routes won't be visible coz the focused route is on top of everything
60
+ // Now we need to determine which routes were added and removed
61
+ const {
62
+ previousRoutes
63
+ } = state;
64
+ let {
65
+ openingRouteKeys,
66
+ closingRouteKeys,
67
+ replacingRouteKeys
68
+ } = state;
69
+ const previousFocusedRoute = previousRoutes[previousRoutes.length - 1];
70
+ const nextFocusedRoute = routes[routes.length - 1];
71
+ const isAnimationEnabled = key => {
72
+ const descriptor = props.descriptors[key] || state.descriptors[key];
73
+ return descriptor ? descriptor.options.animation !== 'none' : true;
74
+ };
75
+ const getAnimationTypeForReplace = key => {
76
+ const descriptor = props.descriptors[key] || state.descriptors[key];
77
+ return descriptor.options.animationTypeForReplace ?? 'push';
78
+ };
79
+ if (previousFocusedRoute && previousFocusedRoute.key !== nextFocusedRoute.key) {
80
+ // We only need to animate routes if the focused route changed
81
+ // Animating previous routes won't be visible coz the focused route is on top of everything
279
82
 
280
- if (previousRoutes.some(r => r.key === nextFocusedRoute.key) && !routes.some(r => r.key === previousFocusedRoute.key)) {
281
- // The previously focused route was removed, and the new focused route was already present
282
- // We treat this as a pop
83
+ if (previousRoutes.some(r => r.key === nextFocusedRoute.key) && !routes.some(r => r.key === previousFocusedRoute.key)) {
84
+ // The previously focused route was removed, and the new focused route was already present
85
+ // We treat this as a pop
283
86
 
284
- if (isAnimationEnabled(previousFocusedRoute.key) && !closingRouteKeys.includes(previousFocusedRoute.key)) {
285
- closingRouteKeys = [...closingRouteKeys, previousFocusedRoute.key];
87
+ if (isAnimationEnabled(previousFocusedRoute.key) && !closingRouteKeys.includes(previousFocusedRoute.key)) {
88
+ closingRouteKeys = [...closingRouteKeys, previousFocusedRoute.key];
286
89
 
287
- // Sometimes a route can be closed before the opening animation finishes
288
- // So we also need to remove it from the opening list
289
- openingRouteKeys = openingRouteKeys.filter(key => key !== previousFocusedRoute.key);
290
- replacingRouteKeys = replacingRouteKeys.filter(key => key !== previousFocusedRoute.key);
90
+ // Sometimes a route can be closed before the opening animation finishes
91
+ // So we also need to remove it from the opening list
92
+ openingRouteKeys = openingRouteKeys.filter(key => key !== previousFocusedRoute.key);
93
+ replacingRouteKeys = replacingRouteKeys.filter(key => key !== previousFocusedRoute.key);
291
94
 
292
- // Keep a copy of route being removed in the state to be able to animate it
293
- routes = [...routes, previousFocusedRoute];
294
- }
295
- } else {
296
- // A route has come to the focus, we treat this as a push
297
- // A replace or rearranging can also trigger this
298
- // The animation should look like push
95
+ // Keep a copy of route being removed in the state to be able to animate it
96
+ routes = [...routes, previousFocusedRoute];
97
+ }
98
+ } else {
99
+ // A route has come to the focus, we treat this as a push
100
+ // A replace or rearranging can also trigger this
101
+ // The animation should look like push
299
102
 
300
- if (isAnimationEnabled(nextFocusedRoute.key) && !openingRouteKeys.includes(nextFocusedRoute.key)) {
301
- // In this case, we need to animate pushing the focused route
302
- // We don't care about animating any other added routes because they won't be visible
303
- openingRouteKeys = [...openingRouteKeys, nextFocusedRoute.key];
304
- closingRouteKeys = closingRouteKeys.filter(key => key !== nextFocusedRoute.key);
305
- replacingRouteKeys = replacingRouteKeys.filter(key => key !== nextFocusedRoute.key);
306
- if (!routes.some(r => r.key === previousFocusedRoute.key)) {
307
- // The previous focused route isn't present in state, we treat this as a replace
103
+ if (isAnimationEnabled(nextFocusedRoute.key) && !openingRouteKeys.includes(nextFocusedRoute.key)) {
104
+ // In this case, we need to animate pushing the focused route
105
+ // We don't care about animating any other added routes because they won't be visible
106
+ openingRouteKeys = [...openingRouteKeys, nextFocusedRoute.key];
107
+ closingRouteKeys = closingRouteKeys.filter(key => key !== nextFocusedRoute.key);
108
+ replacingRouteKeys = replacingRouteKeys.filter(key => key !== nextFocusedRoute.key);
109
+ if (!routes.some(r => r.key === previousFocusedRoute.key)) {
110
+ // The previous focused route isn't present in state, we treat this as a replace
308
111
 
309
- openingRouteKeys = openingRouteKeys.filter(key => key !== previousFocusedRoute.key);
310
- if (getAnimationTypeForReplace(nextFocusedRoute.key) === 'pop') {
311
- closingRouteKeys = [...closingRouteKeys, previousFocusedRoute.key];
112
+ openingRouteKeys = openingRouteKeys.filter(key => key !== previousFocusedRoute.key);
113
+ if (getAnimationTypeForReplace(nextFocusedRoute.key) === 'pop') {
114
+ closingRouteKeys = [...closingRouteKeys, previousFocusedRoute.key];
312
115
 
313
- // By default, new routes have a push animation, so we add it to `openingRouteKeys` before
314
- // But since user configured it to animate the old screen like a pop, we need to add this without animation
315
- // So remove it from `openingRouteKeys` which will remove the animation
316
- openingRouteKeys = openingRouteKeys.filter(key => key !== nextFocusedRoute.key);
116
+ // By default, new routes have a push animation, so we add it to `openingRouteKeys` before
117
+ // But since user configured it to animate the old screen like a pop, we need to add this without animation
118
+ // So remove it from `openingRouteKeys` which will remove the animation
119
+ openingRouteKeys = openingRouteKeys.filter(key => key !== nextFocusedRoute.key);
317
120
 
318
- // Keep the route being removed at the end to animate it out
319
- routes = [...routes, previousFocusedRoute];
320
- } else {
321
- replacingRouteKeys = [...replacingRouteKeys, previousFocusedRoute.key];
322
- closingRouteKeys = closingRouteKeys.filter(key => key !== previousFocusedRoute.key);
121
+ // Keep the route being removed at the end to animate it out
122
+ routes = [...routes, previousFocusedRoute];
123
+ } else {
124
+ replacingRouteKeys = [...replacingRouteKeys, previousFocusedRoute.key];
125
+ closingRouteKeys = closingRouteKeys.filter(key => key !== previousFocusedRoute.key);
323
126
 
324
- // Keep the old route in the state because it's visible under the new route, and removing it will feel abrupt
325
- // We need to insert it just before the focused one (the route being pushed)
326
- // After the push animation is completed, routes being replaced will be removed completely
327
- routes = routes.slice();
328
- routes.splice(routes.length - 1, 0, previousFocusedRoute);
329
- }
127
+ // Keep the old route in the state because it's visible under the new route, and removing it will feel abrupt
128
+ // We need to insert it just before the focused one (the route being pushed)
129
+ // After the push animation is completed, routes being replaced will be removed completely
130
+ routes = routes.slice();
131
+ routes.splice(routes.length - 1, 0, previousFocusedRoute);
330
132
  }
331
133
  }
332
134
  }
333
- } else if (replacingRouteKeys.length || closingRouteKeys.length) {
334
- // Keep the routes we are closing or replacing if animation is enabled for them
335
- routes = routes.slice();
336
- routes.splice(routes.length - 1, 0, ...state.routes.filter(({
337
- key
338
- }) => isAnimationEnabled(key) ? replacingRouteKeys.includes(key) || closingRouteKeys.includes(key) : false));
339
135
  }
340
- if (!routes.length) {
341
- throw new Error('There should always be at least one route in the navigation state.');
342
- }
343
- const descriptors = routes.reduce((acc, route) => {
344
- acc[route.key] = props.descriptors[route.key] || state.descriptors[route.key];
345
- return acc;
346
- }, {});
347
- return {
348
- routes,
349
- previousRoutes: props.state.routes,
350
- previousDescriptors: props.descriptors,
351
- openingRouteKeys,
352
- closingRouteKeys,
353
- replacingRouteKeys,
354
- descriptors
355
- };
136
+ } else if (replacingRouteKeys.length || closingRouteKeys.length) {
137
+ // Keep the routes we are closing or replacing if animation is enabled for them
138
+ routes = routes.slice();
139
+ routes.splice(routes.length - 1, 0, ...state.routes.filter(({
140
+ key
141
+ }) => isAnimationEnabled(key) ? replacingRouteKeys.includes(key) || closingRouteKeys.includes(key) : false));
356
142
  }
357
- }]);
358
- }(React.Component);
143
+ if (!routes.length) {
144
+ throw new Error('There should always be at least one route in the navigation state.');
145
+ }
146
+ const descriptors = routes.reduce((acc, route) => {
147
+ acc[route.key] = props.descriptors[route.key] || state.descriptors[route.key];
148
+ return acc;
149
+ }, {});
150
+ return {
151
+ routes,
152
+ previousRoutes: props.state.routes,
153
+ previousDescriptors: props.descriptors,
154
+ openingRouteKeys,
155
+ closingRouteKeys,
156
+ replacingRouteKeys,
157
+ descriptors
158
+ };
159
+ }
160
+ state = {
161
+ routes: [],
162
+ previousRoutes: [],
163
+ previousDescriptors: {},
164
+ openingRouteKeys: [],
165
+ closingRouteKeys: [],
166
+ replacingRouteKeys: [],
167
+ descriptors: {}
168
+ };
169
+ getPreviousRoute = ({
170
+ route
171
+ }) => {
172
+ const {
173
+ closingRouteKeys,
174
+ replacingRouteKeys
175
+ } = this.state;
176
+ const routes = this.state.routes.filter(r => r.key === route.key || !closingRouteKeys.includes(r.key) && !replacingRouteKeys.includes(r.key));
177
+ const index = routes.findIndex(r => r.key === route.key);
178
+ return routes[index - 1];
179
+ };
180
+ renderHeader = props => {
181
+ return /*#__PURE__*/_jsx(HeaderContainer, {
182
+ ...props
183
+ });
184
+ };
185
+ handleOpenRoute = ({
186
+ route
187
+ }) => {
188
+ const {
189
+ state,
190
+ navigation
191
+ } = this.props;
192
+ const {
193
+ closingRouteKeys,
194
+ replacingRouteKeys
195
+ } = this.state;
196
+ if (closingRouteKeys.some(key => key === route.key) && replacingRouteKeys.every(key => key !== route.key) && state.routeNames.includes(route.name) && !state.routes.some(r => r.key === route.key)) {
197
+ // If route isn't present in current state, but was closing, assume that a close animation was cancelled
198
+ // So we need to add this route back to the state
199
+ navigation.dispatch(state => {
200
+ const routes = [...state.routes.filter(r => r.key !== route.key), route];
201
+ return CommonActions.reset({
202
+ ...state,
203
+ routes,
204
+ index: routes.length - 1
205
+ });
206
+ });
207
+ } else {
208
+ this.setState(state => ({
209
+ routes: state.replacingRouteKeys.length ? state.routes.filter(r => !state.replacingRouteKeys.includes(r.key)) : state.routes,
210
+ openingRouteKeys: state.openingRouteKeys.filter(key => key !== route.key),
211
+ closingRouteKeys: state.closingRouteKeys.filter(key => key !== route.key),
212
+ replacingRouteKeys: []
213
+ }));
214
+ }
215
+ };
216
+ handleCloseRoute = ({
217
+ route
218
+ }) => {
219
+ const {
220
+ state,
221
+ navigation
222
+ } = this.props;
223
+ if (state.routes.some(r => r.key === route.key)) {
224
+ // If a route exists in state, trigger a pop
225
+ // This will happen in when the route was closed from the card component
226
+ // e.g. When the close animation triggered from a gesture ends
227
+ navigation.dispatch({
228
+ ...StackActions.pop(),
229
+ source: route.key,
230
+ target: state.key
231
+ });
232
+ } else {
233
+ // We need to clean up any state tracking the route and pop it immediately
234
+ this.setState(state => ({
235
+ routes: state.routes.filter(r => r.key !== route.key),
236
+ openingRouteKeys: state.openingRouteKeys.filter(key => key !== route.key),
237
+ closingRouteKeys: state.closingRouteKeys.filter(key => key !== route.key)
238
+ }));
239
+ }
240
+ };
241
+ handleTransitionStart = ({
242
+ route
243
+ }, closing) => this.props.navigation.emit({
244
+ type: 'transitionStart',
245
+ data: {
246
+ closing
247
+ },
248
+ target: route.key
249
+ });
250
+ handleTransitionEnd = ({
251
+ route
252
+ }, closing) => this.props.navigation.emit({
253
+ type: 'transitionEnd',
254
+ data: {
255
+ closing
256
+ },
257
+ target: route.key
258
+ });
259
+ handleGestureStart = ({
260
+ route
261
+ }) => {
262
+ this.props.navigation.emit({
263
+ type: 'gestureStart',
264
+ target: route.key
265
+ });
266
+ };
267
+ handleGestureEnd = ({
268
+ route
269
+ }) => {
270
+ this.props.navigation.emit({
271
+ type: 'gestureEnd',
272
+ target: route.key
273
+ });
274
+ };
275
+ handleGestureCancel = ({
276
+ route
277
+ }) => {
278
+ this.props.navigation.emit({
279
+ type: 'gestureCancel',
280
+ target: route.key
281
+ });
282
+ };
283
+ render() {
284
+ const {
285
+ state,
286
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
287
+ descriptors: _,
288
+ ...rest
289
+ } = this.props;
290
+ const {
291
+ routes,
292
+ descriptors,
293
+ openingRouteKeys,
294
+ closingRouteKeys
295
+ } = this.state;
296
+ const preloadedDescriptors = state.preloadedRoutes.reduce((acc, route) => {
297
+ acc[route.key] = acc[route.key] || this.props.describe(route, true);
298
+ return acc;
299
+ }, {});
300
+ return /*#__PURE__*/_jsx(GestureHandlerWrapper, {
301
+ style: styles.container,
302
+ children: /*#__PURE__*/_jsx(SafeAreaProviderCompat, {
303
+ children: /*#__PURE__*/_jsx(SafeAreaInsetsContext.Consumer, {
304
+ children: insets => /*#__PURE__*/_jsx(ModalPresentationContext.Consumer, {
305
+ children: isParentModal => /*#__PURE__*/_jsx(HeaderShownContext.Consumer, {
306
+ children: isParentHeaderShown => /*#__PURE__*/_jsx(CardStack, {
307
+ insets: insets,
308
+ isParentHeaderShown: isParentHeaderShown,
309
+ isParentModal: isParentModal,
310
+ getPreviousRoute: this.getPreviousRoute,
311
+ routes: routes,
312
+ openingRouteKeys: openingRouteKeys,
313
+ closingRouteKeys: closingRouteKeys,
314
+ onOpenRoute: this.handleOpenRoute,
315
+ onCloseRoute: this.handleCloseRoute,
316
+ onTransitionStart: this.handleTransitionStart,
317
+ onTransitionEnd: this.handleTransitionEnd,
318
+ renderHeader: this.renderHeader,
319
+ state: state,
320
+ descriptors: descriptors,
321
+ onGestureStart: this.handleGestureStart,
322
+ onGestureEnd: this.handleGestureEnd,
323
+ onGestureCancel: this.handleGestureCancel,
324
+ preloadedDescriptors: preloadedDescriptors,
325
+ ...rest
326
+ })
327
+ })
328
+ })
329
+ })
330
+ })
331
+ });
332
+ }
333
+ }
359
334
  const styles = StyleSheet.create({
360
335
  container: {
361
336
  flex: 1