@amazon-devices/react-navigation__stack 7.0.9000000000 → 8.0.9000000000-rn-83

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 (275) hide show
  1. package/SystemBundles/03e0ad8b8bcf16e659904adab730cbe9c1832c4a36017809f129fea7fb07b4fc.bundle +13453 -0
  2. package/SystemBundles/03e0ad8b8bcf16e659904adab730cbe9c1832c4a36017809f129fea7fb07b4fc.map +4627 -0
  3. package/SystemModules/amzn__react-navigation__stack-8.modules.txt +32 -0
  4. package/SystemModules/amzn__react-navigation__stack-8.private.modules.txt +91 -0
  5. package/SystemModules/keplerscript-system-bundle-config.json +4 -4
  6. package/kepler-compatibility.json +2 -2
  7. package/lib/module/TransitionConfigs/CardStyleInterpolators.js +57 -1
  8. package/lib/module/TransitionConfigs/CardStyleInterpolators.js.map +1 -1
  9. package/lib/module/TransitionConfigs/HeaderStyleInterpolators.js +30 -16
  10. package/lib/module/TransitionConfigs/HeaderStyleInterpolators.js.map +1 -1
  11. package/lib/module/TransitionConfigs/TransitionPresets.js +32 -4
  12. package/lib/module/TransitionConfigs/TransitionPresets.js.map +1 -1
  13. package/lib/module/TransitionConfigs/TransitionSpecs.js +32 -2
  14. package/lib/module/TransitionConfigs/TransitionSpecs.js.map +1 -1
  15. package/lib/module/index.js +13 -11
  16. package/lib/module/index.js.map +1 -1
  17. package/lib/module/navigators/createStackNavigator.js +46 -48
  18. package/lib/module/navigators/createStackNavigator.js.map +1 -1
  19. package/lib/module/package.json +1 -0
  20. package/lib/module/types.js +2 -0
  21. package/lib/module/types.js.map +1 -1
  22. package/lib/module/utils/CardAnimationContext.js +3 -1
  23. package/lib/module/utils/CardAnimationContext.js.map +1 -1
  24. package/lib/module/utils/GestureHandlerRefContext.js +3 -1
  25. package/lib/module/utils/GestureHandlerRefContext.js.map +1 -1
  26. package/lib/module/utils/ModalPresentationContext.js +3 -2
  27. package/lib/module/utils/ModalPresentationContext.js.map +1 -1
  28. package/lib/module/utils/conditional.js +3 -1
  29. package/lib/module/utils/conditional.js.map +1 -1
  30. package/lib/module/utils/findLastIndex.js +4 -2
  31. package/lib/module/utils/findLastIndex.js.map +1 -1
  32. package/lib/module/utils/gestureActivationCriteria.js +60 -0
  33. package/lib/module/utils/gestureActivationCriteria.js.map +1 -0
  34. package/lib/module/utils/getDistanceForDirection.js +5 -3
  35. package/lib/module/utils/getDistanceForDirection.js.map +1 -1
  36. package/lib/module/utils/getInvertedMultiplier.js +5 -4
  37. package/lib/module/utils/getInvertedMultiplier.js.map +1 -1
  38. package/lib/module/utils/getModalRoutesKeys.js +12 -0
  39. package/lib/module/utils/getModalRoutesKeys.js.map +1 -0
  40. package/lib/module/utils/getShadowStyle.js +24 -0
  41. package/lib/module/utils/getShadowStyle.js.map +1 -0
  42. package/lib/module/utils/{debounce.js → throttle.js} +5 -4
  43. package/lib/module/utils/throttle.js.map +1 -0
  44. package/lib/module/utils/useCardAnimation.js +4 -2
  45. package/lib/module/utils/useCardAnimation.js.map +1 -1
  46. package/lib/module/utils/useGestureHandlerRef.js +5 -3
  47. package/lib/module/utils/useGestureHandlerRef.js.map +1 -1
  48. package/lib/module/utils/useKeyboardManager.js +8 -6
  49. package/lib/module/utils/useKeyboardManager.js.map +1 -1
  50. package/lib/module/views/GestureHandler.android.js +3 -1
  51. package/lib/module/views/GestureHandler.android.js.map +1 -1
  52. package/lib/module/views/GestureHandler.ios.js +3 -1
  53. package/lib/module/views/GestureHandler.ios.js.map +1 -1
  54. package/lib/module/views/GestureHandler.js +6 -1
  55. package/lib/module/views/GestureHandler.js.map +1 -1
  56. package/lib/module/views/GestureHandler.kepler.js +4 -0
  57. package/lib/module/views/GestureHandler.kepler.js.map +1 -0
  58. package/lib/module/views/GestureHandlerNative.js +13 -9
  59. package/lib/module/views/GestureHandlerNative.js.map +1 -1
  60. package/lib/module/views/Header/Header.js +12 -8
  61. package/lib/module/views/Header/Header.js.map +1 -1
  62. package/lib/module/views/Header/HeaderContainer.js +103 -93
  63. package/lib/module/views/Header/HeaderContainer.js.map +1 -1
  64. package/lib/module/views/Header/HeaderSegment.js +43 -31
  65. package/lib/module/views/Header/HeaderSegment.js.map +1 -1
  66. package/lib/module/views/Screens.js +17 -9
  67. package/lib/module/views/Screens.js.map +1 -1
  68. package/lib/module/views/Stack/Card.js +313 -338
  69. package/lib/module/views/Stack/Card.js.map +1 -1
  70. package/lib/module/views/Stack/CardA11yWrapper.js +43 -0
  71. package/lib/module/views/Stack/CardA11yWrapper.js.map +1 -0
  72. package/lib/module/views/Stack/CardContainer.js +116 -90
  73. package/lib/module/views/Stack/CardContainer.js.map +1 -1
  74. package/lib/module/views/Stack/CardContent.js +74 -0
  75. package/lib/module/views/Stack/CardContent.js.map +1 -0
  76. package/lib/module/views/Stack/CardStack.js +246 -181
  77. package/lib/module/views/Stack/CardStack.js.map +1 -1
  78. package/lib/module/views/Stack/StackView.js +80 -64
  79. package/lib/module/views/Stack/StackView.js.map +1 -1
  80. package/lib/typescript/package.json +1 -0
  81. package/lib/typescript/src/TransitionConfigs/CardStyleInterpolators.d.ts +8 -0
  82. package/lib/typescript/src/TransitionConfigs/CardStyleInterpolators.d.ts.map +1 -1
  83. package/lib/typescript/src/TransitionConfigs/HeaderStyleInterpolators.d.ts +3 -3
  84. package/lib/typescript/src/TransitionConfigs/HeaderStyleInterpolators.d.ts.map +1 -1
  85. package/lib/typescript/src/TransitionConfigs/TransitionPresets.d.ts +8 -0
  86. package/lib/typescript/src/TransitionConfigs/TransitionPresets.d.ts.map +1 -1
  87. package/lib/typescript/src/TransitionConfigs/TransitionSpecs.d.ts +10 -0
  88. package/lib/typescript/src/TransitionConfigs/TransitionSpecs.d.ts.map +1 -1
  89. package/lib/typescript/src/index.d.ts +8 -8
  90. package/lib/typescript/src/index.d.ts.map +1 -1
  91. package/lib/typescript/src/navigators/createStackNavigator.d.ts +15 -7
  92. package/lib/typescript/src/navigators/createStackNavigator.d.ts.map +1 -1
  93. package/lib/typescript/src/types.d.ts +84 -24
  94. package/lib/typescript/src/types.d.ts.map +1 -1
  95. package/lib/typescript/src/utils/CardAnimationContext.d.ts +1 -2
  96. package/lib/typescript/src/utils/CardAnimationContext.d.ts.map +1 -1
  97. package/lib/typescript/src/utils/GestureHandlerRefContext.d.ts +1 -2
  98. package/lib/typescript/src/utils/GestureHandlerRefContext.d.ts.map +1 -1
  99. package/lib/typescript/src/utils/ModalPresentationContext.d.ts +1 -2
  100. package/lib/typescript/src/utils/ModalPresentationContext.d.ts.map +1 -1
  101. package/lib/typescript/src/utils/conditional.d.ts +1 -1
  102. package/lib/typescript/src/utils/conditional.d.ts.map +1 -1
  103. package/lib/typescript/src/utils/findLastIndex.d.ts +1 -1
  104. package/lib/typescript/src/utils/findLastIndex.d.ts.map +1 -1
  105. package/lib/typescript/src/utils/gestureActivationCriteria.d.ts +57 -0
  106. package/lib/typescript/src/utils/gestureActivationCriteria.d.ts.map +1 -0
  107. package/lib/typescript/src/utils/getDistanceForDirection.d.ts +1 -1
  108. package/lib/typescript/src/utils/getDistanceForDirection.d.ts.map +1 -1
  109. package/lib/typescript/src/utils/getInvertedMultiplier.d.ts +1 -1
  110. package/lib/typescript/src/utils/getInvertedMultiplier.d.ts.map +1 -1
  111. package/lib/typescript/src/utils/getModalRoutesKeys.d.ts +4 -0
  112. package/lib/typescript/src/utils/getModalRoutesKeys.d.ts.map +1 -0
  113. package/lib/typescript/src/utils/getShadowStyle.d.ts +27 -0
  114. package/lib/typescript/src/utils/getShadowStyle.d.ts.map +1 -0
  115. package/lib/typescript/src/utils/throttle.d.ts +2 -0
  116. package/lib/typescript/src/utils/throttle.d.ts.map +1 -0
  117. package/lib/typescript/src/utils/useCardAnimation.d.ts +1 -1
  118. package/lib/typescript/src/utils/useCardAnimation.d.ts.map +1 -1
  119. package/lib/typescript/src/utils/useGestureHandlerRef.d.ts +1 -1
  120. package/lib/typescript/src/utils/useGestureHandlerRef.d.ts.map +1 -1
  121. package/lib/typescript/src/utils/useKeyboardManager.d.ts +1 -1
  122. package/lib/typescript/src/utils/useKeyboardManager.d.ts.map +1 -1
  123. package/lib/typescript/src/views/GestureHandler.d.ts +3 -2
  124. package/lib/typescript/src/views/GestureHandler.d.ts.map +1 -1
  125. package/lib/typescript/src/views/GestureHandler.kepler.d.ts +2 -0
  126. package/lib/typescript/src/views/GestureHandler.kepler.d.ts.map +1 -0
  127. package/lib/typescript/src/views/GestureHandlerNative.d.ts +4 -5
  128. package/lib/typescript/src/views/GestureHandlerNative.d.ts.map +1 -1
  129. package/lib/typescript/src/views/Header/Header.d.ts +1 -2
  130. package/lib/typescript/src/views/Header/Header.d.ts.map +1 -1
  131. package/lib/typescript/src/views/Header/HeaderContainer.d.ts +4 -5
  132. package/lib/typescript/src/views/Header/HeaderContainer.d.ts.map +1 -1
  133. package/lib/typescript/src/views/Header/HeaderSegment.d.ts +2 -2
  134. package/lib/typescript/src/views/Header/HeaderSegment.d.ts.map +1 -1
  135. package/lib/typescript/src/views/Screens.d.ts +7 -5
  136. package/lib/typescript/src/views/Screens.d.ts.map +1 -1
  137. package/lib/typescript/src/views/Stack/Card.d.ts +14 -42
  138. package/lib/typescript/src/views/Stack/Card.d.ts.map +1 -1
  139. package/lib/typescript/src/views/Stack/CardA11yWrapper.d.ts +15 -0
  140. package/lib/typescript/src/views/Stack/CardA11yWrapper.d.ts.map +1 -0
  141. package/lib/typescript/src/views/Stack/CardContainer.d.ts +6 -8
  142. package/lib/typescript/src/views/Stack/CardContainer.d.ts.map +1 -1
  143. package/lib/typescript/src/views/Stack/CardContent.d.ts +13 -0
  144. package/lib/typescript/src/views/Stack/CardContent.d.ts.map +1 -0
  145. package/lib/typescript/src/views/Stack/CardStack.d.ts +8 -7
  146. package/lib/typescript/src/views/Stack/CardStack.d.ts.map +1 -1
  147. package/lib/typescript/src/views/Stack/StackView.d.ts +10 -81
  148. package/lib/typescript/src/views/Stack/StackView.d.ts.map +1 -1
  149. package/oss-attribution/attribution.txt +76 -0
  150. package/oss-attribution/licenseInfos.json +27 -0
  151. package/package.json +105 -1
  152. package/src/TransitionConfigs/CardStyleInterpolators.tsx +72 -6
  153. package/src/TransitionConfigs/HeaderStyleInterpolators.tsx +43 -25
  154. package/src/TransitionConfigs/TransitionPresets.tsx +35 -5
  155. package/src/TransitionConfigs/TransitionSpecs.tsx +30 -2
  156. package/src/index.tsx +12 -7
  157. package/src/navigators/createStackNavigator.tsx +47 -63
  158. package/src/types.tsx +116 -24
  159. package/src/utils/CardAnimationContext.tsx +3 -3
  160. package/src/utils/GestureHandlerRefContext.tsx +2 -2
  161. package/src/utils/ModalPresentationContext.tsx +1 -3
  162. package/src/utils/conditional.tsx +1 -1
  163. package/src/utils/findLastIndex.tsx +2 -5
  164. package/src/utils/gestureActivationCriteria.tsx +70 -0
  165. package/src/utils/getDistanceForDirection.tsx +5 -4
  166. package/src/utils/getInvertedMultiplier.tsx +5 -6
  167. package/src/utils/getModalRoutesKeys.ts +21 -0
  168. package/src/utils/getShadowStyle.tsx +37 -0
  169. package/src/utils/throttle.tsx +16 -0
  170. package/src/utils/useCardAnimation.tsx +2 -2
  171. package/src/utils/useGestureHandlerRef.tsx +3 -3
  172. package/src/utils/useKeyboardManager.tsx +5 -7
  173. package/src/views/GestureHandler.kepler.tsx +1 -0
  174. package/src/views/GestureHandler.tsx +2 -2
  175. package/src/views/GestureHandlerNative.tsx +5 -5
  176. package/src/views/Header/Header.tsx +8 -7
  177. package/src/views/Header/HeaderContainer.tsx +23 -18
  178. package/src/views/Header/HeaderSegment.tsx +41 -43
  179. package/src/views/Screens.tsx +4 -2
  180. package/src/views/Stack/Card.tsx +480 -462
  181. package/src/views/Stack/CardA11yWrapper.tsx +67 -0
  182. package/src/views/Stack/CardContainer.tsx +127 -108
  183. package/src/views/Stack/CardContent.tsx +92 -0
  184. package/src/views/Stack/CardStack.tsx +375 -243
  185. package/src/views/Stack/StackView.tsx +73 -62
  186. package/SystemBundles/c55a41e7975f46f901d6afe3b0331d043bdbf1f54f96209de0215cf6f6fd5377.bundle +0 -28130
  187. package/SystemBundles/c55a41e7975f46f901d6afe3b0331d043bdbf1f54f96209de0215cf6f6fd5377.map +0 -8489
  188. package/SystemModules/amzn__react-navigation__stack-7.modules.txt +0 -95
  189. package/SystemModules/amzn__react-navigation__stack-7.private.modules.txt +0 -191
  190. package/THIRD_PARTY_NOTICES.txt +0 -24
  191. package/lib/commonjs/TransitionConfigs/CardStyleInterpolators.js +0 -353
  192. package/lib/commonjs/TransitionConfigs/CardStyleInterpolators.js.map +0 -1
  193. package/lib/commonjs/TransitionConfigs/HeaderStyleInterpolators.js +0 -259
  194. package/lib/commonjs/TransitionConfigs/HeaderStyleInterpolators.js.map +0 -1
  195. package/lib/commonjs/TransitionConfigs/TransitionPresets.js +0 -134
  196. package/lib/commonjs/TransitionConfigs/TransitionPresets.js.map +0 -1
  197. package/lib/commonjs/TransitionConfigs/TransitionSpecs.js +0 -100
  198. package/lib/commonjs/TransitionConfigs/TransitionSpecs.js.map +0 -1
  199. package/lib/commonjs/index.js +0 -69
  200. package/lib/commonjs/index.js.map +0 -1
  201. package/lib/commonjs/navigators/createStackNavigator.js +0 -82
  202. package/lib/commonjs/navigators/createStackNavigator.js.map +0 -1
  203. package/lib/commonjs/types.js +0 -6
  204. package/lib/commonjs/types.js.map +0 -1
  205. package/lib/commonjs/utils/CardAnimationContext.js +0 -11
  206. package/lib/commonjs/utils/CardAnimationContext.js.map +0 -1
  207. package/lib/commonjs/utils/GestureHandlerRefContext.js +0 -11
  208. package/lib/commonjs/utils/GestureHandlerRefContext.js.map +0 -1
  209. package/lib/commonjs/utils/ModalPresentationContext.js +0 -12
  210. package/lib/commonjs/utils/ModalPresentationContext.js.map +0 -1
  211. package/lib/commonjs/utils/conditional.js +0 -32
  212. package/lib/commonjs/utils/conditional.js.map +0 -1
  213. package/lib/commonjs/utils/debounce.js +0 -19
  214. package/lib/commonjs/utils/debounce.js.map +0 -1
  215. package/lib/commonjs/utils/findLastIndex.js +0 -15
  216. package/lib/commonjs/utils/findLastIndex.js.map +0 -1
  217. package/lib/commonjs/utils/getDistanceForDirection.js +0 -20
  218. package/lib/commonjs/utils/getDistanceForDirection.js.map +0 -1
  219. package/lib/commonjs/utils/getInvertedMultiplier.js +0 -20
  220. package/lib/commonjs/utils/getInvertedMultiplier.js.map +0 -1
  221. package/lib/commonjs/utils/memoize.js +0 -33
  222. package/lib/commonjs/utils/memoize.js.map +0 -1
  223. package/lib/commonjs/utils/useCardAnimation.js +0 -19
  224. package/lib/commonjs/utils/useCardAnimation.js.map +0 -1
  225. package/lib/commonjs/utils/useGestureHandlerRef.js +0 -19
  226. package/lib/commonjs/utils/useGestureHandlerRef.js.map +0 -1
  227. package/lib/commonjs/utils/useKeyboardManager.js +0 -96
  228. package/lib/commonjs/utils/useKeyboardManager.js.map +0 -1
  229. package/lib/commonjs/views/GestureHandler.android.js +0 -17
  230. package/lib/commonjs/views/GestureHandler.android.js.map +0 -1
  231. package/lib/commonjs/views/GestureHandler.ios.js +0 -17
  232. package/lib/commonjs/views/GestureHandler.ios.js.map +0 -1
  233. package/lib/commonjs/views/GestureHandler.js +0 -24
  234. package/lib/commonjs/views/GestureHandler.js.map +0 -1
  235. package/lib/commonjs/views/GestureHandlerNative.js +0 -34
  236. package/lib/commonjs/views/GestureHandlerNative.js.map +0 -1
  237. package/lib/commonjs/views/Header/Header.js +0 -61
  238. package/lib/commonjs/views/Header/Header.js.map +0 -1
  239. package/lib/commonjs/views/Header/HeaderContainer.js +0 -127
  240. package/lib/commonjs/views/Header/HeaderContainer.js.map +0 -1
  241. package/lib/commonjs/views/Header/HeaderSegment.js +0 -139
  242. package/lib/commonjs/views/Header/HeaderSegment.js.map +0 -1
  243. package/lib/commonjs/views/ModalStatusBarManager.js +0 -42
  244. package/lib/commonjs/views/ModalStatusBarManager.js.map +0 -1
  245. package/lib/commonjs/views/Screens.js +0 -44
  246. package/lib/commonjs/views/Screens.js.map +0 -1
  247. package/lib/commonjs/views/Stack/Card.js +0 -469
  248. package/lib/commonjs/views/Stack/Card.js.map +0 -1
  249. package/lib/commonjs/views/Stack/CardContainer.js +0 -259
  250. package/lib/commonjs/views/Stack/CardContainer.js.map +0 -1
  251. package/lib/commonjs/views/Stack/CardSheet.js +0 -54
  252. package/lib/commonjs/views/Stack/CardSheet.js.map +0 -1
  253. package/lib/commonjs/views/Stack/CardStack.js +0 -443
  254. package/lib/commonjs/views/Stack/CardStack.js.map +0 -1
  255. package/lib/commonjs/views/Stack/StackView.js +0 -333
  256. package/lib/commonjs/views/Stack/StackView.js.map +0 -1
  257. package/lib/module/utils/debounce.js.map +0 -1
  258. package/lib/module/utils/memoize.js +0 -27
  259. package/lib/module/utils/memoize.js.map +0 -1
  260. package/lib/module/views/ModalStatusBarManager.js +0 -34
  261. package/lib/module/views/ModalStatusBarManager.js.map +0 -1
  262. package/lib/module/views/Stack/CardSheet.js +0 -46
  263. package/lib/module/views/Stack/CardSheet.js.map +0 -1
  264. package/lib/typescript/src/utils/debounce.d.ts +0 -2
  265. package/lib/typescript/src/utils/debounce.d.ts.map +0 -1
  266. package/lib/typescript/src/utils/memoize.d.ts +0 -2
  267. package/lib/typescript/src/utils/memoize.d.ts.map +0 -1
  268. package/lib/typescript/src/views/ModalStatusBarManager.d.ts +0 -12
  269. package/lib/typescript/src/views/ModalStatusBarManager.d.ts.map +0 -1
  270. package/lib/typescript/src/views/Stack/CardSheet.d.ts +0 -15
  271. package/lib/typescript/src/views/Stack/CardSheet.d.ts.map +0 -1
  272. package/src/utils/debounce.tsx +0 -17
  273. package/src/utils/memoize.tsx +0 -33
  274. package/src/views/ModalStatusBarManager.tsx +0 -50
  275. package/src/views/Stack/CardSheet.tsx +0 -61
