@react-navigation/stack 8.0.0-alpha.4 → 8.0.0-alpha.40

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.
Files changed (126) hide show
  1. package/lib/module/index.js +2 -2
  2. package/lib/module/index.js.map +1 -1
  3. package/lib/module/navigators/createStackNavigator.js +3 -7
  4. package/lib/module/navigators/createStackNavigator.js.map +1 -1
  5. package/lib/module/utils/GestureHandlerContext.js +5 -0
  6. package/lib/module/utils/GestureHandlerContext.js.map +1 -0
  7. package/lib/module/utils/gestureActivationCriteria.js +10 -8
  8. package/lib/module/utils/gestureActivationCriteria.js.map +1 -1
  9. package/lib/module/utils/useCardAnimation.js +1 -1
  10. package/lib/module/utils/useCardAnimation.js.map +1 -1
  11. package/lib/module/utils/useGestureHandler.js +9 -0
  12. package/lib/module/utils/useGestureHandler.js.map +1 -0
  13. package/lib/module/utils/useKeyboardManager.js +71 -26
  14. package/lib/module/utils/useKeyboardManager.js.map +1 -1
  15. package/lib/module/views/GestureHandler.js +15 -14
  16. package/lib/module/views/GestureHandler.js.map +1 -1
  17. package/lib/module/views/GestureHandlerNative.js +16 -10
  18. package/lib/module/views/GestureHandlerNative.js.map +1 -1
  19. package/lib/module/views/Header/Header.js +2 -2
  20. package/lib/module/views/Header/Header.js.map +1 -1
  21. package/lib/module/views/Header/HeaderContainer.js +52 -18
  22. package/lib/module/views/Header/HeaderContainer.js.map +1 -1
  23. package/lib/module/views/Header/HeaderSegment.js +2 -2
  24. package/lib/module/views/Header/HeaderSegment.js.map +1 -1
  25. package/lib/module/views/Stack/Card.js +90 -87
  26. package/lib/module/views/Stack/Card.js.map +1 -1
  27. package/lib/module/views/Stack/CardContainer.js +72 -98
  28. package/lib/module/views/Stack/CardContainer.js.map +1 -1
  29. package/lib/module/views/Stack/CardStack.js +171 -126
  30. package/lib/module/views/Stack/CardStack.js.map +1 -1
  31. package/lib/module/views/Stack/StackView.js +103 -53
  32. package/lib/module/views/Stack/StackView.js.map +1 -1
  33. package/lib/typescript/src/TransitionConfigs/CardStyleInterpolators.d.ts +1 -1
  34. package/lib/typescript/src/TransitionConfigs/CardStyleInterpolators.d.ts.map +1 -1
  35. package/lib/typescript/src/TransitionConfigs/HeaderStyleInterpolators.d.ts +1 -1
  36. package/lib/typescript/src/TransitionConfigs/HeaderStyleInterpolators.d.ts.map +1 -1
  37. package/lib/typescript/src/TransitionConfigs/TransitionPresets.d.ts +1 -1
  38. package/lib/typescript/src/TransitionConfigs/TransitionPresets.d.ts.map +1 -1
  39. package/lib/typescript/src/TransitionConfigs/TransitionSpecs.d.ts +1 -1
  40. package/lib/typescript/src/TransitionConfigs/TransitionSpecs.d.ts.map +1 -1
  41. package/lib/typescript/src/index.d.ts +12 -12
  42. package/lib/typescript/src/index.d.ts.map +1 -1
  43. package/lib/typescript/src/navigators/createStackNavigator.d.ts +10 -15
  44. package/lib/typescript/src/navigators/createStackNavigator.d.ts.map +1 -1
  45. package/lib/typescript/src/types.d.ts +46 -53
  46. package/lib/typescript/src/types.d.ts.map +1 -1
  47. package/lib/typescript/src/utils/CardAnimationContext.d.ts +1 -1
  48. package/lib/typescript/src/utils/CardAnimationContext.d.ts.map +1 -1
  49. package/lib/typescript/src/utils/GestureHandlerContext.d.ts +3 -0
  50. package/lib/typescript/src/utils/GestureHandlerContext.d.ts.map +1 -0
  51. package/lib/typescript/src/utils/gestureActivationCriteria.d.ts +4 -51
  52. package/lib/typescript/src/utils/gestureActivationCriteria.d.ts.map +1 -1
  53. package/lib/typescript/src/utils/getDistanceForDirection.d.ts +1 -1
  54. package/lib/typescript/src/utils/getDistanceForDirection.d.ts.map +1 -1
  55. package/lib/typescript/src/utils/getInvertedMultiplier.d.ts +1 -1
  56. package/lib/typescript/src/utils/getInvertedMultiplier.d.ts.map +1 -1
  57. package/lib/typescript/src/utils/getModalRoutesKeys.d.ts +1 -1
  58. package/lib/typescript/src/utils/getModalRoutesKeys.d.ts.map +1 -1
  59. package/lib/typescript/src/utils/useCardAnimation.d.ts +1 -1
  60. package/lib/typescript/src/utils/useCardAnimation.d.ts.map +1 -1
  61. package/lib/typescript/src/utils/useGestureHandler.d.ts +2 -0
  62. package/lib/typescript/src/utils/useGestureHandler.d.ts.map +1 -0
  63. package/lib/typescript/src/utils/useKeyboardManager.d.ts +12 -2
  64. package/lib/typescript/src/utils/useKeyboardManager.d.ts.map +1 -1
  65. package/lib/typescript/src/views/GestureHandler.android.d.ts +1 -1
  66. package/lib/typescript/src/views/GestureHandler.android.d.ts.map +1 -1
  67. package/lib/typescript/src/views/GestureHandler.d.ts +7 -11
  68. package/lib/typescript/src/views/GestureHandler.d.ts.map +1 -1
  69. package/lib/typescript/src/views/GestureHandler.ios.d.ts +1 -1
  70. package/lib/typescript/src/views/GestureHandler.ios.d.ts.map +1 -1
  71. package/lib/typescript/src/views/GestureHandlerNative.d.ts +9 -4
  72. package/lib/typescript/src/views/GestureHandlerNative.d.ts.map +1 -1
  73. package/lib/typescript/src/views/Header/Header.d.ts +2 -2
  74. package/lib/typescript/src/views/Header/Header.d.ts.map +1 -1
  75. package/lib/typescript/src/views/Header/HeaderContainer.d.ts +9 -3
  76. package/lib/typescript/src/views/Header/HeaderContainer.d.ts.map +1 -1
  77. package/lib/typescript/src/views/Header/HeaderSegment.d.ts +5 -4
  78. package/lib/typescript/src/views/Header/HeaderSegment.d.ts.map +1 -1
  79. package/lib/typescript/src/views/Stack/Card.d.ts +5 -5
  80. package/lib/typescript/src/views/Stack/Card.d.ts.map +1 -1
  81. package/lib/typescript/src/views/Stack/CardContainer.d.ts +5 -7
  82. package/lib/typescript/src/views/Stack/CardContainer.d.ts.map +1 -1
  83. package/lib/typescript/src/views/Stack/CardContent.d.ts +1 -1
  84. package/lib/typescript/src/views/Stack/CardContent.d.ts.map +1 -1
  85. package/lib/typescript/src/views/Stack/CardStack.d.ts +6 -5
  86. package/lib/typescript/src/views/Stack/CardStack.d.ts.map +1 -1
  87. package/lib/typescript/src/views/Stack/StackView.d.ts +10 -13
  88. package/lib/typescript/src/views/Stack/StackView.d.ts.map +1 -1
  89. package/package.json +21 -23
  90. package/src/index.tsx +3 -2
  91. package/src/navigators/createStackNavigator.tsx +9 -40
  92. package/src/types.tsx +73 -73
  93. package/src/utils/GestureHandlerContext.tsx +5 -0
  94. package/src/utils/gestureActivationCriteria.tsx +14 -10
  95. package/src/utils/useCardAnimation.tsx +1 -1
  96. package/src/utils/useGestureHandler.tsx +9 -0
  97. package/src/utils/useKeyboardManager.tsx +96 -33
  98. package/src/views/GestureHandler.tsx +27 -16
  99. package/src/views/GestureHandlerNative.tsx +26 -12
  100. package/src/views/Header/Header.tsx +2 -2
  101. package/src/views/Header/HeaderContainer.tsx +67 -24
  102. package/src/views/Header/HeaderSegment.tsx +4 -4
  103. package/src/views/Stack/Card.tsx +134 -115
  104. package/src/views/Stack/CardContainer.tsx +86 -127
  105. package/src/views/Stack/CardStack.tsx +380 -323
  106. package/src/views/Stack/StackView.tsx +173 -71
  107. package/lib/module/utils/GestureHandlerRefContext.js +0 -5
  108. package/lib/module/utils/GestureHandlerRefContext.js.map +0 -1
  109. package/lib/module/utils/findLastIndex.js +0 -11
  110. package/lib/module/utils/findLastIndex.js.map +0 -1
  111. package/lib/module/utils/useGestureHandlerRef.js +0 -12
  112. package/lib/module/utils/useGestureHandlerRef.js.map +0 -1
  113. package/lib/module/views/Stack/CardA11yWrapper.js +0 -43
  114. package/lib/module/views/Stack/CardA11yWrapper.js.map +0 -1
  115. package/lib/typescript/src/utils/GestureHandlerRefContext.d.ts +0 -3
  116. package/lib/typescript/src/utils/GestureHandlerRefContext.d.ts.map +0 -1
  117. package/lib/typescript/src/utils/findLastIndex.d.ts +0 -2
  118. package/lib/typescript/src/utils/findLastIndex.d.ts.map +0 -1
  119. package/lib/typescript/src/utils/useGestureHandlerRef.d.ts +0 -3
  120. package/lib/typescript/src/utils/useGestureHandlerRef.d.ts.map +0 -1
  121. package/lib/typescript/src/views/Stack/CardA11yWrapper.d.ts +0 -15
  122. package/lib/typescript/src/views/Stack/CardA11yWrapper.d.ts.map +0 -1
  123. package/src/utils/GestureHandlerRefContext.tsx +0 -5
  124. package/src/utils/findLastIndex.tsx +0 -9
  125. package/src/utils/useGestureHandlerRef.tsx +0 -15
  126. package/src/views/Stack/CardA11yWrapper.tsx +0 -67
