@react-navigation/stack 8.0.0-alpha.51 → 8.0.0-alpha.52

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 (61) hide show
  1. package/lib/module/TransitionConfigs/CardStyleInterpolators.js +241 -83
  2. package/lib/module/TransitionConfigs/CardStyleInterpolators.js.map +1 -1
  3. package/lib/module/TransitionConfigs/HeaderStyleInterpolators.js +11 -44
  4. package/lib/module/TransitionConfigs/HeaderStyleInterpolators.js.map +1 -1
  5. package/lib/module/TransitionConfigs/TransitionEasings.js +71 -0
  6. package/lib/module/TransitionConfigs/TransitionEasings.js.map +1 -0
  7. package/lib/module/TransitionConfigs/TransitionPresets.js +50 -10
  8. package/lib/module/TransitionConfigs/TransitionPresets.js.map +1 -1
  9. package/lib/module/TransitionConfigs/TransitionSpecs.js +69 -34
  10. package/lib/module/TransitionConfigs/TransitionSpecs.js.map +1 -1
  11. package/lib/module/navigators/createStackNavigator.js +25 -16
  12. package/lib/module/navigators/createStackNavigator.js.map +1 -1
  13. package/lib/module/views/Header/Header.js +2 -0
  14. package/lib/module/views/Header/Header.js.map +1 -1
  15. package/lib/module/views/Header/HeaderContainer.js +8 -3
  16. package/lib/module/views/Header/HeaderContainer.js.map +1 -1
  17. package/lib/module/views/Header/HeaderSegment.js +3 -6
  18. package/lib/module/views/Header/HeaderSegment.js.map +1 -1
  19. package/lib/module/views/Stack/Card.js +57 -32
  20. package/lib/module/views/Stack/Card.js.map +1 -1
  21. package/lib/module/views/Stack/CardContainer.js +17 -2
  22. package/lib/module/views/Stack/CardContainer.js.map +1 -1
  23. package/lib/module/views/Stack/CardStack.js +24 -13
  24. package/lib/module/views/Stack/CardStack.js.map +1 -1
  25. package/lib/typescript/src/TransitionConfigs/CardStyleInterpolators.d.ts +19 -11
  26. package/lib/typescript/src/TransitionConfigs/CardStyleInterpolators.d.ts.map +1 -1
  27. package/lib/typescript/src/TransitionConfigs/HeaderStyleInterpolators.d.ts +3 -3
  28. package/lib/typescript/src/TransitionConfigs/HeaderStyleInterpolators.d.ts.map +1 -1
  29. package/lib/typescript/src/TransitionConfigs/TransitionEasings.d.ts +38 -0
  30. package/lib/typescript/src/TransitionConfigs/TransitionEasings.d.ts.map +1 -0
  31. package/lib/typescript/src/TransitionConfigs/TransitionPresets.d.ts +14 -2
  32. package/lib/typescript/src/TransitionConfigs/TransitionPresets.d.ts.map +1 -1
  33. package/lib/typescript/src/TransitionConfigs/TransitionSpecs.d.ts +43 -14
  34. package/lib/typescript/src/TransitionConfigs/TransitionSpecs.d.ts.map +1 -1
  35. package/lib/typescript/src/navigators/createStackNavigator.d.ts.map +1 -1
  36. package/lib/typescript/src/types.d.ts +44 -28
  37. package/lib/typescript/src/types.d.ts.map +1 -1
  38. package/lib/typescript/src/views/Header/Header.d.ts +1 -1
  39. package/lib/typescript/src/views/Header/Header.d.ts.map +1 -1
  40. package/lib/typescript/src/views/Header/HeaderContainer.d.ts.map +1 -1
  41. package/lib/typescript/src/views/Header/HeaderSegment.d.ts +1 -0
  42. package/lib/typescript/src/views/Header/HeaderSegment.d.ts.map +1 -1
  43. package/lib/typescript/src/views/Stack/Card.d.ts +9 -3
  44. package/lib/typescript/src/views/Stack/Card.d.ts.map +1 -1
  45. package/lib/typescript/src/views/Stack/CardContainer.d.ts +3 -1
  46. package/lib/typescript/src/views/Stack/CardContainer.d.ts.map +1 -1
  47. package/lib/typescript/src/views/Stack/CardStack.d.ts.map +1 -1
  48. package/package.json +5 -5
  49. package/src/TransitionConfigs/CardStyleInterpolators.tsx +351 -100
  50. package/src/TransitionConfigs/HeaderStyleInterpolators.tsx +15 -46
  51. package/src/TransitionConfigs/TransitionEasings.tsx +90 -0
  52. package/src/TransitionConfigs/TransitionPresets.tsx +56 -10
  53. package/src/TransitionConfigs/TransitionSpecs.tsx +68 -34
  54. package/src/navigators/createStackNavigator.tsx +33 -24
  55. package/src/types.tsx +46 -29
  56. package/src/views/Header/Header.tsx +2 -0
  57. package/src/views/Header/HeaderContainer.tsx +10 -4
  58. package/src/views/Header/HeaderSegment.tsx +4 -4
  59. package/src/views/Stack/Card.tsx +82 -37
  60. package/src/views/Stack/CardContainer.tsx +17 -2
  61. package/src/views/Stack/CardStack.tsx +69 -14