@@ -1,20 +1,20 @@
1
1
  import {
2
- Background,
3
2
  getDefaultHeaderHeight,
4
3
  SafeAreaProviderCompat,
5
4
  } from '@amazon-devices/react-navigation__elements';
6
5
  import type {
6
+ LocaleDirection,
7
7
  ParamListBase,
8
8
  Route,
9
9
  StackNavigationState,
10
10
  } from '@amazon-devices/react-navigation__native';
11
- import Color from 'color';
12
11
  import * as React from 'react';
13
12
  import {
14
13
  Animated,
15
- LayoutChangeEvent,
14
+ type LayoutChangeEvent,
16
15
  Platform,
17
16
  StyleSheet,
17
+ View,
18
18
  } from 'react-native';
19
19
  import type { EdgeInsets } from '@amazon-devices/react-native-safe-area-context';
20
20
 
@@ -23,33 +23,45 @@ import {
23
23
  forNoAnimation as forNoAnimationCard,
24
24
  } from '../../TransitionConfigs/CardStyleInterpolators';
25
25
  import {
26
+ BottomSheetAndroid,
26
27
  DefaultTransition,
28
+ FadeFromBottomAndroid,
29
+ FadeFromRightAndroid,
27
30
  ModalFadeTransition,
31
+ ModalSlideFromBottomIOS,
28
32
  ModalTransition,
33
+ RevealFromBottomAndroid,
34
+ ScaleFromCenterAndroid,
35
+ SlideFromLeftIOS,
36
+ SlideFromRightIOS,
29
37
  } from '../../TransitionConfigs/TransitionPresets';