@@ -35,10 +35,8 @@ type Props = StackNavigationConfig & {
35
35
  type State = {
36
36
  // Local copy of the routes which are actually rendered
37
37
  routes: Route<string>[];
38
- // Previous routes, to compare whether routes have changed or not
39
- previousRoutes: Route<string>[];
40
- // Previous descriptors, to compare whether descriptors have changed or not
41
- previousDescriptors: StackDescriptorMap;
38
+ // Previous navigation state for comparison
39
+ previousState: StackNavigationState<ParamListBase> | undefined;
42
40
  // List of routes being opened, we need to animate pushing of these new routes
43
41
  openingRouteKeys: string[];
44
42
  // List of routes being closed, we need to animate popping of these routes
@@ -64,33 +62,63 @@ export class StackView extends React.Component<Props, State> {
64
62
  props: Readonly<Props>,
65
63
  state: Readonly<State>
66
64
  ) {
67
- const allRoutes = [...props.state.routes, ...props.state.preloadedRoutes];
65
+ const allRoutes = props.state.routes;
66
+ const previousRoutes = state.previousState?.routes ?? [];
67
+ const previousFocusedRoute =
68
+ state.previousState?.routes[state.previousState.index];
69
+ const nextFocusedRouteFromState = props.state.routes[props.state.index];
70
+
71
+ if (state.previousState && previousFocusedRoute == null) {
72
+ throw new Error(
73
+ `Couldn't find a route at index ${state.previousState.index}.`
74
+ );
75
+ }
76
+
77
+ if (nextFocusedRouteFromState == null) {
78
+ throw new Error(`Couldn't find a route at index ${props.state.index}.`);
79
+ }
80
+
81
+ const activeRoutes = props.state.routes.slice(0, props.state.index + 1);
68
82
 
69
83
  // If there was no change in routes, we don't need to compute anything
70
84
  if (
71
85
  isArrayEqual(
72
86
  allRoutes.map((r) => r.key),
73
- state.previousRoutes.map((r) => r.key)
87
+ previousRoutes.map((r) => r.key)
74
88
  ) &&
89
+ previousFocusedRoute?.key === nextFocusedRouteFromState?.key &&
75
90
  state.routes.length
76
91
  ) {
77
- let routes = props.state.routes;
78
- let previousRoutes = state.previousRoutes;
79
- let descriptors = props.descriptors;
80
- let previousDescriptors = state.previousDescriptors;
92
+ // If there were any routes being closed or replaced,
93
+ // We need to make sure they are preserved in the new state from props.state
94
+ // So first we get all such routes from the previous state (that included the animating routes)
95
+ // Then we add them back to the new state if they don't already exist
96
+
97
+ const closingRoutes = state.routes.filter(
98
+ (r) =>
99
+ state.closingRouteKeys.includes(r.key) &&
100
+ !activeRoutes.some((pr) => pr.key === r.key)
101
+ );
102
+
103
+ const replacingRoutes = state.routes.filter(
104
+ (r) =>
105
+ state.replacingRouteKeys.includes(r.key) &&
106
+ !activeRoutes.some((pr) => pr.key === r.key)
107
+ );
81
108
 
82
- if (props.descriptors !== state.previousDescriptors) {
83
- descriptors = state.routes.reduce<StackDescriptorMap>((acc, route) => {
84
- acc[route.key] =
85
- props.descriptors[route.key] || state.descriptors[route.key];
109
+ let routes: Route<string>[] = activeRoutes.slice();
86
110
 
87
- return acc;
88
- }, {});
111
+ // Replacing routes go before the focused route (they're being covered)
112
+ if (replacingRoutes.length) {
113
+ routes.splice(routes.length - 1, 0, ...replacingRoutes);
114
+ }
89
115
 
90
- previousDescriptors = props.descriptors;
116
+ // Closing routes go at the end (they're animating out on top)
117
+ if (closingRoutes.length) {
118
+ routes.push(...closingRoutes);
91
119
  }
92
120
 
93
- if (!isArrayEqual(allRoutes, state.previousRoutes)) {
121
+ if (!isArrayEqual(allRoutes, previousRoutes)) {
94
122
  // if any route objects have changed, we should update them
95
123
  const map = allRoutes.reduce<Record<string, Route<string>>>(
96
124
  (acc, route) => {
@@ -100,50 +128,73 @@ export class StackView extends React.Component<Props, State> {
100
128
  {}
101
129
  );
102
130
 
103
- routes = props.state.routes.map((route) => map[route.key] || route);
104
- previousRoutes = allRoutes;
131
+ routes = routes.map((route) => map[route.key] ?? route);
105
132
  }
106
133
 
134
+ const routeKeys = new Set(routes.map((route) => route.key));
135
+ const descriptors = [
136
+ ...routes,
137
+ ...props.state.routes.filter((route) => !routeKeys.has(route.key)),
138
+ ].reduce<StackDescriptorMap>((acc, route) => {
139
+ const descriptor =
140
+ props.descriptors[route.key] ?? state.descriptors[route.key];
141
+
142
+ if (descriptor == null) {
143
+ throw new Error(
144
+ `Couldn't find a descriptor for route '${route.key}'.`
145
+ );
146
+ }
147
+
148
+ acc[route.key] = descriptor;
149
+
150
+ return acc;
151
+ }, {});
152
+
107
153
  return {
108
154
  routes,
109
- previousRoutes,
155
+ previousState: props.state,
110
156
  descriptors,
111
- previousDescriptors,
112
157
  };
113
158
  }
114
159
 
115
160
  // Here we determine which routes were added or removed to animate them
116
161
  // We keep a copy of the route being removed in local state to be able to animate it
117
162
 
118
- let routes =
119
- props.state.index < props.state.routes.length - 1
120
- ? // Remove any extra routes from the state
121
- // The last visible route should be the focused route, i.e. at current index
122
- props.state.routes.slice(0, props.state.index + 1)
123
- : props.state.routes;
163
+ let { openingRouteKeys, closingRouteKeys, replacingRouteKeys } = state;
124
164
 
125
- // Now we need to determine which routes were added and removed
126
- const { previousRoutes } = state;
165
+ // If a route that was closing or being replaced is now back in the routes,
166
+ // it was added back before the animation finished, so stop tracking it
167
+ closingRouteKeys = closingRouteKeys.filter(
168
+ (key) => !activeRoutes.some((r) => r.key === key)
169
+ );
127
170
 
128
- let { openingRouteKeys, closingRouteKeys, replacingRouteKeys } = state;
171
+ replacingRouteKeys = replacingRouteKeys.filter(
172
+ (key) => !activeRoutes.some((r) => r.key === key)
173
+ );
129
174
 
130
- const previousFocusedRoute = previousRoutes[previousRoutes.length - 1] as
131
- | Route<string>
132
- | undefined;
133
- const nextFocusedRoute = routes[routes.length - 1];
175
+ // Get previous focused route from previous active routes
176
+ const nextFocusedRoute = activeRoutes[activeRoutes.length - 1];
177
+
178
+ if (nextFocusedRoute == null) {
179
+ throw new Error(
180
+ `Couldn't find a route at index ${activeRoutes.length - 1}.`
181
+ );
182
+ }
134
183
 
135
184
  const isAnimationEnabled = (key: string) => {
136
- const descriptor = props.descriptors[key] || state.descriptors[key];
185
+ const descriptor = props.descriptors[key] ?? state.descriptors[key];
137
186
 
138
187
  return getAnimationEnabled(descriptor?.options.animation);
139
188
  };
140
189
 
141
190
  const getAnimationTypeForReplace = (key: string) => {
142
- const descriptor = props.descriptors[key] || state.descriptors[key];
191
+ const descriptor = props.descriptors[key] ?? state.descriptors[key];
143
192
 
144
- return descriptor.options.animationTypeForReplace ?? 'push';
193
+ return descriptor?.options.animationTypeForReplace ?? 'push';
145
194
  };
146
195
 
196
+ let routes = activeRoutes;
197
+
147
198
  if (
148
199
  previousFocusedRoute &&
149
200
  previousFocusedRoute.key !== nextFocusedRoute.key
@@ -233,6 +284,18 @@ export class StackView extends React.Component<Props, State> {
233
284
  // After the push animation is completed, routes being replaced will be removed completely
234
285
  routes = routes.slice();
235
286
  routes.splice(routes.length - 1, 0, previousFocusedRoute);
287
+
288
+ // Preserve any other routes still being replaced from previous transitions
289
+ const previousReplacingRoutes = state.routes.filter(
290
+ (r) =>
291
+ replacingRouteKeys.includes(r.key) &&
292
+ !routes.some((existing) => existing.key === r.key)
293
+ );
294
+
295
+ if (previousReplacingRoutes.length) {
296
+ // Insert before the route we just added (previousFocusedRoute)
297
+ routes.splice(routes.length - 2, 0, ...previousReplacingRoutes);
298
+ }
236
299
  }
237
300
  }
238
301
  }
@@ -257,17 +320,26 @@ export class StackView extends React.Component<Props, State> {
257
320
  );
258
321
  }
259
322
 
260
- const descriptors = allRoutes.reduce<StackDescriptorMap>((acc, route) => {
261
- acc[route.key] =
262
- props.descriptors[route.key] || state.descriptors[route.key];
323
+ const routeKeys = new Set(routes.map((route) => route.key));
324
+ const descriptors = [
325
+ ...routes,
326
+ ...props.state.routes.filter((route) => !routeKeys.has(route.key)),
327
+ ].reduce<StackDescriptorMap>((acc, route) => {
328
+ const descriptor =
329
+ props.descriptors[route.key] ?? state.descriptors[route.key];
330
+
331
+ if (descriptor == null) {
332
+ throw new Error(`Couldn't find a descriptor for route '${route.key}'.`);
333
+ }
334
+
335
+ acc[route.key] = descriptor;
263
336
 
264
337
  return acc;
265
338
  }, {});
266
339
 
267
340
  return {
268
341
  routes,
269
- previousRoutes: [...props.state.routes, ...props.state.preloadedRoutes],
270
- previousDescriptors: props.descriptors,
342
+ previousState: props.state,
271
343
  openingRouteKeys,
272
344
  closingRouteKeys,
273
345
  replacingRouteKeys,
@@ -277,8 +349,7 @@ export class StackView extends React.Component<Props, State> {
277
349
 
278
350
  state: State = {
279
351
  routes: [],
280
- previousRoutes: [],
281
- previousDescriptors: {},
352
+ previousState: undefined,
282
353
  openingRouteKeys: [],
283
354
  closingRouteKeys: [],
284
355
  replacingRouteKeys: [],
@@ -307,48 +378,73 @@ export class StackView extends React.Component<Props, State> {
307
378
  const { state, navigation } = this.props;
308
379
  const { closingRouteKeys, replacingRouteKeys } = this.state;
309
380
 
381
+ const activeRoutes = state.routes.slice(0, state.index + 1);
382
+
310
383
  if (
311
384
  closingRouteKeys.some((key) => key === route.key) &&
312
385
  replacingRouteKeys.every((key) => key !== route.key) &&
313
386
  state.routeNames.includes(route.name) &&
314
- !state.routes.some((r) => r.key === route.key)
387
+ !activeRoutes.some((r) => r.key === route.key)
315
388
  ) {
316
- // If route isn't present in current state, but was closing, assume that a close animation was cancelled
389
+ // If route is no longer active, but was closing, assume that a close animation was cancelled
317
390
  // So we need to add this route back to the state
318
391
  navigation.dispatch((state) => {
319
- const routes = [
320
- ...state.routes.filter((r) => r.key !== route.key),
321
- route,
322
- ];
392
+ const activeRoutes = state.routes
393
+ .slice(0, state.index + 1)
394
+ .filter((r) => r.key !== route.key);
395
+ const inactiveRoutes = state.routes
396
+ .slice(state.index + 1)
397
+ .filter((r) => r.key !== route.key);
398
+
399
+ const routes = [...activeRoutes, route];
323
400
 
324
- return CommonActions.reset({
401
+ const resetState = {
325
402
  ...state,
326
- routes,
327
403
  index: routes.length - 1,
328
- });
404
+ routes: routes.concat(inactiveRoutes),
405
+ };
406
+
407
+ return CommonActions.reset(resetState);
329
408
  });
330
409
  } else {
331
- this.setState((state) => ({
332
- routes: state.replacingRouteKeys.length
333
- ? state.routes.filter(
334
- (r) => !state.replacingRouteKeys.includes(r.key)
335
- )
336
- : state.routes,
337
- openingRouteKeys: state.openingRouteKeys.filter(
338
- (key) => key !== route.key
339
- ),
340
- closingRouteKeys: state.closingRouteKeys.filter(
341
- (key) => key !== route.key
342
- ),
343
- replacingRouteKeys: [],
344
- }));
410
+ this.setState((state) => {
411
+ const routeIndex = state.routes.findIndex((r) => r.key === route.key);
412
+
413
+ // Remove replacing routes that were before the route that just opened
414
+ // Those were replaced by this or earlier routes and should be cleaned up
415
+ const replacingRoutesToRemove = new Set(
416
+ state.routes
417
+ .slice(0, routeIndex)
418
+ .filter((r) => state.replacingRouteKeys.includes(r.key))
419
+ .map((r) => r.key)
420
+ );
421
+
422
+ const newRoutes = state.routes.filter(
423
+ (r) => !replacingRoutesToRemove.has(r.key)
424
+ );
425
+
426
+ return {
427
+ routes: newRoutes,
428
+ openingRouteKeys: state.openingRouteKeys.filter(
429
+ (key) => key !== route.key
430
+ ),
431
+ closingRouteKeys: state.closingRouteKeys.filter(
432
+ (key) => key !== route.key
433
+ ),
434
+ replacingRouteKeys: state.replacingRouteKeys.filter(
435
+ (key) => !replacingRoutesToRemove.has(key)
436
+ ),
437
+ };
438
+ });
345
439
  }
346
440
  };
347
441
 
348
442
  private handleCloseRoute = ({ route }: { route: Route<string> }) => {
349
443
  const { state, navigation } = this.props;
350
444
 
351
- if (state.routes.some((r) => r.key === route.key)) {
445
+ const activeRoutes = state.routes.slice(0, state.index + 1);
446
+
447
+ if (activeRoutes.some((r) => r.key === route.key)) {
352
448
  // If a route exists in state, trigger a pop
353
449
  // This will happen in when the route was closed from the card component
354
450
  // e.g. When the close animation triggered from a gesture ends
@@ -420,8 +516,13 @@ export class StackView extends React.Component<Props, State> {
420
516
  ...rest
421
517
  } = this.props;
422
518
 
423
- const { routes, descriptors, openingRouteKeys, closingRouteKeys } =
424
- this.state;
519
+ const {
520
+ routes,
521
+ descriptors,
522
+ openingRouteKeys,
523
+ closingRouteKeys,
524
+ replacingRouteKeys,
525
+ } = this.state;
425
526
 
426
527
  return (
427
528
  <GestureHandlerWrapper style={styles.container}>
@@ -440,6 +541,7 @@ export class StackView extends React.Component<Props, State> {
440
541
  routes={routes}
441
542
  openingRouteKeys={openingRouteKeys}
442
543
  closingRouteKeys={closingRouteKeys}
544
+ replacingRouteKeys={replacingRouteKeys}
443
545
  onOpenRoute={this.handleOpenRoute}
444
546
  onCloseRoute={this.handleCloseRoute}
445
547
  onTransitionStart={this.handleTransitionStart}
@@ -1,5 +0,0 @@
1
- "use strict";
2
-
3
- import * as React from 'react';
4
- export const GestureHandlerRefContext = /*#__PURE__*/React.createContext(null);
5
- //# sourceMappingURL=GestureHandlerRefContext.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["React","GestureHandlerRefContext","createContext"],"sourceRoot":"../../../src","sources":["utils/GestureHandlerRefContext.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAE9B,OAAO,MAAMC,wBAAwB,gBAAGD,KAAK,CAACE,aAAa,CAEjD,IAAI,CAAC","ignoreList":[]}
@@ -1,11 +0,0 @@
1
- "use strict";
2
-
3
- export function findLastIndex(array, callback) {
4
- for (let i = array.length - 1; i >= 0; i--) {
5
- if (callback(array[i])) {
6
- return i;
7
- }
8
- }
9
- return -1;
10
- }
11
- //# sourceMappingURL=findLastIndex.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["findLastIndex","array","callback","i","length"],"sourceRoot":"../../../src","sources":["utils/findLastIndex.tsx"],"mappings":";;AAAA,OAAO,SAASA,aAAaA,CAAIC,KAAU,EAAEC,QAA+B,EAAE;EAC5E,KAAK,IAAIC,CAAC,GAAGF,KAAK,CAACG,MAAM,GAAG,CAAC,EAAED,CAAC,IAAI,CAAC,EAAEA,CAAC,EAAE,EAAE;IAC1C,IAAID,QAAQ,CAACD,KAAK,CAACE,CAAC,CAAC,CAAC,EAAE;MACtB,OAAOA,CAAC;IACV;EACF;EAEA,OAAO,CAAC,CAAC;AACX","ignoreList":[]}
@@ -1,12 +0,0 @@
1
- "use strict";
2
-
3
- import * as React from 'react';
4
- import { GestureHandlerRefContext } from "./GestureHandlerRefContext.js";
5
- export function useGestureHandlerRef() {
6
- const ref = React.useContext(GestureHandlerRefContext);
7
- if (ref === undefined) {
8
- throw new Error("Couldn't find a ref for gesture handler. Are you inside a screen in Stack?");
9
- }
10
- return ref;
11
- }
12
- //# sourceMappingURL=useGestureHandlerRef.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["React","GestureHandlerRefContext","useGestureHandlerRef","ref","useContext","undefined","Error"],"sourceRoot":"../../../src","sources":["utils/useGestureHandlerRef.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAE9B,SAASC,wBAAwB,QAAQ,+BAA4B;AAErE,OAAO,SAASC,oBAAoBA,CAAA,EAAG;EACrC,MAAMC,GAAG,GAAGH,KAAK,CAACI,UAAU,CAACH,wBAAwB,CAAC;EAEtD,IAAIE,GAAG,KAAKE,SAAS,EAAE;IACrB,MAAM,IAAIC,KAAK,CACb,4EACF,CAAC;EACH;EAEA,OAAOH,GAAG;AACZ","ignoreList":[]}
@@ -1,43 +0,0 @@
1
- "use strict";
2
-
3
- import * as React from 'react';
4
- import { Platform, StyleSheet, View } from 'react-native';
5
- import { jsx as _jsx } from "react/jsx-runtime";
6
- export const CardA11yWrapper = /*#__PURE__*/React.forwardRef(({
7
- focused,
8
- active,
9
- animated,
10
- isNextScreenTransparent,
11
- detachCurrentScreen,
12
- children
13
- }, ref) => {
14
- // Manage this in separate component to avoid re-rendering card during gestures
15
- // Otherwise the gesture animation will be interrupted as state hasn't updated yet
16
- const [inert, setInert] = React.useState(false);
17
- React.useImperativeHandle(ref, () => ({
18
- setInert
19
- }), []);
20
- const isHidden = !animated && isNextScreenTransparent === false && detachCurrentScreen !== false && !focused;
21
- return /*#__PURE__*/_jsx(View, {
22
- "aria-hidden": !focused,
23
- style: [StyleSheet.absoluteFill, {
24
- pointerEvents: (animated ? inert : !focused) ? 'none' : 'box-none',
25
- // This is necessary to avoid unfocused larger pages increasing scroll area
26
- // The issue can be seen on the web when a smaller screen is pushed over a larger one
27
- overflow: active ? undefined : 'hidden',
28
- // We use visibility on web
29
- display: Platform.OS !== 'web' && isHidden ? 'none' : 'flex',
30
- // Hide unfocused screens when animation isn't enabled
31
- // This is also necessary for a11y on web
32
- // @ts-expect-error visibility is only available on web
33
- visibility: isHidden ? 'hidden' : 'visible'
34
- }]
35
- // Make sure this view is not removed on the new architecture, as it causes focus loss during navigation on Android.
36
- // This can happen when the view flattening results in different trees - due to `overflow` style changing in a parent.
37
- ,
38
- collapsable: false,
39
- children: children
40
- });
41
- });
42
- CardA11yWrapper.displayName = 'CardA11yWrapper';
43
- //# sourceMappingURL=CardA11yWrapper.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["React","Platform","StyleSheet","View","jsx","_jsx","CardA11yWrapper","forwardRef","focused","active","animated","isNextScreenTransparent","detachCurrentScreen","children","ref","inert","setInert","useState","useImperativeHandle","isHidden","style","absoluteFill","pointerEvents","overflow","undefined","display","OS","visibility","collapsable","displayName"],"sourceRoot":"../../../../src","sources":["views/Stack/CardA11yWrapper.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAC9B,SAASC,QAAQ,EAAEC,UAAU,EAAEC,IAAI,QAAQ,cAAc;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAa1D,OAAO,MAAMC,eAAe,gBAAGN,KAAK,CAACO,UAAU,CAC7C,CACE;EACEC,OAAO;EACPC,MAAM;EACNC,QAAQ;EACRC,uBAAuB;EACvBC,mBAAmB;EACnBC;AACK,CAAC,EACRC,GAAkC,KAC/B;EACH;EACA;EACA,MAAM,CAACC,KAAK,EAAEC,QAAQ,CAAC,GAAGhB,KAAK,CAACiB,QAAQ,CAAC,KAAK,CAAC;EAE/CjB,KAAK,CAACkB,mBAAmB,CAACJ,GAAG,EAAE,OAAO;IAAEE;EAAS,CAAC,CAAC,EAAE,EAAE,CAAC;EAExD,MAAMG,QAAQ,GACZ,CAACT,QAAQ,IACTC,uBAAuB,KAAK,KAAK,IACjCC,mBAAmB,KAAK,KAAK,IAC7B,CAACJ,OAAO;EAEV,oBACEH,IAAA,CAACF,IAAI;IACH,eAAa,CAACK,OAAQ;IACtBY,KAAK,EAAE,CACLlB,UAAU,CAACmB,YAAY,EACvB;MACEC,aAAa,EAAE,CAACZ,QAAQ,GAAGK,KAAK,GAAG,CAACP,OAAO,IAAI,MAAM,GAAG,UAAU;MAClE;MACA;MACAe,QAAQ,EAAEd,MAAM,GAAGe,SAAS,GAAG,QAAQ;MACvC;MACAC,OAAO,EAAExB,QAAQ,CAACyB,EAAE,KAAK,KAAK,IAAIP,QAAQ,GAAG,MAAM,GAAG,MAAM;MAC5D;MACA;MACA;MACAQ,UAAU,EAAER,QAAQ,GAAG,QAAQ,GAAG;IACpC,CAAC;IAEH;IACA;IAAA;IACAS,WAAW,EAAE,KAAM;IAAAf,QAAA,EAElBA;EAAQ,CACL,CAAC;AAEX,CACF,CAAC;AAEDP,eAAe,CAACuB,WAAW,GAAG,iBAAiB","ignoreList":[]}
@@ -1,3 +0,0 @@
1
- import * as React from 'react';
2
- export declare const GestureHandlerRefContext: React.Context<React.Ref<React.ComponentType<import("react-native-gesture-handler").PanGestureHandlerProps & React.RefAttributes<any>>>>;
3
- //# sourceMappingURL=GestureHandlerRefContext.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"GestureHandlerRefContext.d.ts","sourceRoot":"","sources":["../../../../src/utils/GestureHandlerRefContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,eAAO,MAAM,wBAAwB,yIAEtB,CAAC"}
@@ -1,2 +0,0 @@
1
- export declare function findLastIndex<T>(array: T[], callback: (value: T) => boolean): number;
2
- //# sourceMappingURL=findLastIndex.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"findLastIndex.d.ts","sourceRoot":"","sources":["../../../../src/utils/findLastIndex.tsx"],"names":[],"mappings":"AAAA,wBAAgB,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,UAQ3E"}
@@ -1,3 +0,0 @@
1
- import * as React from 'react';
2
- export declare function useGestureHandlerRef(): React.Ref<React.ComponentType<import("react-native-gesture-handler").PanGestureHandlerProps & React.RefAttributes<any>>>;
3
- //# sourceMappingURL=useGestureHandlerRef.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useGestureHandlerRef.d.ts","sourceRoot":"","sources":["../../../../src/utils/useGestureHandlerRef.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,wBAAgB,oBAAoB,6HAUnC"}
@@ -1,15 +0,0 @@
1
- import * as React from 'react';
2
- type Props = {
3
- focused: boolean;
4
- active: boolean;
5
- animated: boolean;
6
- isNextScreenTransparent: boolean;
7
- detachCurrentScreen: boolean;
8
- children: React.ReactNode;
9
- };
10
- export type CardA11yWrapperRef = {
11
- setInert: (value: boolean) => void;
12
- };
13
- export declare const CardA11yWrapper: React.ForwardRefExoticComponent<Props & React.RefAttributes<CardA11yWrapperRef>>;
14
- export {};
15
- //# sourceMappingURL=CardA11yWrapper.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"CardA11yWrapper.d.ts","sourceRoot":"","sources":["../../../../../src/views/Stack/CardA11yWrapper.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,KAAK,KAAK,GAAG;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,uBAAuB,EAAE,OAAO,CAAC;IACjC,mBAAmB,EAAE,OAAO,CAAC;IAC7B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;CAAE,CAAC;AAExE,eAAO,MAAM,eAAe,kFAkD3B,CAAC"}
@@ -1,5 +0,0 @@
1
- import * as React from 'react';
2
-
3
- export const GestureHandlerRefContext = React.createContext<React.Ref<
4
- import('react-native-gesture-handler').PanGestureHandler
5
- > | null>(null);
@@ -1,9 +0,0 @@
1
- export function findLastIndex<T>(array: T[], callback: (value: T) => boolean) {
2
- for (let i = array.length - 1; i >= 0; i--) {
3
- if (callback(array[i])) {
4
- return i;
5
- }
6
- }
7
-
8
- return -1;
9
- }
@@ -1,15 +0,0 @@
1
- import * as React from 'react';
2
-
3
- import { GestureHandlerRefContext } from './GestureHandlerRefContext';
4
-
5
- export function useGestureHandlerRef() {
6
- const ref = React.useContext(GestureHandlerRefContext);
7
-
8
- if (ref === undefined) {
9
- throw new Error(
10
- "Couldn't find a ref for gesture handler. Are you inside a screen in Stack?"
11
- );
12
- }
13
-
14
- return ref;
15
- }
@@ -1,67 +0,0 @@
1
- import * as React from 'react';
2
- import { Platform, StyleSheet, View } from 'react-native';
3
-
4
- type Props = {
5
- focused: boolean;
6
- active: boolean;
7
- animated: boolean;
8
- isNextScreenTransparent: boolean;
9
- detachCurrentScreen: boolean;
10
- children: React.ReactNode;
11
- };
12
-
13
- export type CardA11yWrapperRef = { setInert: (value: boolean) => void };
14
-
15
- export const CardA11yWrapper = React.forwardRef(
16
- (
17
- {
18
- focused,
19
- active,
20
- animated,
21
- isNextScreenTransparent,
22
- detachCurrentScreen,
23
- children,
24
- }: Props,
25
- ref: React.Ref<CardA11yWrapperRef>
26
- ) => {
27
- // Manage this in separate component to avoid re-rendering card during gestures
28
- // Otherwise the gesture animation will be interrupted as state hasn't updated yet
29
- const [inert, setInert] = React.useState(false);
30
-
31
- React.useImperativeHandle(ref, () => ({ setInert }), []);
32
-
33
- const isHidden =
34
- !animated &&
35
- isNextScreenTransparent === false &&
36
- detachCurrentScreen !== false &&
37
- !focused;
38
-
39
- return (
40
- <View
41
- aria-hidden={!focused}
42
- style={[
43
- StyleSheet.absoluteFill,
44
- {
45
- pointerEvents: (animated ? inert : !focused) ? 'none' : 'box-none',
46
- // This is necessary to avoid unfocused larger pages increasing scroll area
47
- // The issue can be seen on the web when a smaller screen is pushed over a larger one
48
- overflow: active ? undefined : 'hidden',
49
- // We use visibility on web
50
- display: Platform.OS !== 'web' && isHidden ? 'none' : 'flex',
51
- // Hide unfocused screens when animation isn't enabled
52
- // This is also necessary for a11y on web
53
- // @ts-expect-error visibility is only available on web
54
- visibility: isHidden ? 'hidden' : 'visible',
55
- },
56
- ]}
57
- // Make sure this view is not removed on the new architecture, as it causes focus loss during navigation on Android.
58
- // This can happen when the view flattening results in different trees - due to `overflow` style changing in a parent.
59
- collapsable={false}
60
- >
61
- {children}
62
- </View>
63
- );
64
- }
65
- );
66
-
67
- CardA11yWrapper.displayName = 'CardA11yWrapper';