@@ -5,6 +5,16 @@ import type {
5
5
  StackCardInterpolationProps,
6
6
  } from '../types';
7
7
  import { conditional } from '../utils/conditional';
8
+ import {
9
+ accelerate,
10
+ ACTIVITY_CLOSE_DIM,
11
+ clamp,
12
+ decelerate,
13
+ FAST_OUT_EXTRA_SLOW_IN,
14
+ FAST_OUT_SLOW_IN,
15
+ LINEAR_OUT_SLOW_IN,
16
+ timeline,
17
+ } from './TransitionEasings';
8
18
 
9
19
  const { add, multiply } = Animated;
10
20
 
@@ -39,13 +49,7 @@ export function forHorizontalIOS({
39
49
 
40
50
  const overlayOpacity = current.progress.interpolate({
41
51
  inputRange: [0, 1],
42
- outputRange: [0, 0.07],
43
- extrapolate: 'clamp',
44
- });
45
-
46
- const shadowOpacity = current.progress.interpolate({
47
- inputRange: [0, 1],
48
- outputRange: [0, 0.3],
52
+ outputRange: [0, 0.1],
49
53
  extrapolate: 'clamp',
50
54
  });
51
55
 
@@ -59,23 +63,10 @@ export function forHorizontalIOS({
59
63
  ],
60
64
  },
61
65
  overlayStyle: { opacity: overlayOpacity },
62
- shadowStyle: { shadowOpacity },
66
+ shadowStyle: { shadowOpacity: 0.04 },
63
67
  };
64
68
  }
65
69
 
66
- /**
67
- * iOS-style slide in from the left.
68
- */
69
- export function forHorizontalIOSInverted({
70
- inverted,
71
- ...rest
72
- }: StackCardInterpolationProps): StackCardInterpolatedStyle {
73
- return forHorizontalIOS({
74
- ...rest,
75
- inverted: Animated.multiply(inverted, -1),
76
- });
77
- }
78
-
79
70
  /**
80
71
  * Standard iOS-style slide in from the bottom (used for modals).
81
72
  */
