@react-navigation/stack 7.0.13 → 7.0.14

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