30
38
  import type {
31
39
  Layout,
32
40
  Scene,
33
- StackDescriptor,
41
+ StackAnimationName,
42
+ StackCardStyleInterpolator,
34
43
  StackDescriptorMap,
35
44
  StackHeaderMode,
36
45
  StackNavigationOptions,
46
+ TransitionPreset,
37
47
  } from '../../types';
38
- import findLastIndex from '../../utils/findLastIndex';
39
- import getDistanceForDirection from '../../utils/getDistanceForDirection';
48
+ import { findLastIndex } from '../../utils/findLastIndex';
49
+ import { getDistanceForDirection } from '../../utils/getDistanceForDirection';
50
+ import { getModalRouteKeys } from '../../utils/getModalRoutesKeys';
40
51
  import type { Props as HeaderContainerProps } from '../Header/HeaderContainer';
41
52
  import { MaybeScreen, MaybeScreenContainer } from '../Screens';
42
- import { getIsModalPresentation } from './Card';
43
- import CardContainer from './CardContainer';
53
+ import { CardContainer } from './CardContainer';
44
54
 
45
55
  type GestureValues = {
46
56
  [key: string]: Animated.Value;
47
57
  };
48
58
 
49
59
  type Props = {
60
+ direction: LocaleDirection;
50
61
  insets: EdgeInsets;
51
62
  state: StackNavigationState<ParamListBase>;
52
63
  descriptors: StackDescriptorMap;
64
+ preloadedDescriptors: StackDescriptorMap;
53
65
  routes: Route<string>[];
54
66
  openingRouteKeys: string[];
55
67
  closingRouteKeys: string[];
@@ -59,7 +71,6 @@ type Props = {
59
71
  route: Route<string>;
60
72
  }) => Route<string> | undefined;
