@react-navigation/stack 7.0.0-alpha.7 → 7.0.0-alpha.9
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/commonjs/TransitionConfigs/CardStyleInterpolators.js.map +1 -1
- package/lib/commonjs/TransitionConfigs/TransitionPresets.js.map +1 -1
- package/lib/commonjs/navigators/createStackNavigator.js +4 -0
- package/lib/commonjs/navigators/createStackNavigator.js.map +1 -1
- package/lib/commonjs/views/Header/Header.js.map +1 -1
- package/lib/commonjs/views/Header/HeaderContainer.js +1 -1
- package/lib/commonjs/views/Header/HeaderContainer.js.map +1 -1
- package/lib/commonjs/views/Screens.js.map +1 -1
- package/lib/commonjs/views/Stack/Card.js +17 -9
- package/lib/commonjs/views/Stack/Card.js.map +1 -1
- package/lib/commonjs/views/Stack/CardContainer.js +4 -5
- package/lib/commonjs/views/Stack/CardContainer.js.map +1 -1
- package/lib/commonjs/views/Stack/CardStack.js +32 -21
- package/lib/commonjs/views/Stack/CardStack.js.map +1 -1
- package/lib/commonjs/views/Stack/StackView.js +20 -26
- package/lib/commonjs/views/Stack/StackView.js.map +1 -1
- package/lib/module/TransitionConfigs/CardStyleInterpolators.js.map +1 -1
- package/lib/module/TransitionConfigs/TransitionPresets.js.map +1 -1
- package/lib/module/navigators/createStackNavigator.js +4 -0
- package/lib/module/navigators/createStackNavigator.js.map +1 -1
- package/lib/module/views/Header/Header.js.map +1 -1
- package/lib/module/views/Header/HeaderContainer.js +2 -2
- package/lib/module/views/Header/HeaderContainer.js.map +1 -1
- package/lib/module/views/Screens.js.map +1 -1
- package/lib/module/views/Stack/Card.js +17 -9
- package/lib/module/views/Stack/Card.js.map +1 -1
- package/lib/module/views/Stack/CardContainer.js +5 -6
- package/lib/module/views/Stack/CardContainer.js.map +1 -1
- package/lib/module/views/Stack/CardStack.js +32 -21
- package/lib/module/views/Stack/CardStack.js.map +1 -1
- package/lib/module/views/Stack/StackView.js +20 -26
- package/lib/module/views/Stack/StackView.js.map +1 -1
- package/lib/typescript/src/navigators/createStackNavigator.d.ts +1 -1
- package/lib/typescript/src/navigators/createStackNavigator.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +33 -3
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/views/Screens.d.ts +1 -0
- package/lib/typescript/src/views/Screens.d.ts.map +1 -1
- package/lib/typescript/src/views/Stack/Card.d.ts +1 -0
- package/lib/typescript/src/views/Stack/Card.d.ts.map +1 -1
- package/lib/typescript/src/views/Stack/CardContainer.d.ts +2 -4
- package/lib/typescript/src/views/Stack/CardContainer.d.ts.map +1 -1
- package/lib/typescript/src/views/Stack/CardStack.d.ts +1 -3
- package/lib/typescript/src/views/Stack/CardStack.d.ts.map +1 -1
- package/lib/typescript/src/views/Stack/StackView.d.ts +5 -77
- package/lib/typescript/src/views/Stack/StackView.d.ts.map +1 -1
- package/package.json +18 -18
- package/src/TransitionConfigs/CardStyleInterpolators.tsx +5 -5
- package/src/TransitionConfigs/TransitionPresets.tsx +2 -2
- package/src/navigators/createStackNavigator.tsx +4 -1
- package/src/types.tsx +34 -3
- package/src/views/Header/Header.tsx +2 -2
- package/src/views/Header/HeaderContainer.tsx +4 -4
- package/src/views/Screens.tsx +1 -0
- package/src/views/Stack/Card.tsx +32 -15
- package/src/views/Stack/CardContainer.tsx +6 -5
- package/src/views/Stack/CardStack.tsx +190 -161
- package/src/views/Stack/StackView.tsx +13 -12
|
@@ -52,6 +52,8 @@ type Props = {
|
|
|
52
52
|
insets: EdgeInsets;
|
|
53
53
|
state: StackNavigationState<ParamListBase>;
|
|
54
54
|
descriptors: StackDescriptorMap;
|
|
55
|
+
// eslint-disable-next-line react/no-unused-prop-types
|
|
56
|
+
preloadedDescriptors: StackDescriptorMap;
|
|
55
57
|
routes: Route<string>[];
|
|
56
58
|
// eslint-disable-next-line react/no-unused-prop-types
|
|
57
59
|
openingRouteKeys: string[];
|
|
@@ -62,7 +64,6 @@ type Props = {
|
|
|
62
64
|
route: Route<string>;
|
|
63
65
|
}) => Route<string> | undefined;
|
|
64
66
|
renderHeader: (props: HeaderContainerProps) => React.ReactNode;
|
|
65
|
-
renderScene: (props: { route: Route<string> }) => React.ReactNode;
|
|
66
67
|
isParentHeaderShown: boolean;
|
|
67
68
|
isParentModal: boolean;
|
|
68
69
|
onTransitionStart: (
|
|
@@ -174,7 +175,7 @@ const getHeaderHeights = (
|
|
|
174
175
|
|
|
175
176
|
const getDistanceFromOptions = (
|
|
176
177
|
layout: Layout,
|
|
177
|
-
descriptor: StackDescriptor,
|
|
178
|
+
descriptor: StackDescriptor | undefined,
|
|
178
179
|
isRTL: boolean
|
|
179
180
|
) => {
|
|
180
181
|
const {
|
|
@@ -190,7 +191,7 @@ const getDistanceFromOptions = (
|
|
|
190
191
|
const getProgressFromGesture = (
|
|
191
192
|
gesture: Animated.Value,
|
|
192
193
|
layout: Layout,
|
|
193
|
-
descriptor: StackDescriptor,
|
|
194
|
+
descriptor: StackDescriptor | undefined,
|
|
194
195
|
isRTL: boolean
|
|
195
196
|
) => {
|
|
196
197
|
const distance = getDistanceFromOptions(
|
|
@@ -229,15 +230,20 @@ export class CardStack extends React.Component<Props, State> {
|
|
|
229
230
|
return null;
|
|
230
231
|
}
|
|
231
232
|
|
|
232
|
-
const gestures =
|
|
233
|
-
|
|
233
|
+
const gestures = [
|
|
234
|
+
...props.routes,
|
|
235
|
+
...props.state.preloadedRoutes,
|
|
236
|
+
].reduce<GestureValues>((acc, curr) => {
|
|
237
|
+
const descriptor =
|
|
238
|
+
props.descriptors[curr.key] || props.preloadedDescriptors[curr.key];
|
|
234
239
|
const { animationEnabled } = descriptor?.options || {};
|
|
235
240
|
|
|
236
241
|
acc[curr.key] =
|
|
237
242
|
state.gestures[curr.key] ||
|
|
238
243
|
new Animated.Value(
|
|
239
|
-
props.openingRouteKeys.includes(curr.key) &&
|
|
240
|
-
|
|
244
|
+
(props.openingRouteKeys.includes(curr.key) &&
|
|
245
|
+
animationEnabled !== false) ||
|
|
246
|
+
props.state.preloadedRoutes.includes(curr)
|
|
241
247
|
? getDistanceFromOptions(
|
|
242
248
|
state.layout,
|
|
243
249
|
descriptor,
|
|
@@ -249,147 +255,156 @@ export class CardStack extends React.Component<Props, State> {
|
|
|
249
255
|
return acc;
|
|
250
256
|
}, {});
|
|
251
257
|
|
|
252
|
-
const scenes = props.routes.map(
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
optionsForTransitionConfig
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
258
|
+
const scenes = [...props.routes, ...props.state.preloadedRoutes].map(
|
|
259
|
+
(route, index, self) => {
|
|
260
|
+
// For preloaded screens, we don't care about the previous and the next screen
|
|
261
|
+
const isPreloaded = props.state.preloadedRoutes.includes(route);
|
|
262
|
+
const previousRoute = isPreloaded ? undefined : self[index - 1];
|
|
263
|
+
const nextRoute = isPreloaded ? undefined : self[index + 1];
|
|
264
|
+
|
|
265
|
+
const oldScene = state.scenes[index];
|
|
266
|
+
|
|
267
|
+
const currentGesture = gestures[route.key];
|
|
268
|
+
const previousGesture = previousRoute
|
|
269
|
+
? gestures[previousRoute.key]
|
|
270
|
+
: undefined;
|
|
271
|
+
const nextGesture = nextRoute ? gestures[nextRoute.key] : undefined;
|
|
272
|
+
|
|
273
|
+
const descriptor =
|
|
274
|
+
(isPreloaded ? props.preloadedDescriptors : props.descriptors)[
|
|
275
|
+
route.key
|
|
276
|
+
] ||
|
|
277
|
+
state.descriptors[route.key] ||
|
|
278
|
+
(oldScene ? oldScene.descriptor : FALLBACK_DESCRIPTOR);
|
|
279
|
+
|
|
280
|
+
const nextDescriptor =
|
|
281
|
+
nextRoute &&
|
|
282
|
+
(props.descriptors[nextRoute?.key] ||
|
|
283
|
+
state.descriptors[nextRoute?.key]);
|
|
284
|
+
|
|
285
|
+
const previousDescriptor =
|
|
286
|
+
previousRoute &&
|
|
287
|
+
(props.descriptors[previousRoute?.key] ||
|
|
288
|
+
state.descriptors[previousRoute?.key]);
|
|
289
|
+
|
|
290
|
+
// When a screen is not the last, it should use next screen's transition config
|
|
291
|
+
// Many transitions also animate the previous screen, so using 2 different transitions doesn't look right
|
|
292
|
+
// For example combining a slide and a modal transition would look wrong otherwise
|
|
293
|
+
// With this approach, combining different transition styles in the same navigator mostly looks right
|
|
294
|
+
// This will still be broken when 2 transitions have different idle state (e.g. modal presentation),
|
|
295
|
+
// but the majority of the transitions look alright
|
|
296
|
+
const optionsForTransitionConfig =
|
|
297
|
+
index !== self.length - 1 &&
|
|
298
|
+
nextDescriptor &&
|
|
299
|
+
nextDescriptor.options.presentation !== 'transparentModal'
|
|
300
|
+
? nextDescriptor.options
|
|
301
|
+
: descriptor.options;
|
|
302
|
+
|
|
303
|
+
const defaultTransitionPreset =
|
|
304
|
+
optionsForTransitionConfig.presentation === 'modal'
|
|
305
|
+
? ModalTransition
|
|
306
|
+
: optionsForTransitionConfig.presentation === 'transparentModal'
|
|
307
|
+
? ModalFadeTransition
|
|
308
|
+
: DefaultTransition;
|
|
309
|
+
|
|
310
|
+
const {
|
|
311
|
+
animationEnabled = Platform.OS !== 'web' &&
|
|
312
|
+
Platform.OS !== 'windows' &&
|
|
313
|
+
Platform.OS !== 'macos',
|
|
314
|
+
gestureEnabled = Platform.OS === 'ios' && animationEnabled,
|
|
315
|
+
gestureDirection = defaultTransitionPreset.gestureDirection,
|
|
316
|
+
transitionSpec = defaultTransitionPreset.transitionSpec,
|
|
317
|
+
cardStyleInterpolator = animationEnabled === false
|
|
318
|
+
? forNoAnimationCard
|
|
319
|
+
: defaultTransitionPreset.cardStyleInterpolator,
|
|
320
|
+
headerStyleInterpolator = defaultTransitionPreset.headerStyleInterpolator,
|
|
321
|
+
cardOverlayEnabled = (Platform.OS !== 'ios' &&
|
|
322
|
+
optionsForTransitionConfig.presentation !== 'transparentModal') ||
|
|
323
|
+
getIsModalPresentation(cardStyleInterpolator),
|
|
324
|
+
} = optionsForTransitionConfig;
|
|
325
|
+
|
|
326
|
+
const headerMode: StackHeaderMode =
|
|
327
|
+
descriptor.options.headerMode ??
|
|
328
|
+
(!(
|
|
329
|
+
optionsForTransitionConfig.presentation === 'modal' ||
|
|
330
|
+
optionsForTransitionConfig.presentation === 'transparentModal' ||
|
|
331
|
+
nextDescriptor?.options.presentation === 'modal' ||
|
|
332
|
+
nextDescriptor?.options.presentation === 'transparentModal' ||
|
|
333
|
+
getIsModalPresentation(cardStyleInterpolator)
|
|
334
|
+
) &&
|
|
335
|
+
Platform.OS === 'ios' &&
|
|
336
|
+
descriptor.options.header === undefined
|
|
337
|
+
? 'float'
|
|
338
|
+
: 'screen');
|
|
339
|
+
|
|
340
|
+
const isRTL = props.direction === 'rtl';
|
|
341
|
+
|
|
342
|
+
const scene = {
|
|
343
|
+
route,
|
|
344
|
+
descriptor: {
|
|
345
|
+
...descriptor,
|
|
346
|
+
options: {
|
|
347
|
+
...descriptor.options,
|
|
348
|
+
animationEnabled,
|
|
349
|
+
cardOverlayEnabled,
|
|
350
|
+
cardStyleInterpolator,
|
|
351
|
+
gestureDirection,
|
|
352
|
+
gestureEnabled,
|
|
353
|
+
headerStyleInterpolator,
|
|
354
|
+
transitionSpec,
|
|
355
|
+
headerMode,
|
|
356
|
+
},
|
|
342
357
|
},
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
358
|
+
progress: {
|
|
359
|
+
current: getProgressFromGesture(
|
|
360
|
+
currentGesture,
|
|
361
|
+
state.layout,
|
|
362
|
+
descriptor,
|
|
363
|
+
isRTL
|
|
364
|
+
),
|
|
365
|
+
next:
|
|
366
|
+
nextGesture &&
|
|
367
|
+
nextDescriptor?.options.presentation !== 'transparentModal'
|
|
368
|
+
? getProgressFromGesture(
|
|
369
|
+
nextGesture,
|
|
370
|
+
state.layout,
|
|
371
|
+
nextDescriptor,
|
|
372
|
+
isRTL
|
|
373
|
+
)
|
|
374
|
+
: undefined,
|
|
375
|
+
previous: previousGesture
|
|
354
376
|
? getProgressFromGesture(
|
|
355
|
-
|
|
377
|
+
previousGesture,
|
|
356
378
|
state.layout,
|
|
357
|
-
|
|
379
|
+
previousDescriptor,
|
|
358
380
|
isRTL
|
|
359
381
|
)
|
|
360
382
|
: undefined,
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
383
|
+
},
|
|
384
|
+
__memo: [
|
|
385
|
+
state.layout,
|
|
386
|
+
descriptor,
|
|
387
|
+
nextDescriptor,
|
|
388
|
+
previousDescriptor,
|
|
389
|
+
currentGesture,
|
|
390
|
+
nextGesture,
|
|
391
|
+
previousGesture,
|
|
392
|
+
],
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
if (
|
|
396
|
+
oldScene &&
|
|
397
|
+
scene.__memo.every((it, i) => {
|
|
398
|
+
// @ts-expect-error: we haven't added __memo to the annotation to prevent usage elsewhere
|
|
399
|
+
return oldScene.__memo[i] === it;
|
|
400
|
+
})
|
|
401
|
+
) {
|
|
402
|
+
return oldScene;
|
|
403
|
+
}
|
|
380
404
|
|
|
381
|
-
|
|
382
|
-
oldScene &&
|
|
383
|
-
scene.__memo.every((it, i) => {
|
|
384
|
-
// @ts-expect-error: we haven't added __memo to the annotation to prevent usage elsewhere
|
|
385
|
-
return oldScene.__memo[i] === it;
|
|
386
|
-
})
|
|
387
|
-
) {
|
|
388
|
-
return oldScene;
|
|
405
|
+
return scene;
|
|
389
406
|
}
|
|
390
|
-
|
|
391
|
-
return scene;
|
|
392
|
-
});
|
|
407
|
+
);
|
|
393
408
|
|
|
394
409
|
return {
|
|
395
410
|
routes: props.routes,
|
|
@@ -504,7 +519,6 @@ export class CardStack extends React.Component<Props, State> {
|
|
|
504
519
|
onOpenRoute,
|
|
505
520
|
onCloseRoute,
|
|
506
521
|
renderHeader,
|
|
507
|
-
renderScene,
|
|
508
522
|
isParentHeaderShown,
|
|
509
523
|
isParentModal,
|
|
510
524
|
onTransitionStart,
|
|
@@ -546,16 +560,16 @@ export class CardStack extends React.Component<Props, State> {
|
|
|
546
560
|
detachPreviousScreen = options.presentation === 'transparentModal'
|
|
547
561
|
? false
|
|
548
562
|
: getIsModalPresentation(options.cardStyleInterpolator)
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
563
|
+
? i !==
|
|
564
|
+
findLastIndex(scenes, (scene) => {
|
|
565
|
+
const { cardStyleInterpolator } = scene.descriptor.options;
|
|
566
|
+
|
|
567
|
+
return (
|
|
568
|
+
cardStyleInterpolator === forModalPresentationIOS ||
|
|
569
|
+
cardStyleInterpolator?.name === 'forModalPresentationIOS'
|
|
570
|
+
);
|
|
571
|
+
})
|
|
572
|
+
: true,
|
|
559
573
|
} = options;
|
|
560
574
|
|
|
561
575
|
if (detachPreviousScreen === false) {
|
|
@@ -599,10 +613,23 @@ export class CardStack extends React.Component<Props, State> {
|
|
|
599
613
|
style={styles.container}
|
|
600
614
|
onLayout={this.handleLayout}
|
|
601
615
|
>
|
|
602
|
-
{routes.map((route, index
|
|
616
|
+
{[...routes, ...state.preloadedRoutes].map((route, index) => {
|
|
603
617
|
const focused = focusedRoute.key === route.key;
|
|
604
618
|
const gesture = gestures[route.key];
|
|
605
619
|
const scene = scenes[index];
|
|
620
|
+
// It is possible that for a short period the route appears in both arrays.
|
|
621
|
+
// Particularly, if the screen is removed with `retain`, then it needs a moment to execute the animation.
|
|
622
|
+
// However, due to the router action, it immediately populates the `preloadedRoutes` array.
|
|
623
|
+
// Practically, the logic below takes care that it is rendered only once.
|
|
624
|
+
const isPreloaded =
|
|
625
|
+
state.preloadedRoutes.includes(route) && !routes.includes(route);
|
|
626
|
+
if (
|
|
627
|
+
state.preloadedRoutes.includes(route) &&
|
|
628
|
+
routes.includes(route) &&
|
|
629
|
+
index >= routes.length
|
|
630
|
+
) {
|
|
631
|
+
return null;
|
|
632
|
+
}
|
|
606
633
|
|
|
607
634
|
// For the screens that shouldn't be active, the value is 0
|
|
608
635
|
// For those that should be active, but are not the top screen, the value is 1
|
|
@@ -614,17 +641,17 @@ export class CardStack extends React.Component<Props, State> {
|
|
|
614
641
|
| 1
|
|
615
642
|
| 2 = 1;
|
|
616
643
|
|
|
617
|
-
if (index <
|
|
644
|
+
if (index < routes.length - activeScreensLimit - 1 || isPreloaded) {
|
|
618
645
|
// screen should be inactive because it is too deep in the stack
|
|
619
646
|
isScreenActive = STATE_INACTIVE;
|
|
620
647
|
} else {
|
|
621
|
-
const sceneForActivity = scenes[
|
|
648
|
+
const sceneForActivity = scenes[routes.length - 1];
|
|
622
649
|
const outputValue =
|
|
623
|
-
index ===
|
|
650
|
+
index === routes.length - 1
|
|
624
651
|
? STATE_ON_TOP // the screen is on top after the transition
|
|
625
|
-
: index >=
|
|
626
|
-
|
|
627
|
-
|
|
652
|
+
: index >= routes.length - activeScreensLimit
|
|
653
|
+
? STATE_TRANSITIONING_OR_BELOW_TOP // the screen should stay active after the transition, it is not on top but is in activeLimit
|
|
654
|
+
: STATE_INACTIVE; // the screen should be active only during the transition, it is at the edge of activeLimit
|
|
628
655
|
isScreenActive = sceneForActivity
|
|
629
656
|
? sceneForActivity.progress.current.interpolate({
|
|
630
657
|
inputRange: [0, 1 - EPSILON, 1],
|
|
@@ -638,6 +665,7 @@ export class CardStack extends React.Component<Props, State> {
|
|
|
638
665
|
headerShown = true,
|
|
639
666
|
headerTransparent,
|
|
640
667
|
freezeOnBlur,
|
|
668
|
+
autoHideHomeIndicator,
|
|
641
669
|
} = scene.descriptor.options;
|
|
642
670
|
|
|
643
671
|
const safeAreaInsetTop = insets.top;
|
|
@@ -667,17 +695,18 @@ export class CardStack extends React.Component<Props, State> {
|
|
|
667
695
|
return (
|
|
668
696
|
<MaybeScreen
|
|
669
697
|
key={route.key}
|
|
670
|
-
style={StyleSheet.absoluteFill}
|
|
698
|
+
style={[StyleSheet.absoluteFill]}
|
|
671
699
|
enabled={detachInactiveScreens}
|
|
672
700
|
active={isScreenActive}
|
|
673
701
|
freezeOnBlur={freezeOnBlur}
|
|
702
|
+
homeIndicatorHidden={autoHideHomeIndicator}
|
|
674
703
|
pointerEvents="box-none"
|
|
675
704
|
>
|
|
676
705
|
<CardContainer
|
|
677
706
|
index={index}
|
|
678
707
|
interpolationIndex={interpolationIndex}
|
|
679
708
|
modal={isModal}
|
|
680
|
-
active={index ===
|
|
709
|
+
active={index === routes.length - 1}
|
|
681
710
|
focused={focused}
|
|
682
711
|
closing={closingRouteKeys.includes(route.key)}
|
|
683
712
|
layout={layout}
|
|
@@ -699,13 +728,13 @@ export class CardStack extends React.Component<Props, State> {
|
|
|
699
728
|
isFloatHeaderAbsolute && !headerTransparent
|
|
700
729
|
}
|
|
701
730
|
renderHeader={renderHeader}
|
|
702
|
-
renderScene={renderScene}
|
|
703
731
|
onOpenRoute={onOpenRoute}
|
|
704
732
|
onCloseRoute={onCloseRoute}
|
|
705
733
|
onTransitionStart={onTransitionStart}
|
|
706
734
|
onTransitionEnd={onTransitionEnd}
|
|
707
735
|
isNextScreenTransparent={isNextScreenTransparent}
|
|
708
736
|
detachCurrentScreen={detachCurrentScreen}
|
|
737
|
+
preloaded={isPreloaded}
|
|
709
738
|
/>
|
|
710
739
|
</MaybeScreen>
|
|
711
740
|
);
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
type LocaleDirection,
|
|
8
8
|
type ParamListBase,
|
|
9
9
|
type Route,
|
|
10
|
+
type RouteProp,
|
|
10
11
|
StackActions,
|
|
11
12
|
type StackNavigationState,
|
|
12
13
|
} from '@react-navigation/native';
|
|
@@ -15,6 +16,7 @@ import { StyleSheet, View } from 'react-native';
|
|
|
15
16
|
import { SafeAreaInsetsContext } from 'react-native-safe-area-context';
|
|
16
17
|
|
|
17
18
|
import type {
|
|
19
|
+
StackDescriptor,
|
|
18
20
|
StackDescriptorMap,
|
|
19
21
|
StackNavigationConfig,
|
|
20
22
|
StackNavigationHelpers,
|
|
@@ -32,6 +34,10 @@ type Props = StackNavigationConfig & {
|
|
|
32
34
|
state: StackNavigationState<ParamListBase>;
|
|
33
35
|
navigation: StackNavigationHelpers;
|
|
34
36
|
descriptors: StackDescriptorMap;
|
|
37
|
+
describe: (
|
|
38
|
+
route: RouteProp<ParamListBase>,
|
|
39
|
+
placeholder: boolean
|
|
40
|
+
) => StackDescriptor;
|
|
35
41
|
};
|
|
36
42
|
|
|
37
43
|
type State = {
|
|
@@ -299,17 +305,6 @@ export class StackView extends React.Component<Props, State> {
|
|
|
299
305
|
return routes[index - 1];
|
|
300
306
|
};
|
|
301
307
|
|
|
302
|
-
private renderScene = ({ route }: { route: Route<string> }) => {
|
|
303
|
-
const descriptor =
|
|
304
|
-
this.state.descriptors[route.key] || this.props.descriptors[route.key];
|
|
305
|
-
|
|
306
|
-
if (!descriptor) {
|
|
307
|
-
return null;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
return descriptor.render();
|
|
311
|
-
};
|
|
312
|
-
|
|
313
308
|
private renderHeader = (props: HeaderContainerProps) => {
|
|
314
309
|
return <HeaderContainer {...props} />;
|
|
315
310
|
};
|
|
@@ -434,6 +429,12 @@ export class StackView extends React.Component<Props, State> {
|
|
|
434
429
|
const { routes, descriptors, openingRouteKeys, closingRouteKeys } =
|
|
435
430
|
this.state;
|
|
436
431
|
|
|
432
|
+
const preloadedDescriptors =
|
|
433
|
+
state.preloadedRoutes.reduce<StackDescriptorMap>((acc, route) => {
|
|
434
|
+
acc[route.key] = acc[route.key] || this.props.describe(route, true);
|
|
435
|
+
return acc;
|
|
436
|
+
}, {});
|
|
437
|
+
|
|
437
438
|
return (
|
|
438
439
|
<GestureHandlerWrapper style={styles.container}>
|
|
439
440
|
<SafeAreaProviderCompat>
|
|
@@ -456,12 +457,12 @@ export class StackView extends React.Component<Props, State> {
|
|
|
456
457
|
onTransitionStart={this.handleTransitionStart}
|
|
457
458
|
onTransitionEnd={this.handleTransitionEnd}
|
|
458
459
|
renderHeader={this.renderHeader}
|
|
459
|
-
renderScene={this.renderScene}
|
|
460
460
|
state={state}
|
|
461
461
|
descriptors={descriptors}
|
|
462
462
|
onGestureStart={this.handleGestureStart}
|
|
463
463
|
onGestureEnd={this.handleGestureEnd}
|
|
464
464
|
onGestureCancel={this.handleGestureCancel}
|
|
465
|
+
preloadedDescriptors={preloadedDescriptors}
|
|
465
466
|
{...rest}
|
|
466
467
|
/>
|
|
467
468
|
)}
|