@@ -242,9 +233,9 @@ export function forModalPresentationIOS({
242
233
  */
243
234
  export function forFadeFromBottomAndroid({
244
235
  current,
236
+ next,
245
237
  inverted,
246
238
  layouts: { screen },
247
- closing,
248
239
  }: StackCardInterpolationProps): StackCardInterpolatedStyle {
249
240
  const translateY = multiply(
250
241
  current.progress.interpolate({
@@ -256,13 +247,24 @@ export function forFadeFromBottomAndroid({
256
247
  );
257
248
 
258
249
  const opacity = conditional(
259
- closing,
260
- current.progress,
261
- current.progress.interpolate({
262
- inputRange: [0, 0.5, 0.9, 1],
263
- outputRange: [0, 0.25, 0.7, 1],
264
- extrapolate: 'clamp',
265
- })
250
+ current.closing,
251
+ current.progress.interpolate(
252
+ timeline({
253
+ duration: 250,
254
+ easing: (value) => accelerate(4, value),
255
+ closing: true,
256
+ stops: [100],
257
+ output: (time) => 1 - clamp((time - 100) / 150),
258
+ })
259
+ ),
260
+ current.progress.interpolate(
261
+ timeline({
262
+ duration: 350,
263
+ easing: (value) => decelerate(5, value),
264
+ stops: [200],
265
+ output: (time) => decelerate(4, clamp(time / 200)),
266
+ })
267
+ )
266
268
  );
267
269
 
268
270
  return {
@@ -270,6 +272,29 @@ export function forFadeFromBottomAndroid({
270
272
  opacity,
271
273
  transform: [{ translateY }],
272
274
  },
275
+ dimStyle: next
276
+ ? {
277
+ opacity: conditional(
278
+ next.closing,
279
+ next.progress.interpolate(
280
+ timeline({
281
+ duration: 250,
282
+ easing: (value) => accelerate(4, value),
283
+ closing: true,
284
+ output: (time) => 0.3 * (1 - LINEAR_OUT_SLOW_IN(time / 250)),
285
+ })
286
+ ),
287
+ next.progress.interpolate(
288
+ timeline({
289
+ duration: 350,
290
+ easing: (value) => decelerate(5, value),
291
+ stops: [217],
292
+ output: (time) => 0.3 * FAST_OUT_SLOW_IN(clamp(time / 217)),
293
+ })
294
+ )
295
+ ),
296
+ }
297
+ : undefined,
273
298
  };
274
299
  }
275
300
 
@@ -282,40 +307,80 @@ export function forRevealFromBottomAndroid({
282
307
  inverted,
283
308
  layouts: { screen },
284
309
  }: StackCardInterpolationProps): StackCardInterpolatedStyle {
310
+ const translationOpenRanges = timeline({
311
+ duration: 425,
312
+ easing: FAST_OUT_EXTRA_SLOW_IN,
313
+ output: (time) => FAST_OUT_SLOW_IN(time / 425),
314
+ });
315
+
316
+ const translationCloseRanges = timeline({
317
+ duration: 425,
318
+ easing: FAST_OUT_EXTRA_SLOW_IN,
319
+ closing: true,
320
+ output: (time) => 1 - FAST_OUT_SLOW_IN(time / 425),
321
+ });
322
+
323
+ const clipProgress = current.progress.interpolate({
324
+ inputRange: [0, 1],
325
+ outputRange: [0, 1],
326
+ extrapolate: 'clamp',
327
+ });
328
+
329
+ const translationProgress = conditional(
330
+ current.closing,
331
+ current.progress.interpolate(translationCloseRanges),
332
+ current.progress.interpolate(translationOpenRanges)
333
+ );
334
+
285
335
  const containerTranslateY = multiply(
286
- current.progress.interpolate({
287
- inputRange: [0, 1],
288
- outputRange: [screen.height, 0],
289
- extrapolate: 'clamp',
290
- }),
336
+ multiply(
337
+ add(
338
+ add(1, multiply(clipProgress, -0.959)),
339
+ multiply(translationProgress, -0.041)
340
+ ),
341
+ screen.height
342
+ ),
291
343
  inverted
292
344
  );
293
345
 
294
346
  const cardTranslateYFocused = multiply(
295
- current.progress.interpolate({
296
- inputRange: [0, 1],
297
- outputRange: [screen.height * (95.9 / 100) * -1, 0],
298
- extrapolate: 'clamp',
299
- }),
347
+ multiply(add(clipProgress, -1), screen.height * 0.959),
300
348
  inverted
301
349
  );
302
350
 
303
351
  const cardTranslateYUnfocused = next
304
352
  ? multiply(
305
- next.progress.interpolate({
306
- inputRange: [0, 1],
307
- outputRange: [0, screen.height * (2 / 100) * -1],
308
- extrapolate: 'clamp',
309
- }),
353
+ multiply(
354
+ conditional(
355
+ next.closing,
356
+ next.progress.interpolate(translationCloseRanges),
357
+ next.progress.interpolate(translationOpenRanges)
358
+ ),
359
+ screen.height * -0.02
360
+ ),
310
361
  inverted
311
362
  )
312
363
  : 0;
313
364
 
314
- const overlayOpacity = current.progress.interpolate({
315
- inputRange: [0, 0.36, 1],
316
- outputRange: [0, 0.1, 0.1],
317
- extrapolate: 'clamp',
318
- });
365
+ const overlayOpacity = conditional(
366
+ current.closing,
367
+ current.progress.interpolate(
368
+ timeline({
369
+ duration: 425,
370
+ easing: FAST_OUT_EXTRA_SLOW_IN,
371
+ closing: true,
372
+ output: (time) => 0.1 * (1 - ACTIVITY_CLOSE_DIM(time / 425)),
373
+ })
374
+ ),
375
+ current.progress.interpolate(
376
+ timeline({
377
+ duration: 425,
378
+ easing: FAST_OUT_EXTRA_SLOW_IN,
379
+ stops: [117],
380
+ output: (time) => 0.1 * clamp(time / 117),
381
+ })
382
+ )
383
+ );
319
384
 
320
385
  return {
321
386
  containerStyle: {
@@ -333,62 +398,94 @@ export function forRevealFromBottomAndroid({
333
398
  }
334
399
 
335
400
  /**
336
- * Standard Android-style zoom for Android 10.
401
+ * Standard Android-style scale from center for Android 10.
337
402
  */
338
403
  export function forScaleFromCenterAndroid({
339
404
  current,
340
405
  next,
341
- closing,
342
406
  }: StackCardInterpolationProps): StackCardInterpolatedStyle {
343
- const progress = add(
344
- current.progress.interpolate({
345
- inputRange: [0, 1],
346
- outputRange: [0, 1],
347
- extrapolate: 'clamp',
348
- }),
349
- next
350
- ? next.progress.interpolate({
407
+ const opacity = conditional(
408
+ current.closing,
409
+ current.progress.interpolate(
410
+ timeline({
411
+ duration: 400,
412
+ easing: FAST_OUT_EXTRA_SLOW_IN,
413
+ closing: true,
414
+ stops: [33, 83],
415
+ output: (time) => 1 - clamp((time - 33) / 50),
416
+ })
417
+ ),
418
+ current.progress.interpolate(
419
+ timeline({
420
+ duration: 400,
421
+ easing: FAST_OUT_EXTRA_SLOW_IN,
422
+ stops: [50, 100],
423
+ output: (time) => clamp((time - 50) / 50),
424
+ })
425
+ )
426
+ );
427
+
428
+ const scale = next
429
+ ? conditional(
430
+ next.closing,
431
+ next.progress.interpolate({
351
432
  inputRange: [0, 1],
352
- outputRange: [0, 1],
433
+ outputRange: [1, 1.1],
434
+ extrapolate: 'clamp',
435
+ }),
436
+ next.progress.interpolate({
437
+ inputRange: [0, 1],
438
+ outputRange: [1, 1.05],
353
439
  extrapolate: 'clamp',
354
440
  })
355
- : 0
356
- );
357
-
358
- const opacity = progress.interpolate({
359
- inputRange: [0, 0.75, 0.875, 1, 1.0825, 1.2075, 2],
360
- outputRange: [0, 0, 1, 1, 1, 1, 0],
361
- });
362
-
363
- const scale = conditional(
364
- closing,
365
- current.progress.interpolate({
366
- inputRange: [0, 1],
367
- outputRange: [0.925, 1],
368
- extrapolate: 'clamp',
369
- }),
370
- progress.interpolate({
371
- inputRange: [0, 1, 2],
372
- outputRange: [0.85, 1, 1.075],
373
- })
374
- );
441
+ )
442
+ : conditional(
443
+ current.closing,
444
+ current.progress.interpolate({
445
+ inputRange: [0, 1],
446
+ outputRange: [0.9, 1],
447
+ extrapolate: 'clamp',
448
+ }),
449
+ current.progress.interpolate({
450
+ inputRange: [0, 1],
451
+ outputRange: [0.85, 1],
452
+ extrapolate: 'clamp',
453
+ })
454
+ );
375
455
 
376
456
  return {
377
457
  cardStyle: {
378
458
  opacity,
379
459
  transform: [{ scale }],
380
460
  },
461
+ dimStyle: next
462
+ ? {
463
+ opacity: multiply(
464
+ next.closing.interpolate({
465
+ inputRange: [0, 1],
466
+ outputRange: [1, 0],
467
+ }),
468
+ next.progress.interpolate(
469
+ timeline({
470
+ duration: 400,
471
+ easing: FAST_OUT_EXTRA_SLOW_IN,
472
+ stops: [83, 250],
473
+ output: (time) => 0.6 * clamp((time - 83) / 167),
474
+ })
475
+ )
476
+ ),
477
+ }
478
+ : undefined,
381
479
  };
382
480
  }
383
481
 
384
482
  /**
385
- * Standard Android-style fade from right for Android 14.
483
+ * Standard Android-style fade from right for Android 14 and later.
386
484
  */
387
485
  export function forFadeFromRightAndroid({
388
486
  current,
389
487
  next,
390
488
  inverted,
391
- closing,
392
489
  }: StackCardInterpolationProps): StackCardInterpolatedStyle {
393
490
  const translateFocused = multiply(
394
491
  current.progress.interpolate({
@@ -411,13 +508,24 @@ export function forFadeFromRightAndroid({
411
508
  : 0;
412
509
 
413
510
  const opacity = conditional(
414
- closing,
415
- current.progress.interpolate({
416
- inputRange: [0, 1],
417
- outputRange: [0, 1],
418
- extrapolate: 'clamp',
419
- }),
420
- current.progress
511
+ current.closing,
512
+ current.progress.interpolate(
513
+ timeline({
514
+ duration: 450,
515
+ easing: FAST_OUT_EXTRA_SLOW_IN,
516
+ closing: true,
517
+ stops: [35, 118],
518
+ output: (time) => 1 - clamp((time - 35) / 83),
519
+ })
520
+ ),
521
+ current.progress.interpolate(
522
+ timeline({
523
+ duration: 450,
524
+ easing: FAST_OUT_EXTRA_SLOW_IN,
525
+ stops: [50, 133],
526
+ output: (time) => clamp((time - 50) / 83),
527
+ })
528
+ )
421
529
  );
422
530
 
423
531
  return {
@@ -440,20 +548,27 @@ export function forBottomSheetAndroid({
440
548
  current,
441
549
  inverted,
442
550
  layouts: { screen },
443
- closing,
444
551
  }: StackCardInterpolationProps): StackCardInterpolatedStyle {
445
552
  const translateY = multiply(
446
553
  current.progress.interpolate({
447
554
  inputRange: [0, 1],
448
- outputRange: [screen.height * 0.8, 0],
555
+ outputRange: [screen.height * 0.2, 0],
449
556
  extrapolate: 'clamp',
450
557
  }),
451
558
  inverted
452
559
  );
453
560
 
454
561
  const opacity = conditional(
455
- closing,
456
- current.progress,
562
+ current.closing,
563
+ current.progress.interpolate(
564
+ timeline({
565
+ duration: 350,
566
+ easing: FAST_OUT_EXTRA_SLOW_IN,
567
+ closing: true,
568
+ stops: [300],
569
+ output: (time) => 1 - FAST_OUT_EXTRA_SLOW_IN(clamp(time / 300)),
570
+ })
571
+ ),
457
572
  current.progress.interpolate({
458
573
  inputRange: [0, 1],
459
574
  outputRange: [0, 1],
@@ -461,23 +576,107 @@ export function forBottomSheetAndroid({
461
576
  })
462
577
  );
463
578
 
464
- const overlayOpacity = current.progress.interpolate({
579
+ // We follow Android's window dim timing for the 0.32 scrim.
580
+ // This makes it reach full opacity after 128 ms and clear after 112 ms.
581
+ // See https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-17.0.0_r1/services/core/java/com/android/server/wm/DimmerAnimationHelper.java
582
+ const overlayOpacity = conditional(
583
+ current.closing,
584
+ current.progress.interpolate(
585
+ timeline({
586
+ duration: 350,
587
+ easing: FAST_OUT_EXTRA_SLOW_IN,
588
+ closing: true,
589
+ stops: [112],
590
+ output: (time) => 0.32 * (1 - clamp(time / 112)),
591
+ })
592
+ ),
593
+ current.progress.interpolate(
594
+ timeline({
595
+ duration: 400,
596
+ easing: FAST_OUT_EXTRA_SLOW_IN,
597
+ stops: [128],
598
+ output: (time) => 0.32 * clamp(time / 128),
599
+ })
600
+ )
601
+ );
602
+
603
+ return {
604
+ cardStyle: {
605
+ opacity,
606
+ transform: [{ translateY }],
607
+ },
608
+ overlayStyle: { opacity: overlayOpacity },
609
+ };
610
+ }
611
+
612
+ /**
613
+ * Standard Android dialog transition.
614
+ */
615
+ export function forDialogAndroid({
616
+ current: { progress, closing },
617
+ }: StackCardInterpolationProps): StackCardInterpolatedStyle {
618
+ const opacity = conditional(
619
+ closing,
620
+ progress.interpolate(
621
+ timeline({
622
+ duration: 220,
623
+ easing: (value) => decelerate(5, value),
624
+ closing: true,
625
+ stops: [150],
626
+ output: (time) => 1 - decelerate(3, clamp(time / 150)),
627
+ })
628
+ ),
629
+ progress.interpolate(
630
+ timeline({
631
+ duration: 220,
632
+ easing: (value) => decelerate(5, value),
633
+ stops: [150],
634
+ output: (time) => decelerate(3, clamp(time / 150)),
635
+ })
636
+ )
637
+ );
638
+
639
+ const scale = progress.interpolate({
465
640
  inputRange: [0, 1],
466
- outputRange: [0, 0.3],
641
+ outputRange: [0.9, 1],
467
642
  extrapolate: 'clamp',
468
643
  });
469
644
 
645
+ // We follow Android's window dim timing for the 0.6 dialog dim.
646
+ // This makes it reach or clear full opacity after 132 ms.
647
+ // See https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-17.0.0_r1/services/core/java/com/android/server/wm/DimmerAnimationHelper.java
648
+ const overlayOpacity = conditional(
649
+ closing,
650
+ progress.interpolate(
651
+ timeline({
652
+ duration: 220,
653
+ easing: (value) => decelerate(5, value),
654
+ closing: true,
655
+ stops: [132],
656
+ output: (time) => 0.6 * (1 - clamp(time / 132)),
657
+ })
658
+ ),
659
+ progress.interpolate(
660
+ timeline({
661
+ duration: 220,
662
+ easing: (value) => decelerate(5, value),
663
+ stops: [132],
664
+ output: (time) => 0.6 * clamp(time / 132),
665
+ })
666
+ )
667
+ );
668
+
470
669
  return {
471
670
  cardStyle: {
472
671
  opacity,
473
- transform: [{ translateY }],
672
+ transform: [{ scale }],
474
673
  },
475
674
  overlayStyle: { opacity: overlayOpacity },
476
675
  };
477
676
  }
478
677
 
479
678
  /**
480
- * Simple fade animation for dialogs
679
+ * Simple fade animation.
481
680
  */
482
681
  export function forFadeFromCenter({
483
682
  current: { progress },
@@ -487,15 +686,67 @@ export function forFadeFromCenter({
487
686
  opacity: progress.interpolate({
488
687
  inputRange: [0, 0.5, 0.9, 1],
489
688
  outputRange: [0, 0.25, 0.7, 1],
689
+ extrapolate: 'clamp',
490
690
  }),
491
691
  },
492
- overlayStyle: {
493
- opacity: progress.interpolate({
692
+ };
693
+ }
694
+
695
+ /**
696
+ * Standard iOS cross-dissolve transition.
697
+ */
698
+ export function forCrossDissolveIOS({
699
+ current,
700
+ next,
701
+ }: StackCardInterpolationProps): StackCardInterpolatedStyle {
702
+ // UIKit cross-dissolve darkens identical light screens at the midpoint.
703
+ // Dimming the outgoing card reproduces this without exposing earlier screens.
704
+ return {
705
+ cardStyle: {
706
+ opacity: current.progress.interpolate({
494
707
  inputRange: [0, 1],
495
- outputRange: [0, 0.5],
708
+ outputRange: [0, 1],
496
709
  extrapolate: 'clamp',
497
710
  }),
498
711
  },
712
+ dimStyle: next
713
+ ? {
714
+ opacity: next.progress.interpolate({
715
+ inputRange: [0, 1],
716
+ outputRange: [0, 1],
717
+ extrapolate: 'clamp',
718
+ }),
719
+ }
720
+ : undefined,
721
+ };
722
+ }
723
+
724
+ /**
725
+ * Standard iOS horizontal flip transition.
726
+ */
727
+ export function forFlipIOS({
728
+ current,
729
+ next,
730
+ inverted,
731
+ }: StackCardInterpolationProps): StackCardInterpolatedStyle {
732
+ const progress = add(current.progress, next ? next.progress : 0);
733
+
734
+ const rotateY = multiply(
735
+ progress.interpolate({
736
+ inputRange: [0, 1, 2],
737
+ outputRange: [180, 0, -180],
738
+ }),
739
+ inverted
740
+ ).interpolate({
741
+ inputRange: [-180, 0, 180],
742
+ outputRange: ['-180deg', '0deg', '180deg'],
743
+ });
744
+
745
+ return {
746
+ cardStyle: {
747
+ backfaceVisibility: 'hidden',
748
+ transform: [{ perspective: 1000 }, { rotateY }],
749
+ },
499
750
  };
500
751
  }
501
752
 
@@ -14,11 +14,9 @@ const { add, multiply } = Animated;
14
14
  export function forUIKit({
15
15
  current,
16
16
  next,
17
- direction,
17
+ inverted,
18
18
  layouts,
19
19
  }: StackHeaderInterpolationProps): StackHeaderInterpolatedStyle {
20
- const multiplier = direction === 'rtl' ? -1 : 1;
21
-
22
20
  const progress = add(
23
21
  current.progress.interpolate({
24
22
  inputRange: [0, 1],
@@ -45,7 +43,7 @@ export function forUIKit({
45
43
  });
46
44
 
47
45
  const translateX = multiply(
48
- multiplier,
46
+ inverted,
49
47
  progress.interpolate({
50
48
  inputRange: [0, 1, 2],
51
49
  outputRange: [layouts.screen.width, 0, -layouts.screen.width * 0.3],
@@ -128,10 +126,9 @@ export function forFade({
128
126
  export function forSlideLeft({
129
127
  current,
130
128
  next,
131
- direction,
129
+ inverted,
132
130
  layouts: { screen },
133
131
  }: StackHeaderInterpolationProps): StackHeaderInterpolatedStyle {
134
- const isRTL = direction === 'rtl';
135
132
  const progress = add(
136
133
  current.progress.interpolate({
137
134
  inputRange: [0, 1],
@@ -147,12 +144,13 @@ export function forSlideLeft({
147
144
  : 0
148
145
  );
149
146
 
150
- const translateX = progress.interpolate({
151
- inputRange: [0, 1, 2],
152
- outputRange: isRTL
153
- ? [-screen.width, 0, screen.width]
154
- : [screen.width, 0, -screen.width],
155
- });
147
+ const translateX = multiply(
148
+ inverted,
149
+ progress.interpolate({
150
+ inputRange: [0, 1, 2],
151
+ outputRange: [screen.width, 0, -screen.width],
152
+ })
153
+ );
156
154
 
157
155
  const transform = [{ translateX }];
158
156
 
@@ -168,42 +166,13 @@ export function forSlideLeft({
168
166
  * Simple translate animation to translate the header to right.
169
167
  */
170
168
  export function forSlideRight({
171
- current,
172
- next,
173
- direction,
174
- layouts: { screen },
169
+ inverted,
170
+ ...rest
175
171
  }: StackHeaderInterpolationProps): StackHeaderInterpolatedStyle {
176
- const isRTL = direction === 'rtl';
177
- const progress = add(
178
- current.progress.interpolate({
179
- inputRange: [0, 1],
180
- outputRange: [0, 1],
181
- extrapolate: 'clamp',
182
- }),
183
- next
184
- ? next.progress.interpolate({
185
- inputRange: [0, 1],
186
- outputRange: [0, 1],
187
- extrapolate: 'clamp',
188
- })
189
- : 0
190
- );
191
-
192
- const translateX = progress.interpolate({
193
- inputRange: [0, 1, 2],
194
- outputRange: isRTL
195
- ? [screen.width, 0, -screen.width]
196
- : [-screen.width, 0, screen.width],
172
+ return forSlideLeft({
173
+ ...rest,
174
+ inverted: inverted === 1 ? -1 : 1,
197
175
  });
198
-
199
- const transform = [{ translateX }];
200
-
201
- return {
202
- leftButtonStyle: { transform },
203
- rightButtonStyle: { transform },
204
- titleStyle: { transform },
205
- backgroundStyle: { transform },
206
- };
207
176
  }
208
177
 
209
178
  /**