61
73
  renderHeader: (props: HeaderContainerProps) => React.ReactNode;
62
- renderScene: (props: { route: Route<string> }) => React.ReactNode;
63
74
  isParentHeaderShown: boolean;
64
75
  isParentModal: boolean;
65
76
  onTransitionStart: (
@@ -79,11 +90,31 @@ type State = {
79
90
  scenes: Scene[];
80
91
  gestures: GestureValues;
81
92
  layout: Layout;
93
+ activeStates: (0 | 1 | Animated.AnimatedInterpolation<0 | 1>)[];
82
94
  headerHeights: Record<string, number>;
83
95
  };
84
96
 
97
+ const NAMED_TRANSITIONS_PRESETS = {
98
+ default: DefaultTransition,
99
+ fade: ModalFadeTransition,
100
+ fade_from_bottom: FadeFromBottomAndroid,
101
+ fade_from_right: FadeFromRightAndroid,
102
+ none: DefaultTransition,
103
+ reveal_from_bottom: RevealFromBottomAndroid,
104
+ scale_from_center: ScaleFromCenterAndroid,
105
+ slide_from_left: SlideFromLeftIOS,
106
+ slide_from_right: SlideFromRightIOS,
107
+ slide_from_bottom: Platform.select({
108
+ ios: ModalSlideFromBottomIOS,
109
+ default: BottomSheetAndroid,
110
+ }),
111
+ } as const satisfies Record<StackAnimationName, TransitionPreset>;
112
+
113
+ const EPSILON = 1e-5;
114
+
85
115
  const STATE_INACTIVE = 0;
86
116
  const STATE_TRANSITIONING_OR_BELOW_TOP = 1;
117
+ const STATE_ON_TOP = 2;
87
118
 
88
119
  const FALLBACK_DESCRIPTOR = Object.freeze({ options: {} });
89
120
 
@@ -107,6 +138,16 @@ const getInterpolationIndex = (scenes: Scene[], index: number) => {
107
138
  return interpolationIndex;
108
139
  };
109
140
 
141
+ const getIsModalPresentation = (
142
+ cardStyleInterpolator: StackCardStyleInterpolator
143
+ ) => {
144
+ return (
145
+ cardStyleInterpolator === forModalPresentationIOS ||
146
+ // Handle custom modal presentation interpolators as well
147
+ cardStyleInterpolator.name === 'forModalPresentationIOS'
148
+ );
149
+ };
150
+
110
151
  const getIsModal = (
111
152
  scene: Scene,
112
153
  interpolationIndex: number,
@@ -158,22 +199,30 @@ const getHeaderHeights = (
158
199
 
159
200
  const getDistanceFromOptions = (
160
201
  layout: Layout,
161
- descriptor?: StackDescriptor
202
+ options: StackNavigationOptions | undefined,
203
+ isRTL: boolean
162
204
  ) => {
163
- const {
164
- presentation,
165
- gestureDirection = presentation === 'modal'
205
+ if (options?.gestureDirection) {
206
+ return getDistanceForDirection(layout, options.gestureDirection, isRTL);
207
+ }
208
+
209
+ const defaultGestureDirection =
210
+ options?.presentation === 'modal'
166
211
  ? ModalTransition.gestureDirection
167
- : DefaultTransition.gestureDirection,
168
- } = (descriptor?.options || {}) as StackNavigationOptions;
212
+ : DefaultTransition.gestureDirection;
169
213
 
170
- return getDistanceForDirection(layout, gestureDirection);
214
+ const gestureDirection = options?.animation
215
+ ? NAMED_TRANSITIONS_PRESETS[options?.animation]?.gestureDirection
216
+ : defaultGestureDirection;
217
+
218
+ return getDistanceForDirection(layout, gestureDirection, isRTL);
171
219
  };
172
220
 
173
221
  const getProgressFromGesture = (
174
222
  gesture: Animated.Value,
175
223
  layout: Layout,
176
- descriptor?: StackDescriptor
224
+ options: StackNavigationOptions | undefined,
225
+ isRTL: boolean
177
226
  ) => {
178
227
  const distance = getDistanceFromOptions(
179
228
  {
@@ -182,7 +231,8 @@ const getProgressFromGesture = (
182
231
  width: Math.max(1, layout.width),
183
232
  height: Math.max(1, layout.height),
184
233
  },
185
- descriptor
234
+ options,
235
+ isRTL
186
236
  );
187
237
 
188
238
  if (distance > 0) {
@@ -198,7 +248,21 @@ const getProgressFromGesture = (
198
248
  });
199
249
  };
200
250
 
201
- export default class CardStack extends React.Component<Props, State> {
251
+ function getDefaultAnimation(animation: StackAnimationName | undefined) {
252
+ // Disable screen transition animation by default on web, windows and macos to match the native behavior
253
+ const excludedPlatforms =
254
+ Platform.OS !== 'web' &&
255
+ Platform.OS !== 'windows' &&
256
+ Platform.OS !== 'macos';
257
+
258
+ return animation ?? (excludedPlatforms ? 'default' : 'none');
259
+ }
260
+
261
+ export function getAnimationEnabled(animation: StackAnimationName | undefined) {
262
+ return getDefaultAnimation(animation) !== 'none';
263
+ }
264
+
265
+ export class CardStack extends React.Component<Props, State> {
202
266
  static getDerivedStateFromProps(
203
267
  props: Props,
204
268
  state: State
@@ -210,164 +274,289 @@ export default class CardStack extends React.Component<Props, State> {
210
274
  return null;
211
275
  }
212
276
 
213
- const gestures = props.routes.reduce<GestureValues>((acc, curr) => {
214
- const descriptor = props.descriptors[curr.key];
215
- const { animationEnabled } = descriptor?.options || {};
277
+ const gestures = [
278
+ ...props.routes,
279
+ ...props.state.preloadedRoutes,
280
+ ].reduce<GestureValues>((acc, curr) => {
281
+ const descriptor =
282
+ props.descriptors[curr.key] || props.preloadedDescriptors[curr.key];
283
+ const { animation } = descriptor?.options || {};
216
284
 
217
285
  acc[curr.key] =
218
286
  state.gestures[curr.key] ||
219
287
  new Animated.Value(
220
- props.openingRouteKeys.includes(curr.key) &&
221
- animationEnabled !== false
222
- ? getDistanceFromOptions(state.layout, descriptor)
288
+ (props.openingRouteKeys.includes(curr.key) &&
289
+ getAnimationEnabled(animation)) ||
290
+ props.state.preloadedRoutes.includes(curr)
291
+ ? getDistanceFromOptions(
292
+ state.layout,
293
+ descriptor?.options,
294
+ props.direction === 'rtl'
295
+ )
223
296
  : 0
224
297
  );
225
298
 
226
299
  return acc;
227
300
  }, {});
228
301
 
229
- const scenes = props.routes.map((route, index, self) => {
230
- const previousRoute = self[index - 1];
231
- const nextRoute = self[index + 1];
232
-
233
- const oldScene = state.scenes[index];
302
+ const modalRouteKeys = getModalRouteKeys(
303
+ [...props.routes, ...props.state.preloadedRoutes],
304
+ {
305
+ ...props.descriptors,
306
+ ...props.preloadedDescriptors,
307
+ }
308
+ );
234
309
 
235
- const currentGesture = gestures[route.key];
236
- const previousGesture = previousRoute
237
- ? gestures[previousRoute.key]
238
- : undefined;
239
- const nextGesture = nextRoute ? gestures[nextRoute.key] : undefined;
310
+ const scenes = [...props.routes, ...props.state.preloadedRoutes].map(
311
+ (route, index, self) => {
312
+ // For preloaded screens, we don't care about the previous and the next screen
313
+ const isPreloaded = props.state.preloadedRoutes.includes(route);
314
+ const previousRoute = isPreloaded ? undefined : self[index - 1];
315
+ const nextRoute = isPreloaded ? undefined : self[index + 1];
316
+
317
+ const oldScene = state.scenes[index];
318
+
319
+ const currentGesture = gestures[route.key];
320
+ const previousGesture = previousRoute
321
+ ? gestures[previousRoute.key]
322
+ : undefined;
323
+ const nextGesture = nextRoute ? gestures[nextRoute.key] : undefined;
324
+
325
+ const descriptor =
326
+ (isPreloaded ? props.preloadedDescriptors : props.descriptors)[
327
+ route.key
328
+ ] ||
329
+ state.descriptors[route.key] ||
330
+ (oldScene ? oldScene.descriptor : FALLBACK_DESCRIPTOR);
331
+
332
+ const nextOptions =
333
+ nextRoute &&
334
+ (
335
+ props.descriptors[nextRoute?.key] ||
336
+ state.descriptors[nextRoute?.key]
337
+ )?.options;
338
+
339
+ const previousOptions =
340
+ previousRoute &&
341
+ (
342
+ props.descriptors[previousRoute?.key] ||
343
+ state.descriptors[previousRoute?.key]
344
+ )?.options;
345
+
346
+ // When a screen is not the last, it should use next screen's transition config
347
+ // Many transitions also animate the previous screen, so using 2 different transitions doesn't look right
348
+ // For example combining a slide and a modal transition would look wrong otherwise
349
+ // With this approach, combining different transition styles in the same navigator mostly looks right
350
+ // This will still be broken when 2 transitions have different idle state (e.g. modal presentation),
351
+ // but the majority of the transitions look alright
352
+ const optionsForTransitionConfig =
353
+ index !== self.length - 1 &&
354
+ nextOptions &&
355
+ nextOptions?.presentation !== 'transparentModal'
356
+ ? nextOptions
357
+ : descriptor.options;
358
+
359
+ // Assume modal if there are already modal screens in the stack
360
+ // or current screen is a modal when no presentation is specified
361
+ const isModal = modalRouteKeys.includes(route.key);
362
+
363
+ const animation = getDefaultAnimation(
364
+ optionsForTransitionConfig.animation
365
+ );
240
366
 
241
- const descriptor =
242
- props.descriptors[route.key] ||
243
- state.descriptors[route.key] ||
244
- (oldScene ? oldScene.descriptor : FALLBACK_DESCRIPTOR);
245
-
246
- const nextDescriptor =
247
- props.descriptors[nextRoute?.key] || state.descriptors[nextRoute?.key];
248
-
249
- const previousDescriptor =
250
- props.descriptors[previousRoute?.key] ||
251
- state.descriptors[previousRoute?.key];
252
-
253
- // When a screen is not the last, it should use next screen's transition config
254
- // Many transitions also animate the previous screen, so using 2 different transitions doesn't look right
255
- // For example combining a slide and a modal transition would look wrong otherwise
256
- // With this approach, combining different transition styles in the same navigator mostly looks right
257
- // This will still be broken when 2 transitions have different idle state (e.g. modal presentation),
258
- // but majority of the transitions look alright
259
- const optionsForTransitionConfig =
260
- index !== self.length - 1 &&
261
- nextDescriptor &&
262
- nextDescriptor.options.presentation !== 'transparentModal'
263
- ? nextDescriptor.options
264
- : descriptor.options;
265
-
266
- let defaultTransitionPreset =
267
- optionsForTransitionConfig.presentation === 'modal'
268
- ? ModalTransition
269
- : optionsForTransitionConfig.presentation === 'transparentModal'
270
- ? ModalFadeTransition
271
- : DefaultTransition;
272
-
273
- const {
274
- animationEnabled = Platform.OS !== 'web' &&
275
- Platform.OS !== 'windows' &&
276
- Platform.OS !== 'macos',
277
- gestureEnabled = Platform.OS === 'ios' && animationEnabled,
278
- gestureDirection = defaultTransitionPreset.gestureDirection,
279
- transitionSpec = defaultTransitionPreset.transitionSpec,
280
- cardStyleInterpolator = animationEnabled === false
281
- ? forNoAnimationCard
282
- : defaultTransitionPreset.cardStyleInterpolator,
283
- headerStyleInterpolator = defaultTransitionPreset.headerStyleInterpolator,
284
- cardOverlayEnabled = (Platform.OS !== 'ios' &&
285
- optionsForTransitionConfig.presentation !== 'transparentModal') ||
286
- getIsModalPresentation(cardStyleInterpolator),
287
- } = optionsForTransitionConfig;
288
-
289
- const headerMode: StackHeaderMode =
290
- descriptor.options.headerMode ??
291
- (!(
292
- optionsForTransitionConfig.presentation === 'modal' ||
293
- optionsForTransitionConfig.presentation === 'transparentModal' ||
294
- nextDescriptor?.options.presentation === 'modal' ||
295
- nextDescriptor?.options.presentation === 'transparentModal' ||
296
- getIsModalPresentation(cardStyleInterpolator)
297
- ) &&
298
- Platform.OS === 'ios' &&
299
- descriptor.options.header === undefined
300
- ? 'float'
301
- : 'screen');
302
-
303
- const scene = {
304
- route,
305
- descriptor: {
306
- ...descriptor,
307
- options: {
308
- ...descriptor.options,
309
- animationEnabled,
310
- cardOverlayEnabled,
311
- cardStyleInterpolator,
312
- gestureDirection,
313
- gestureEnabled,
314
- headerStyleInterpolator,
315
- transitionSpec,
316
- headerMode,
367
+ const isAnimationEnabled = getAnimationEnabled(animation);
368
+
369
+ const transitionPreset =
370
+ animation !== 'default'
371
+ ? NAMED_TRANSITIONS_PRESETS[animation]
372
+ : optionsForTransitionConfig.presentation === 'transparentModal'
373
+ ? ModalFadeTransition
374
+ : optionsForTransitionConfig.presentation === 'modal' || isModal
375
+ ? ModalTransition
376
+ : DefaultTransition;
377
+
378
+ const {
379
+ gestureEnabled = Platform.OS === 'ios' && isAnimationEnabled,
380
+ gestureDirection = transitionPreset.gestureDirection,
381
+ transitionSpec = transitionPreset.transitionSpec,
382
+ cardStyleInterpolator = isAnimationEnabled
383
+ ? transitionPreset.cardStyleInterpolator
384
+ : forNoAnimationCard,
385
+ headerStyleInterpolator = transitionPreset.headerStyleInterpolator,
386
+ cardOverlayEnabled = (Platform.OS !== 'ios' &&
387
+ optionsForTransitionConfig.presentation !== 'transparentModal') ||
388
+ getIsModalPresentation(cardStyleInterpolator),
389
+ } = optionsForTransitionConfig;
390
+
391
+ const headerMode: StackHeaderMode =
392
+ descriptor.options.headerMode ??
393
+ (!(
394
+ optionsForTransitionConfig.presentation === 'modal' ||
395
+ optionsForTransitionConfig.presentation === 'transparentModal' ||
396
+ nextOptions?.presentation === 'modal' ||
397
+ nextOptions?.presentation === 'transparentModal' ||
398
+ getIsModalPresentation(cardStyleInterpolator)
399
+ ) &&
400
+ Platform.OS === 'ios' &&
401
+ descriptor.options.header === undefined
402
+ ? 'float'
403
+ : 'screen');
404
+
405
+ const isRTL = props.direction === 'rtl';
406
+
407
+ const scene = {
408
+ route,
409
+ descriptor: {
410
+ ...descriptor,
411
+ options: {
412
+ ...descriptor.options,
413
+ animation,
414
+ cardOverlayEnabled,
415
+ cardStyleInterpolator,
416
+ gestureDirection,
417
+ gestureEnabled,
418
+ headerStyleInterpolator,
419
+ transitionSpec,
420
+ headerMode,
421
+ },
317
422
  },
318
- },
319
- progress: {
320
- current: getProgressFromGesture(
321
- currentGesture,
322
- state.layout,
323
- descriptor
324
- ),
325
- next:
326
- nextGesture &&
327
- nextDescriptor?.options.presentation !== 'transparentModal'
423
+ progress: {
424
+ current: getProgressFromGesture(
425
+ currentGesture,
426
+ state.layout,
427
+ descriptor.options,
428
+ isRTL
429
+ ),
430
+ next:
431
+ nextGesture && nextOptions?.presentation !== 'transparentModal'
432
+ ? getProgressFromGesture(
433
+ nextGesture,
434
+ state.layout,
435
+ nextOptions,
436
+ isRTL
437
+ )
438
+ : undefined,
439
+ previous: previousGesture
328
440
  ? getProgressFromGesture(
329
- nextGesture,
441
+ previousGesture,
330
442
  state.layout,
331
- nextDescriptor
443
+ previousOptions,
444
+ isRTL
332
445
  )
333
446
  : undefined,
334
- previous: previousGesture
335
- ? getProgressFromGesture(
336
- previousGesture,
337
- state.layout,
338
- previousDescriptor
339
- )
340
- : undefined,
341
- },
342
- __memo: [
343
- state.layout,
344
- descriptor,
345
- nextDescriptor,
346
- previousDescriptor,
347
- currentGesture,
348
- nextGesture,
349
- previousGesture,
350
- ],
351
- };
447
+ },
448
+ __memo: [
449
+ state.layout,
450
+ descriptor,
451
+ nextOptions,
452
+ previousOptions,
453
+ currentGesture,
454
+ nextGesture,
455
+ previousGesture,
456
+ ],
457
+ };
458
+
459
+ if (
460
+ oldScene &&
461
+ scene.__memo.every((it, i) => {
462
+ // @ts-expect-error: we haven't added __memo to the annotation to prevent usage elsewhere
463
+ return oldScene.__memo[i] === it;
464
+ })
465
+ ) {
466
+ return oldScene;
467
+ }
352
468
 
353
- if (
354
- oldScene &&
355
- scene.__memo.every((it, i) => {
356
- // @ts-expect-error: we haven't added __memo to the annotation to prevent usage elsewhere
357
- return oldScene.__memo[i] === it;
358
- })
359
- ) {
360
- return oldScene;
469
+ return scene;
361
470
  }
471
+ );
362
472
 
363
- return scene;
364
- });
473
+ let activeStates = state.activeStates;
474
+
475
+ if (props.routes.length !== state.routes.length) {
476
+ // amznmod_react - change activeScreensLimit from 1 to 2
477
+ // Increase activeScreensLimit to prevent detaching the screen underneath
478
+ // When performing a pop animation, the screen underneath is inactive and has to by mounted
479
+ // This takes a long time and results with a noticeable delay when navigating between screens
480
+ // @ts-ignore - accept kepler as a platform
481
+ let activeScreensLimit = Platform.OS === 'kepler' ? 2 : 1;
482
+
483
+ for (let i = props.routes.length - 1; i >= 0; i--) {
484
+ const { options } = scenes[i].descriptor;
485
+
486
+ const {
487
+ // By default, we don't want to detach the previous screen of the active one for modals
488
+ detachPreviousScreen = options.presentation === 'transparentModal'
489
+ ? false
490
+ : getIsModalPresentation(options.cardStyleInterpolator)
491
+ ? i !==
492
+ findLastIndex(scenes, (scene) => {
493
+ const { cardStyleInterpolator } = scene.descriptor.options;
494
+
495
+ return (
496
+ cardStyleInterpolator === forModalPresentationIOS ||
497
+ cardStyleInterpolator?.name === 'forModalPresentationIOS'
498
+ );
499
+ })
500
+ : true,
501
+ } = options;
502
+
503
+ if (detachPreviousScreen === false) {
504
+ activeScreensLimit++;
505
+ } else {
506
+ // Check at least last 2 screens before stopping
507
+ // This will make sure that screen isn't detached when another screen is animating on top of the transparent one
508
+ // e.g. opaque -> transparent -> opaque
509
+ if (i <= props.routes.length - 2) {
510
+ break;
511
+ }
512
+ }
513
+ }
514
+
515
+ activeStates = props.routes.map((_, index, self) => {
516
+ // The activity state represents state of the screen:
517
+ // 0 - inactive, the screen is detached
518
+ // 1 - transitioning or below the top screen, the screen is mounted but interaction is disabled
519
+ // 2 - on top of the stack, the screen is mounted and interaction is enabled
520
+ let activityState:
521
+ | Animated.AnimatedInterpolation<0 | 1 | 2>
522
+ | 0
523
+ | 1
524
+ | 2;
525
+
526
+ const lastActiveState = state.activeStates[index];
527
+ const activeAfterTransition = index >= self.length - activeScreensLimit;
528
+
529
+ if (lastActiveState === STATE_INACTIVE && !activeAfterTransition) {
530
+ // screen was inactive before and it will still be inactive after the transition
531
+ activityState = STATE_INACTIVE;
532
+ } else {
533
+ const sceneForActivity = scenes[self.length - 1];
534
+ const outputValue =
535
+ index === self.length - 1
536
+ ? STATE_ON_TOP // the screen is on top after the transition
537
+ : activeAfterTransition
538
+ ? STATE_TRANSITIONING_OR_BELOW_TOP // the screen should stay active after the transition, it is not on top but is in activeLimit
539
+ : STATE_INACTIVE; // the screen should be active only during the transition, it is at the edge of activeLimit
540
+
541
+ activityState = sceneForActivity
542
+ ? sceneForActivity.progress.current.interpolate({
543
+ inputRange: [0, 1 - EPSILON, 1],
544
+ outputRange: [1, 1, outputValue],
545
+ extrapolate: 'clamp',
546
+ })
547
+ : STATE_TRANSITIONING_OR_BELOW_TOP;
548
+ }
549
+
550
+ return activityState;
551
+ });
552
+ }
365
553
 
366
554
  return {
367
555
  routes: props.routes,
368
556
  scenes,
369
557
  gestures,
370
558
  descriptors: props.descriptors,
559
+ activeStates,
371
560
  headerHeights: getHeaderHeights(
372
561
  scenes,
373
562
  props.insets,
@@ -388,6 +577,7 @@ export default class CardStack extends React.Component<Props, State> {
388
577
  gestures: {},
389
578
  layout: SafeAreaProviderCompat.initialMetrics.frame,
390
579
  descriptors: this.props.descriptors,
580
+ activeStates: [],
391
581
  // Used when card's header is null and mode is float to make transition
392
582
  // between screens with headers and those without headers smooth.
393
583
  // This is not a great heuristic here. We don't know synchronously
@@ -472,11 +662,11 @@ export default class CardStack extends React.Component<Props, State> {
472
662
  insets,
473
663
  state,
474
664
  routes,
665
+ openingRouteKeys,
475
666
  closingRouteKeys,
476
667
  onOpenRoute,
477
668
  onCloseRoute,
478
669
  renderHeader,
479
- renderScene,
480
670
  isParentHeaderShown,
481
671
  isParentModal,
482
672
  onTransitionStart,
@@ -487,12 +677,12 @@ export default class CardStack extends React.Component<Props, State> {
487
677
  detachInactiveScreens = Platform.OS === 'web' ||
488
678
  Platform.OS === 'android' ||
489
679
  Platform.OS === 'ios' ||
490
- //amznmod_react add kepler platform
491
- //@ts-ignore
680
+ // @ts-ignore - accept kepler as a platform
492
681
  Platform.OS === 'kepler',
493
682
  } = this.props;
494
683
 
495
- const { scenes, layout, gestures, headerHeights } = this.state;
684
+ const { scenes, layout, gestures, activeStates, headerHeights } =
685
+ this.state;
496
686
 
497
687
  const focusedRoute = state.routes[state.index];
498
688
  const focusedHeaderHeight = headerHeights[focusedRoute.key];
@@ -512,41 +702,8 @@ export default class CardStack extends React.Component<Props, State> {
512
702
  return false;
513
703
  });
514
704
 
515
- let activeScreensLimit = 1;
516
-
517
- for (let i = scenes.length - 1; i >= 0; i--) {
518
- const { options } = scenes[i].descriptor;
519
- const {
520
- // By default, we don't want to detach the previous screen of the active one for modals
521
- detachPreviousScreen = options.presentation === 'transparentModal'
522
- ? false
523
- : getIsModalPresentation(options.cardStyleInterpolator)
524
- ? i !==
525
- findLastIndex(scenes, (scene) => {
526
- const { cardStyleInterpolator } = scene.descriptor.options;
527
-
528
- return (
529
- cardStyleInterpolator === forModalPresentationIOS ||
530
- cardStyleInterpolator?.name === 'forModalPresentationIOS'
531
- );
532
- })
533
- : true,
534
- } = options;
535
-
536
- if (detachPreviousScreen === false) {
537
- activeScreensLimit++;
538
- } else {
539
- // Check at least last 2 screens before stopping
540
- // This will make sure that screen isn't detached when another screen is animating on top of the transparent one
541
- // For example, (Opaque -> Transparent -> Opaque)
542
- if (i <= scenes.length - 2) {
543
- break;
544
- }
545
- }
546
- }
547
-
548
- const floatingHeader = (
549
- <React.Fragment key="header">
705
+ return (
706
+ <View style={styles.container}>
550
707
  {renderHeader({
551
708
  mode: 'float',
552
709
  layout,
@@ -563,44 +720,34 @@ export default class CardStack extends React.Component<Props, State> {
563
720
  ],
564
721
  ],
565
722
  })}
566
- </React.Fragment>
567
- );
568
-
569
- return (
570
- <Background>
571
- {isFloatHeaderAbsolute ? null : floatingHeader}
572
723
  <MaybeScreenContainer
573
724
  enabled={detachInactiveScreens}
574
725
  style={styles.container}
575
726
  onLayout={this.handleLayout}
576
727
  >
577
- {routes.map((route, index, self) => {
728
+ {[...routes, ...state.preloadedRoutes].map((route, index) => {
578
729
  const focused = focusedRoute.key === route.key;
579
730
  const gesture = gestures[route.key];
580
731
  const scene = scenes[index];
581
-
582
- // For the screens that shouldn't be active, the value is 0
583
- // For those that should be active, but are not the top screen, the value is 1
584
- // For those on top of the stack and with interaction enabled, the value is 2
585
- // For the old implementation, it stays the same it was
586
- let isScreenActive:
587
- | 2
588
- | 1
589
- | 0 = 1;
590
-
591
- //amznmod_react - Fix off-by-one error in activity state calculation to prevent multiple screens from having same state
592
- if (index < self.length - activeScreensLimit) {
593
- isScreenActive = STATE_INACTIVE;
594
- } else {
595
- isScreenActive = STATE_TRANSITIONING_OR_BELOW_TOP;
732
+ // It is possible that for a short period the route appears in both arrays.
733
+ // Particularly, if the screen is removed with `retain`, then it needs a moment to execute the animation.
734
+ // However, due to the router action, it immediately populates the `preloadedRoutes` array.
735
+ // Practically, the logic below takes care that it is rendered only once.
736
+ const isPreloaded =
737
+ state.preloadedRoutes.includes(route) && !routes.includes(route);
738
+ if (
739
+ state.preloadedRoutes.includes(route) &&
740
+ routes.includes(route) &&
741
+ index >= routes.length
742
+ ) {
743
+ return null;
596
744
  }
597
745
 
598
746
  const {
599
747
  headerShown = true,
600
748
  headerTransparent,
601
- headerStyle,
602
- headerTintColor,
603
749
  freezeOnBlur,
750
+ autoHideHomeIndicator,
604
751
  } = scene.descriptor.options;
605
752
 
606
753
  const safeAreaInsetTop = insets.top;
@@ -611,26 +758,6 @@ export default class CardStack extends React.Component<Props, State> {
611
758
  const headerHeight =
612
759
  headerShown !== false ? headerHeights[route.key] : 0;
613
760
 
614
- let headerDarkContent: boolean | undefined;
615
-
616
- if (headerShown) {
617
- if (typeof headerTintColor === 'string') {
618
- headerDarkContent = Color(headerTintColor).isDark();
619
- } else {
620
- const flattenedHeaderStyle = StyleSheet.flatten(headerStyle);
621
-
622
- if (
623
- flattenedHeaderStyle &&
624
- 'backgroundColor' in flattenedHeaderStyle &&
625
- typeof flattenedHeaderStyle.backgroundColor === 'string'
626
- ) {
627
- headerDarkContent = !Color(
628
- flattenedHeaderStyle.backgroundColor
629
- ).isDark();
630
- }
631
- }
632
- }
633
-
634
761
  // Start from current card and count backwards the number of cards with same interpolation
635
762
  const interpolationIndex = getInterpolationIndex(scenes, index);
636
763
  const isModal = getIsModal(
@@ -647,21 +774,28 @@ export default class CardStack extends React.Component<Props, State> {
647
774
  scenes[index + 1]?.descriptor.options.detachPreviousScreen !==
648
775
  false;
649
776
 
777
+ const activityState = isPreloaded
778
+ ? STATE_INACTIVE
779
+ : activeStates[index];
780
+
650
781
  return (
651
782
  <MaybeScreen
652
783
  key={route.key}
653
- style={StyleSheet.absoluteFill}
784
+ style={[StyleSheet.absoluteFill]}
654
785
  enabled={detachInactiveScreens}
655
- active={isScreenActive}
786
+ active={activityState}
656
787
  freezeOnBlur={freezeOnBlur}
788
+ shouldFreeze={activityState === STATE_INACTIVE && !isPreloaded}
789
+ homeIndicatorHidden={autoHideHomeIndicator}
657
790
  pointerEvents="box-none"
658
791
  >
659
792
  <CardContainer
660
793
  index={index}
661
794
  interpolationIndex={interpolationIndex}
662
795
  modal={isModal}
663
- active={index === self.length - 1}
796
+ active={index === routes.length - 1}
664
797
  focused={focused}
798
+ opening={openingRouteKeys.includes(route.key)}
665
799
  closing={closingRouteKeys.includes(route.key)}
666
800
  layout={layout}
667
801
  gesture={gesture}
@@ -678,25 +812,23 @@ export default class CardStack extends React.Component<Props, State> {
678
812
  onHeaderHeightChange={this.handleHeaderLayout}
679
813
  getPreviousScene={this.getPreviousScene}
680
814
  getFocusedRoute={this.getFocusedRoute}
681
- headerDarkContent={headerDarkContent}
682
815
  hasAbsoluteFloatHeader={
683
816
  isFloatHeaderAbsolute && !headerTransparent
684
817
  }
685
818
  renderHeader={renderHeader}
686
- renderScene={renderScene}
687
819
  onOpenRoute={onOpenRoute}
688
820
  onCloseRoute={onCloseRoute}
689
821
  onTransitionStart={onTransitionStart}
690
822
  onTransitionEnd={onTransitionEnd}
691
823
  isNextScreenTransparent={isNextScreenTransparent}
692
824
  detachCurrentScreen={detachCurrentScreen}
825
+ preloaded={isPreloaded}
693
826
  />
694
827
  </MaybeScreen>
695
828
  );
696
829
  })}
697
830
  </MaybeScreenContainer>
698
- {isFloatHeaderAbsolute ? floatingHeader : null}
699
- </Background>
831
+ </View>
700
832
  );
701
833
  }
702
834
  }
@@ -708,8 +840,8 @@ const styles = StyleSheet.create({
708
840
  absolute: {
709
841
  position: 'absolute',
710
842
  top: 0,
711
- left: 0,
712
- right: 0,
843
+ start: 0,
844
+ end: 0,
713
845
  },
714
846
  floating: {
715
847
  zIndex: 1,