@react-navigation/stack 8.0.0-alpha.11 → 8.0.0-alpha.13
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.
- package/lib/module/views/Stack/Card.js +25 -20
- package/lib/module/views/Stack/Card.js.map +1 -1
- package/lib/module/views/Stack/CardA11yWrapper.js +1 -2
- package/lib/module/views/Stack/CardA11yWrapper.js.map +1 -1
- package/lib/module/views/Stack/CardContainer.js +3 -4
- package/lib/module/views/Stack/CardContainer.js.map +1 -1
- package/lib/module/views/Stack/CardStack.js +56 -117
- package/lib/module/views/Stack/CardStack.js.map +1 -1
- package/lib/module/views/Stack/StackView.js +18 -14
- package/lib/module/views/Stack/StackView.js.map +1 -1
- package/lib/typescript/src/types.d.ts +20 -42
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/utils/gestureActivationCriteria.d.ts +1 -1
- package/lib/typescript/src/utils/gestureActivationCriteria.d.ts.map +1 -1
- package/lib/typescript/src/views/Header/HeaderSegment.d.ts +2 -2
- package/lib/typescript/src/views/Header/HeaderSegment.d.ts.map +1 -1
- package/lib/typescript/src/views/Stack/Card.d.ts +3 -3
- package/lib/typescript/src/views/Stack/Card.d.ts.map +1 -1
- package/lib/typescript/src/views/Stack/CardA11yWrapper.d.ts +0 -1
- package/lib/typescript/src/views/Stack/CardA11yWrapper.d.ts.map +1 -1
- package/lib/typescript/src/views/Stack/CardContainer.d.ts +2 -2
- package/lib/typescript/src/views/Stack/CardContainer.d.ts.map +1 -1
- package/lib/typescript/src/views/Stack/CardStack.d.ts +1 -1
- package/lib/typescript/src/views/Stack/CardStack.d.ts.map +1 -1
- package/lib/typescript/src/views/Stack/StackView.d.ts +5 -15
- package/lib/typescript/src/views/Stack/StackView.d.ts.map +1 -1
- package/package.json +13 -13
- package/src/types.tsx +46 -61
- package/src/utils/gestureActivationCriteria.tsx +1 -1
- package/src/views/Header/HeaderSegment.tsx +2 -2
- package/src/views/Stack/Card.tsx +32 -23
- package/src/views/Stack/CardA11yWrapper.tsx +2 -14
- package/src/views/Stack/CardContainer.tsx +3 -4
- package/src/views/Stack/CardStack.tsx +82 -153
- package/src/views/Stack/StackView.tsx +34 -17
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { getDefaultHeaderHeight } from '@react-navigation/elements';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
ActivityView,
|
|
4
|
+
SafeAreaProviderCompat,
|
|
5
|
+
} from '@react-navigation/elements/internal';
|
|
3
6
|
import type {
|
|
4
7
|
LocaleDirection,
|
|
5
8
|
ParamListBase,
|
|
@@ -15,7 +18,6 @@ import {
|
|
|
15
18
|
View,
|
|
16
19
|
} from 'react-native';
|
|
17
20
|
import type { EdgeInsets } from 'react-native-safe-area-context';
|
|
18
|
-
import { Screen, ScreenContainer } from 'react-native-screens';
|
|
19
21
|
|
|
20
22
|
import {
|
|
21
23
|
forModalPresentationIOS,
|
|
@@ -44,7 +46,6 @@ import type {
|
|
|
44
46
|
StackNavigationOptions,
|
|
45
47
|
TransitionPreset,
|
|
46
48
|
} from '../../types';
|
|
47
|
-
import { findLastIndex } from '../../utils/findLastIndex';
|
|
48
49
|
import { getDistanceForDirection } from '../../utils/getDistanceForDirection';
|
|
49
50
|
import { getModalRouteKeys } from '../../utils/getModalRoutesKeys';
|
|
50
51
|
import type { Props as HeaderContainerProps } from '../Header/HeaderContainer';
|
|
@@ -62,6 +63,7 @@ type Props = {
|
|
|
62
63
|
routes: Route<string>[];
|
|
63
64
|
openingRouteKeys: string[];
|
|
64
65
|
closingRouteKeys: string[];
|
|
66
|
+
replacingRouteKeys: string[];
|
|
65
67
|
onOpenRoute: (props: { route: Route<string> }) => void;
|
|
66
68
|
onCloseRoute: (props: { route: Route<string> }) => void;
|
|
67
69
|
getPreviousRoute: (props: {
|
|
@@ -87,7 +89,6 @@ type State = {
|
|
|
87
89
|
scenes: Scene[];
|
|
88
90
|
gestures: GestureValues;
|
|
89
91
|
layout: Layout;
|
|
90
|
-
activeStates: (0 | 1 | Animated.AnimatedInterpolation<0 | 1>)[];
|
|
91
92
|
headerHeights: Record<string, number>;
|
|
92
93
|
};
|
|
93
94
|
|
|
@@ -107,12 +108,6 @@ const NAMED_TRANSITIONS_PRESETS = {
|
|
|
107
108
|
}),
|
|
108
109
|
} as const satisfies Record<StackAnimationName, TransitionPreset>;
|
|
109
110
|
|
|
110
|
-
const EPSILON = 1e-5;
|
|
111
|
-
|
|
112
|
-
const STATE_INACTIVE = 0;
|
|
113
|
-
const STATE_TRANSITIONING_OR_BELOW_TOP = 1;
|
|
114
|
-
const STATE_ON_TOP = 2;
|
|
115
|
-
|
|
116
111
|
const FALLBACK_DESCRIPTOR = Object.freeze({ options: {} });
|
|
117
112
|
|
|
118
113
|
const getInterpolationIndex = (scenes: Scene[], index: number) => {
|
|
@@ -465,88 +460,11 @@ export class CardStack extends React.Component<Props, State> {
|
|
|
465
460
|
}
|
|
466
461
|
);
|
|
467
462
|
|
|
468
|
-
let activeStates = state.activeStates;
|
|
469
|
-
|
|
470
|
-
if (props.routes.length !== state.routes.length) {
|
|
471
|
-
let activeScreensLimit = 1;
|
|
472
|
-
|
|
473
|
-
for (let i = props.routes.length - 1; i >= 0; i--) {
|
|
474
|
-
const { options } = scenes[i].descriptor;
|
|
475
|
-
|
|
476
|
-
const {
|
|
477
|
-
// By default, we don't want to detach the previous screen of the active one for modals
|
|
478
|
-
detachPreviousScreen = options.presentation === 'transparentModal'
|
|
479
|
-
? false
|
|
480
|
-
: getIsModalPresentation(options.cardStyleInterpolator)
|
|
481
|
-
? i !==
|
|
482
|
-
findLastIndex(scenes, (scene) => {
|
|
483
|
-
const { cardStyleInterpolator } = scene.descriptor.options;
|
|
484
|
-
|
|
485
|
-
return (
|
|
486
|
-
cardStyleInterpolator === forModalPresentationIOS ||
|
|
487
|
-
cardStyleInterpolator?.name === 'forModalPresentationIOS'
|
|
488
|
-
);
|
|
489
|
-
})
|
|
490
|
-
: true,
|
|
491
|
-
} = options;
|
|
492
|
-
|
|
493
|
-
if (detachPreviousScreen === false) {
|
|
494
|
-
activeScreensLimit++;
|
|
495
|
-
} else {
|
|
496
|
-
// Check at least last 2 screens before stopping
|
|
497
|
-
// This will make sure that screen isn't detached when another screen is animating on top of the transparent one
|
|
498
|
-
// e.g. opaque -> transparent -> opaque
|
|
499
|
-
if (i <= props.routes.length - 2) {
|
|
500
|
-
break;
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
activeStates = props.routes.map((_, index, self) => {
|
|
506
|
-
// The activity state represents state of the screen:
|
|
507
|
-
// 0 - inactive, the screen is detached
|
|
508
|
-
// 1 - transitioning or below the top screen, the screen is mounted but interaction is disabled
|
|
509
|
-
// 2 - on top of the stack, the screen is mounted and interaction is enabled
|
|
510
|
-
let activityState:
|
|
511
|
-
| Animated.AnimatedInterpolation<0 | 1 | 2>
|
|
512
|
-
| 0
|
|
513
|
-
| 1
|
|
514
|
-
| 2;
|
|
515
|
-
|
|
516
|
-
const lastActiveState = state.activeStates[index];
|
|
517
|
-
const activeAfterTransition = index >= self.length - activeScreensLimit;
|
|
518
|
-
|
|
519
|
-
if (lastActiveState === STATE_INACTIVE && !activeAfterTransition) {
|
|
520
|
-
// screen was inactive before and it will still be inactive after the transition
|
|
521
|
-
activityState = STATE_INACTIVE;
|
|
522
|
-
} else {
|
|
523
|
-
const sceneForActivity = scenes[self.length - 1];
|
|
524
|
-
const outputValue =
|
|
525
|
-
index === self.length - 1
|
|
526
|
-
? STATE_ON_TOP // the screen is on top after the transition
|
|
527
|
-
: activeAfterTransition
|
|
528
|
-
? STATE_TRANSITIONING_OR_BELOW_TOP // the screen should stay active after the transition, it is not on top but is in activeLimit
|
|
529
|
-
: STATE_INACTIVE; // the screen should be active only during the transition, it is at the edge of activeLimit
|
|
530
|
-
|
|
531
|
-
activityState = sceneForActivity
|
|
532
|
-
? sceneForActivity.progress.current.interpolate({
|
|
533
|
-
inputRange: [0, 1 - EPSILON, 1],
|
|
534
|
-
outputRange: [1, 1, outputValue],
|
|
535
|
-
extrapolate: 'clamp',
|
|
536
|
-
})
|
|
537
|
-
: STATE_TRANSITIONING_OR_BELOW_TOP;
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
return activityState;
|
|
541
|
-
});
|
|
542
|
-
}
|
|
543
|
-
|
|
544
463
|
return {
|
|
545
464
|
routes: props.routes,
|
|
546
465
|
scenes,
|
|
547
466
|
gestures,
|
|
548
467
|
descriptors: props.descriptors,
|
|
549
|
-
activeStates,
|
|
550
468
|
headerHeights: getHeaderHeights(
|
|
551
469
|
scenes,
|
|
552
470
|
props.insets,
|
|
@@ -567,7 +485,6 @@ export class CardStack extends React.Component<Props, State> {
|
|
|
567
485
|
gestures: {},
|
|
568
486
|
layout: SafeAreaProviderCompat.initialMetrics.frame,
|
|
569
487
|
descriptors: this.props.descriptors,
|
|
570
|
-
activeStates: [],
|
|
571
488
|
// Used when card's header is null and mode is float to make transition
|
|
572
489
|
// between screens with headers and those without headers smooth.
|
|
573
490
|
// This is not a great heuristic here. We don't know synchronously
|
|
@@ -654,23 +571,20 @@ export class CardStack extends React.Component<Props, State> {
|
|
|
654
571
|
routes,
|
|
655
572
|
openingRouteKeys,
|
|
656
573
|
closingRouteKeys,
|
|
574
|
+
replacingRouteKeys,
|
|
657
575
|
onOpenRoute,
|
|
658
576
|
onCloseRoute,
|
|
577
|
+
onGestureStart,
|
|
578
|
+
onGestureEnd,
|
|
579
|
+
onGestureCancel,
|
|
659
580
|
renderHeader,
|
|
660
581
|
isParentHeaderShown,
|
|
661
582
|
isParentModal,
|
|
662
583
|
onTransitionStart,
|
|
663
584
|
onTransitionEnd,
|
|
664
|
-
onGestureStart,
|
|
665
|
-
onGestureEnd,
|
|
666
|
-
onGestureCancel,
|
|
667
|
-
detachInactiveScreens = Platform.OS === 'web' ||
|
|
668
|
-
Platform.OS === 'android' ||
|
|
669
|
-
Platform.OS === 'ios',
|
|
670
585
|
} = this.props;
|
|
671
586
|
|
|
672
|
-
const { scenes, layout, gestures,
|
|
673
|
-
this.state;
|
|
587
|
+
const { scenes, layout, gestures, headerHeights } = this.state;
|
|
674
588
|
|
|
675
589
|
const focusedRoute = state.routes[state.index];
|
|
676
590
|
|
|
@@ -712,12 +626,8 @@ export class CardStack extends React.Component<Props, State> {
|
|
|
712
626
|
],
|
|
713
627
|
],
|
|
714
628
|
})}
|
|
715
|
-
<
|
|
716
|
-
|
|
717
|
-
style={styles.container}
|
|
718
|
-
onLayout={this.handleLayout}
|
|
719
|
-
>
|
|
720
|
-
{[...routes, ...state.preloadedRoutes].map((route, index) => {
|
|
629
|
+
<View style={styles.container} onLayout={this.handleLayout}>
|
|
630
|
+
{[...routes, ...state.preloadedRoutes].map((route, index, self) => {
|
|
721
631
|
const focused = focusedRoute.key === route.key;
|
|
722
632
|
const gesture = gestures[route.key];
|
|
723
633
|
const scene = scenes[index];
|
|
@@ -736,10 +646,9 @@ export class CardStack extends React.Component<Props, State> {
|
|
|
736
646
|
}
|
|
737
647
|
|
|
738
648
|
const {
|
|
649
|
+
inactiveBehavior = 'pause',
|
|
739
650
|
headerShown = true,
|
|
740
651
|
headerTransparent,
|
|
741
|
-
freezeOnBlur,
|
|
742
|
-
autoHideHomeIndicator,
|
|
743
652
|
} = scene.descriptor.options;
|
|
744
653
|
|
|
745
654
|
const safeAreaInsetTop = insets.top;
|
|
@@ -762,63 +671,83 @@ export class CardStack extends React.Component<Props, State> {
|
|
|
762
671
|
scenes[index + 1]?.descriptor.options.presentation ===
|
|
763
672
|
'transparentModal';
|
|
764
673
|
|
|
765
|
-
const
|
|
766
|
-
|
|
767
|
-
|
|
674
|
+
const isRemoving =
|
|
675
|
+
replacingRouteKeys.includes(route.key) ||
|
|
676
|
+
closingRouteKeys.includes(route.key);
|
|
768
677
|
|
|
769
|
-
const
|
|
770
|
-
|
|
771
|
-
|
|
678
|
+
const isFocusing =
|
|
679
|
+
openingRouteKeys.includes(route.key) ||
|
|
680
|
+
[...closingRouteKeys, ...replacingRouteKeys].includes(
|
|
681
|
+
self[index + 1]?.key
|
|
682
|
+
);
|
|
772
683
|
|
|
773
684
|
return (
|
|
774
|
-
<
|
|
685
|
+
<CardContainer
|
|
775
686
|
key={route.key}
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
687
|
+
index={index}
|
|
688
|
+
interpolationIndex={interpolationIndex}
|
|
689
|
+
modal={isModal}
|
|
690
|
+
active={index === routes.length - 1}
|
|
691
|
+
focused={focused}
|
|
692
|
+
opening={openingRouteKeys.includes(route.key)}
|
|
693
|
+
closing={closingRouteKeys.includes(route.key)}
|
|
694
|
+
layout={layout}
|
|
695
|
+
gesture={gesture}
|
|
696
|
+
scene={scene}
|
|
697
|
+
safeAreaInsetTop={safeAreaInsetTop}
|
|
698
|
+
safeAreaInsetRight={safeAreaInsetRight}
|
|
699
|
+
safeAreaInsetBottom={safeAreaInsetBottom}
|
|
700
|
+
safeAreaInsetLeft={safeAreaInsetLeft}
|
|
701
|
+
onGestureStart={onGestureStart}
|
|
702
|
+
onGestureCancel={onGestureCancel}
|
|
703
|
+
onGestureEnd={onGestureEnd}
|
|
704
|
+
headerHeight={headerHeight}
|
|
705
|
+
isParentHeaderShown={isParentHeaderShown}
|
|
706
|
+
onHeaderHeightChange={this.handleHeaderLayout}
|
|
707
|
+
getPreviousScene={this.getPreviousScene}
|
|
708
|
+
getFocusedRoute={this.getFocusedRoute}
|
|
709
|
+
hasAbsoluteFloatHeader={
|
|
710
|
+
isFloatHeaderAbsolute && !headerTransparent
|
|
711
|
+
}
|
|
712
|
+
renderHeader={renderHeader}
|
|
713
|
+
onOpenRoute={onOpenRoute}
|
|
714
|
+
onCloseRoute={onCloseRoute}
|
|
715
|
+
onTransitionStart={onTransitionStart}
|
|
716
|
+
onTransitionEnd={onTransitionEnd}
|
|
717
|
+
isNextScreenTransparent={isNextScreenTransparent}
|
|
718
|
+
preloaded={isPreloaded}
|
|
782
719
|
>
|
|
783
|
-
<
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
getFocusedRoute={this.getFocusedRoute}
|
|
806
|
-
hasAbsoluteFloatHeader={
|
|
807
|
-
isFloatHeaderAbsolute && !headerTransparent
|
|
720
|
+
<ActivityView
|
|
721
|
+
mode={
|
|
722
|
+
// Render focused and animating screens normally
|
|
723
|
+
focused || isFocusing
|
|
724
|
+
? 'normal'
|
|
725
|
+
: // Unpause preloaded screens so updates are visible
|
|
726
|
+
// This lets preloaded screens initialize
|
|
727
|
+
// And avoids things like pressable animation from being frozen
|
|
728
|
+
inactiveBehavior === 'none' ||
|
|
729
|
+
isPreloaded ||
|
|
730
|
+
isRemoving ||
|
|
731
|
+
isNextScreenTransparent
|
|
732
|
+
? 'inert'
|
|
733
|
+
: 'paused'
|
|
734
|
+
}
|
|
735
|
+
visible={
|
|
736
|
+
// keep animating, preloaded & last two screens visible for smoother transitions
|
|
737
|
+
isFocusing ||
|
|
738
|
+
isRemoving ||
|
|
739
|
+
isPreloaded ||
|
|
740
|
+
isNextScreenTransparent ||
|
|
741
|
+
index >= routes.length - 2
|
|
808
742
|
}
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
isNextScreenTransparent={isNextScreenTransparent}
|
|
815
|
-
detachCurrentScreen={detachCurrentScreen}
|
|
816
|
-
preloaded={isPreloaded}
|
|
817
|
-
/>
|
|
818
|
-
</Screen>
|
|
743
|
+
style={StyleSheet.absoluteFill}
|
|
744
|
+
>
|
|
745
|
+
{scene.descriptor.render()}
|
|
746
|
+
</ActivityView>
|
|
747
|
+
</CardContainer>
|
|
819
748
|
);
|
|
820
749
|
})}
|
|
821
|
-
</
|
|
750
|
+
</View>
|
|
822
751
|
</View>
|
|
823
752
|
);
|
|
824
753
|
}
|
|
@@ -35,8 +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
|
|
39
|
-
|
|
38
|
+
// Previous navigation state for comparison
|
|
39
|
+
previousState: StackNavigationState<ParamListBase> | undefined;
|
|
40
40
|
// Previous descriptors, to compare whether descriptors have changed or not
|
|
41
41
|
previousDescriptors: StackDescriptorMap;
|
|
42
42
|
// List of routes being opened, we need to animate pushing of these new routes
|
|
@@ -65,12 +65,15 @@ export class StackView extends React.Component<Props, State> {
|
|
|
65
65
|
state: Readonly<State>
|
|
66
66
|
) {
|
|
67
67
|
const allRoutes = [...props.state.routes, ...props.state.preloadedRoutes];
|
|
68
|
+
const previousRoutes = state.previousState
|
|
69
|
+
? [...state.previousState.routes, ...state.previousState.preloadedRoutes]
|
|
70
|
+
: [];
|
|
68
71
|
|
|
69
72
|
// If there was no change in routes, we don't need to compute anything
|
|
70
73
|
if (
|
|
71
74
|
isArrayEqual(
|
|
72
75
|
allRoutes.map((r) => r.key),
|
|
73
|
-
|
|
76
|
+
previousRoutes.map((r) => r.key)
|
|
74
77
|
) &&
|
|
75
78
|
state.routes.length
|
|
76
79
|
) {
|
|
@@ -103,7 +106,6 @@ export class StackView extends React.Component<Props, State> {
|
|
|
103
106
|
routes.push(...closingRoutes);
|
|
104
107
|
}
|
|
105
108
|
|
|
106
|
-
let previousRoutes = state.previousRoutes;
|
|
107
109
|
let descriptors = props.descriptors;
|
|
108
110
|
let previousDescriptors = state.previousDescriptors;
|
|
109
111
|
|
|
@@ -118,7 +120,7 @@ export class StackView extends React.Component<Props, State> {
|
|
|
118
120
|
previousDescriptors = props.descriptors;
|
|
119
121
|
}
|
|
120
122
|
|
|
121
|
-
if (!isArrayEqual(allRoutes,
|
|
123
|
+
if (!isArrayEqual(allRoutes, previousRoutes)) {
|
|
122
124
|
// if any route objects have changed, we should update them
|
|
123
125
|
const map = allRoutes.reduce<Record<string, Route<string>>>(
|
|
124
126
|
(acc, route) => {
|
|
@@ -129,12 +131,11 @@ export class StackView extends React.Component<Props, State> {
|
|
|
129
131
|
);
|
|
130
132
|
|
|
131
133
|
routes = routes.map((route) => map[route.key] || route);
|
|
132
|
-
previousRoutes = allRoutes;
|
|
133
134
|
}
|
|
134
135
|
|
|
135
136
|
return {
|
|
136
137
|
routes,
|
|
137
|
-
|
|
138
|
+
previousState: props.state,
|
|
138
139
|
descriptors,
|
|
139
140
|
previousDescriptors,
|
|
140
141
|
};
|
|
@@ -150,14 +151,24 @@ export class StackView extends React.Component<Props, State> {
|
|
|
150
151
|
props.state.routes.slice(0, props.state.index + 1)
|
|
151
152
|
: props.state.routes;
|
|
152
153
|
|
|
153
|
-
// Now we need to determine which routes were added and removed
|
|
154
|
-
const { previousRoutes } = state;
|
|
155
|
-
|
|
156
154
|
let { openingRouteKeys, closingRouteKeys, replacingRouteKeys } = state;
|
|
157
155
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
156
|
+
// If a route that was closing or being replaced is now back in the routes,
|
|
157
|
+
// it was added back before the animation finished, so stop tracking it
|
|
158
|
+
closingRouteKeys = closingRouteKeys.filter(
|
|
159
|
+
(key) => !routes.some((r) => r.key === key)
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
replacingRouteKeys = replacingRouteKeys.filter(
|
|
163
|
+
(key) => !routes.some((r) => r.key === key)
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
// Get previous focused route from previousState (actual focused route, not last in previousRoutes
|
|
167
|
+
// which can be a preloaded route that was never focused)
|
|
168
|
+
const previousFocusedRoute = state.previousState
|
|
169
|
+
? state.previousState.routes[state.previousState.index]
|
|
170
|
+
: undefined;
|
|
171
|
+
|
|
161
172
|
const nextFocusedRoute = routes[routes.length - 1];
|
|
162
173
|
|
|
163
174
|
const isAnimationEnabled = (key: string) => {
|
|
@@ -306,7 +317,7 @@ export class StackView extends React.Component<Props, State> {
|
|
|
306
317
|
|
|
307
318
|
return {
|
|
308
319
|
routes,
|
|
309
|
-
|
|
320
|
+
previousState: props.state,
|
|
310
321
|
previousDescriptors: props.descriptors,
|
|
311
322
|
openingRouteKeys,
|
|
312
323
|
closingRouteKeys,
|
|
@@ -317,7 +328,7 @@ export class StackView extends React.Component<Props, State> {
|
|
|
317
328
|
|
|
318
329
|
state: State = {
|
|
319
330
|
routes: [],
|
|
320
|
-
|
|
331
|
+
previousState: undefined,
|
|
321
332
|
previousDescriptors: {},
|
|
322
333
|
openingRouteKeys: [],
|
|
323
334
|
closingRouteKeys: [],
|
|
@@ -475,8 +486,13 @@ export class StackView extends React.Component<Props, State> {
|
|
|
475
486
|
...rest
|
|
476
487
|
} = this.props;
|
|
477
488
|
|
|
478
|
-
const {
|
|
479
|
-
|
|
489
|
+
const {
|
|
490
|
+
routes,
|
|
491
|
+
descriptors,
|
|
492
|
+
openingRouteKeys,
|
|
493
|
+
closingRouteKeys,
|
|
494
|
+
replacingRouteKeys,
|
|
495
|
+
} = this.state;
|
|
480
496
|
|
|
481
497
|
return (
|
|
482
498
|
<GestureHandlerWrapper style={styles.container}>
|
|
@@ -495,6 +511,7 @@ export class StackView extends React.Component<Props, State> {
|
|
|
495
511
|
routes={routes}
|
|
496
512
|
openingRouteKeys={openingRouteKeys}
|
|
497
513
|
closingRouteKeys={closingRouteKeys}
|
|
514
|
+
replacingRouteKeys={replacingRouteKeys}
|
|
498
515
|
onOpenRoute={this.handleOpenRoute}
|
|
499
516
|
onCloseRoute={this.handleCloseRoute}
|
|
500
517
|
onTransitionStart={this.handleTransitionStart}
|