@amazon-devices/react-navigation__stack 7.0.1759135970 → 8.0.9000000000

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 (273) hide show
  1. package/SystemBundles/98ca5eeb45684e3e5615c766e1d3a956fee53d14cd6c2318098c23c210bd76d7.bundle +13464 -0
  2. package/SystemBundles/98ca5eeb45684e3e5615c766e1d3a956fee53d14cd6c2318098c23c210bd76d7.map +4638 -0
  3. package/SystemModules/amzn__react-navigation__stack-8.modules.txt +32 -0
  4. package/SystemModules/amzn__react-navigation__stack-8.private.modules.txt +92 -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 +241 -180
  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/package.json +1 -1
  150. package/src/TransitionConfigs/CardStyleInterpolators.tsx +72 -6
  151. package/src/TransitionConfigs/HeaderStyleInterpolators.tsx +43 -25
  152. package/src/TransitionConfigs/TransitionPresets.tsx +35 -5
  153. package/src/TransitionConfigs/TransitionSpecs.tsx +30 -2
  154. package/src/index.tsx +12 -7
  155. package/src/navigators/createStackNavigator.tsx +47 -63
  156. package/src/types.tsx +116 -24
  157. package/src/utils/CardAnimationContext.tsx +3 -3
  158. package/src/utils/GestureHandlerRefContext.tsx +2 -2
  159. package/src/utils/ModalPresentationContext.tsx +1 -3
  160. package/src/utils/conditional.tsx +1 -1
  161. package/src/utils/findLastIndex.tsx +2 -5
  162. package/src/utils/gestureActivationCriteria.tsx +70 -0
  163. package/src/utils/getDistanceForDirection.tsx +5 -4
  164. package/src/utils/getInvertedMultiplier.tsx +5 -6
  165. package/src/utils/getModalRoutesKeys.ts +21 -0
  166. package/src/utils/getShadowStyle.tsx +37 -0
  167. package/src/utils/throttle.tsx +16 -0
  168. package/src/utils/useCardAnimation.tsx +2 -2
  169. package/src/utils/useGestureHandlerRef.tsx +3 -3
  170. package/src/utils/useKeyboardManager.tsx +5 -7
  171. package/src/views/GestureHandler.kepler.tsx +1 -0
  172. package/src/views/GestureHandler.tsx +2 -2
  173. package/src/views/GestureHandlerNative.tsx +5 -5
  174. package/src/views/Header/Header.tsx +8 -7
  175. package/src/views/Header/HeaderContainer.tsx +23 -18
  176. package/src/views/Header/HeaderSegment.tsx +41 -43
  177. package/src/views/Screens.tsx +4 -2
  178. package/src/views/Stack/Card.tsx +480 -462
  179. package/src/views/Stack/CardA11yWrapper.tsx +67 -0
  180. package/src/views/Stack/CardContainer.tsx +127 -108
  181. package/src/views/Stack/CardContent.tsx +92 -0
  182. package/src/views/Stack/CardStack.tsx +370 -243
  183. package/src/views/Stack/StackView.tsx +73 -62
  184. package/SystemBundles/b598f9dfffcd611d6cd7d6a3c5ab3d66234659a03b40b6579fddb628e61b8313.bundle +0 -28538
  185. package/SystemBundles/b598f9dfffcd611d6cd7d6a3c5ab3d66234659a03b40b6579fddb628e61b8313.map +0 -1
  186. package/SystemModules/amzn__react-navigation__stack-7.modules.txt +0 -95
  187. package/SystemModules/amzn__react-navigation__stack-7.private.modules.txt +0 -185
  188. package/THIRD_PARTY_NOTICES.txt +0 -24
  189. package/lib/commonjs/TransitionConfigs/CardStyleInterpolators.js +0 -353
  190. package/lib/commonjs/TransitionConfigs/CardStyleInterpolators.js.map +0 -1
  191. package/lib/commonjs/TransitionConfigs/HeaderStyleInterpolators.js +0 -259
  192. package/lib/commonjs/TransitionConfigs/HeaderStyleInterpolators.js.map +0 -1
  193. package/lib/commonjs/TransitionConfigs/TransitionPresets.js +0 -134
  194. package/lib/commonjs/TransitionConfigs/TransitionPresets.js.map +0 -1
  195. package/lib/commonjs/TransitionConfigs/TransitionSpecs.js +0 -100
  196. package/lib/commonjs/TransitionConfigs/TransitionSpecs.js.map +0 -1
  197. package/lib/commonjs/index.js +0 -69
  198. package/lib/commonjs/index.js.map +0 -1
  199. package/lib/commonjs/navigators/createStackNavigator.js +0 -82
  200. package/lib/commonjs/navigators/createStackNavigator.js.map +0 -1
  201. package/lib/commonjs/types.js +0 -6
  202. package/lib/commonjs/types.js.map +0 -1
  203. package/lib/commonjs/utils/CardAnimationContext.js +0 -11
  204. package/lib/commonjs/utils/CardAnimationContext.js.map +0 -1
  205. package/lib/commonjs/utils/GestureHandlerRefContext.js +0 -11
  206. package/lib/commonjs/utils/GestureHandlerRefContext.js.map +0 -1
  207. package/lib/commonjs/utils/ModalPresentationContext.js +0 -12
  208. package/lib/commonjs/utils/ModalPresentationContext.js.map +0 -1
  209. package/lib/commonjs/utils/conditional.js +0 -32
  210. package/lib/commonjs/utils/conditional.js.map +0 -1
  211. package/lib/commonjs/utils/debounce.js +0 -19
  212. package/lib/commonjs/utils/debounce.js.map +0 -1
  213. package/lib/commonjs/utils/findLastIndex.js +0 -15
  214. package/lib/commonjs/utils/findLastIndex.js.map +0 -1
  215. package/lib/commonjs/utils/getDistanceForDirection.js +0 -20
  216. package/lib/commonjs/utils/getDistanceForDirection.js.map +0 -1
  217. package/lib/commonjs/utils/getInvertedMultiplier.js +0 -20
  218. package/lib/commonjs/utils/getInvertedMultiplier.js.map +0 -1
  219. package/lib/commonjs/utils/memoize.js +0 -33
  220. package/lib/commonjs/utils/memoize.js.map +0 -1
  221. package/lib/commonjs/utils/useCardAnimation.js +0 -19
  222. package/lib/commonjs/utils/useCardAnimation.js.map +0 -1
  223. package/lib/commonjs/utils/useGestureHandlerRef.js +0 -19
  224. package/lib/commonjs/utils/useGestureHandlerRef.js.map +0 -1
  225. package/lib/commonjs/utils/useKeyboardManager.js +0 -96
  226. package/lib/commonjs/utils/useKeyboardManager.js.map +0 -1
  227. package/lib/commonjs/views/GestureHandler.android.js +0 -17
  228. package/lib/commonjs/views/GestureHandler.android.js.map +0 -1
  229. package/lib/commonjs/views/GestureHandler.ios.js +0 -17
  230. package/lib/commonjs/views/GestureHandler.ios.js.map +0 -1
  231. package/lib/commonjs/views/GestureHandler.js +0 -24
  232. package/lib/commonjs/views/GestureHandler.js.map +0 -1
  233. package/lib/commonjs/views/GestureHandlerNative.js +0 -34
  234. package/lib/commonjs/views/GestureHandlerNative.js.map +0 -1
  235. package/lib/commonjs/views/Header/Header.js +0 -61
  236. package/lib/commonjs/views/Header/Header.js.map +0 -1
  237. package/lib/commonjs/views/Header/HeaderContainer.js +0 -127
  238. package/lib/commonjs/views/Header/HeaderContainer.js.map +0 -1
  239. package/lib/commonjs/views/Header/HeaderSegment.js +0 -139
  240. package/lib/commonjs/views/Header/HeaderSegment.js.map +0 -1
  241. package/lib/commonjs/views/ModalStatusBarManager.js +0 -42
  242. package/lib/commonjs/views/ModalStatusBarManager.js.map +0 -1
  243. package/lib/commonjs/views/Screens.js +0 -44
  244. package/lib/commonjs/views/Screens.js.map +0 -1
  245. package/lib/commonjs/views/Stack/Card.js +0 -469
  246. package/lib/commonjs/views/Stack/Card.js.map +0 -1
  247. package/lib/commonjs/views/Stack/CardContainer.js +0 -259
  248. package/lib/commonjs/views/Stack/CardContainer.js.map +0 -1
  249. package/lib/commonjs/views/Stack/CardSheet.js +0 -54
  250. package/lib/commonjs/views/Stack/CardSheet.js.map +0 -1
  251. package/lib/commonjs/views/Stack/CardStack.js +0 -442
  252. package/lib/commonjs/views/Stack/CardStack.js.map +0 -1
  253. package/lib/commonjs/views/Stack/StackView.js +0 -333
  254. package/lib/commonjs/views/Stack/StackView.js.map +0 -1
  255. package/lib/module/utils/debounce.js.map +0 -1
  256. package/lib/module/utils/memoize.js +0 -27
  257. package/lib/module/utils/memoize.js.map +0 -1
  258. package/lib/module/views/ModalStatusBarManager.js +0 -34
  259. package/lib/module/views/ModalStatusBarManager.js.map +0 -1
  260. package/lib/module/views/Stack/CardSheet.js +0 -46
  261. package/lib/module/views/Stack/CardSheet.js.map +0 -1
  262. package/lib/typescript/src/utils/debounce.d.ts +0 -2
  263. package/lib/typescript/src/utils/debounce.d.ts.map +0 -1
  264. package/lib/typescript/src/utils/memoize.d.ts +0 -2
  265. package/lib/typescript/src/utils/memoize.d.ts.map +0 -1
  266. package/lib/typescript/src/views/ModalStatusBarManager.d.ts +0 -12
  267. package/lib/typescript/src/views/ModalStatusBarManager.d.ts.map +0 -1
  268. package/lib/typescript/src/views/Stack/CardSheet.d.ts +0 -15
  269. package/lib/typescript/src/views/Stack/CardSheet.d.ts.map +0 -1
  270. package/src/utils/debounce.tsx +0 -17
  271. package/src/utils/memoize.tsx +0 -33
  272. package/src/views/ModalStatusBarManager.tsx +0 -50
  273. package/src/views/Stack/CardSheet.tsx +0 -61
@@ -1,46 +1,47 @@
1
+ import type { LocaleDirection } from '@amazon-devices/react-navigation__native';
1
2
  import Color from 'color';
2
3
  import * as React from 'react';
3
4
  import {
4
5
  Animated,
5
6
  InteractionManager,
6
7
  Platform,
7
- StyleProp,
8
+ type StyleProp,
8
9
  StyleSheet,
9
10
  View,
10
- ViewProps,
11
- ViewStyle,
11
+ type ViewStyle,
12
12
  } from 'react-native';
13
13
  import type { EdgeInsets } from '@amazon-devices/react-native-safe-area-context';
14
+ import useLatestCallback from 'use-latest-callback';
14
15
 
15
- import { forModalPresentationIOS } from '../../TransitionConfigs/CardStyleInterpolators';
16
16
  import type {
17
17
  GestureDirection,
18
18
  Layout,
19
- StackCardInterpolationProps,
20
19
  StackCardStyleInterpolator,
21
20
  TransitionSpec,
22
21
  } from '../../types';
23
- import CardAnimationContext from '../../utils/CardAnimationContext';
24
- import getDistanceForDirection from '../../utils/getDistanceForDirection';
25
- import getInvertedMultiplier from '../../utils/getInvertedMultiplier';
26
- import memoize from '../../utils/memoize';
22
+ import { CardAnimationContext } from '../../utils/CardAnimationContext';
23
+ import { gestureActivationCriteria } from '../../utils/gestureActivationCriteria';
24
+ import { getDistanceForDirection } from '../../utils/getDistanceForDirection';
25
+ import { getInvertedMultiplier } from '../../utils/getInvertedMultiplier';
26
+ import { getShadowStyle } from '../../utils/getShadowStyle';
27
27
  import {
28
28
  GestureState,
29
29
  PanGestureHandler,
30
- PanGestureHandlerGestureEvent,
30
+ type PanGestureHandlerGestureEvent,
31
31
  } from '../GestureHandler';
32
- import ModalStatusBarManager from '../ModalStatusBarManager';
33
- import CardSheet, { CardSheetRef } from './CardSheet';
32
+ import { CardContent } from './CardContent';
34
33
 
35
- type Props = ViewProps & {
34
+ type Props = {
35
+ animated: boolean;
36
36
  interpolationIndex: number;
37
+ opening: boolean;
37
38
  closing: boolean;
38
- next?: Animated.AnimatedInterpolation<number>;
39
+ next: Animated.AnimatedInterpolation<number> | undefined;
39
40
  current: Animated.AnimatedInterpolation<number>;
40
41
  gesture: Animated.Value;
41
42
  layout: Layout;
42
43
  insets: EdgeInsets;
43
- headerDarkContent: boolean | undefined;
44
+ direction: LocaleDirection;
44
45
  pageOverflowEnabled: boolean;
45
46
  gestureDirection: GestureDirection;
46
47
  onOpen: () => void;
@@ -50,18 +51,21 @@ type Props = ViewProps & {
50
51
  onGestureCanceled: () => void;
51
52
  onGestureEnd: () => void;
52
53
  children: React.ReactNode;
53
- overlay: (props: {
54
- style: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
55
- }) => React.ReactNode;
54
+ overlay:
55
+ | ((props: {
56
+ style: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
57
+ }) => React.ReactNode)
58
+ | undefined;
56
59
  overlayEnabled: boolean;
57
- shadowEnabled: boolean;
60
+ shadowEnabled: boolean | undefined;
58
61
  gestureEnabled: boolean;
59
62
  gestureResponseDistance?: number;
60
- gestureVelocityImpact: number;
63
+ gestureVelocityImpact: number | undefined;
61
64
  transitionSpec: {
62
65
  open: TransitionSpec;
63
66
  close: TransitionSpec;
64
67
  };
68
+ preloaded: boolean;
65
69
  styleInterpolator: StackCardStyleInterpolator;
66
70
  containerStyle?: StyleProp<ViewStyle>;
67
71
  contentStyle?: StyleProp<ViewStyle>;
@@ -72,440 +76,454 @@ const GESTURE_VELOCITY_IMPACT = 0.3;
72
76
  const TRUE = 1;
73
77
  const FALSE = 0;
74
78
 
75
- /**
76
- * The distance of touch start from the edge of the screen where the gesture will be recognized
77
- */
78
- const GESTURE_RESPONSE_DISTANCE_HORIZONTAL = 50;
79
- const GESTURE_RESPONSE_DISTANCE_VERTICAL = 135;
80
-
81
79
  const useNativeDriver = Platform.OS !== 'web';
82
80
 
83
- const hasOpacityStyle = (style: any) => {
81
+ const hasOpacityStyle = (
82
+ style: Animated.WithAnimatedValue<StyleProp<ViewStyle>>
83
+ ) => {
84
84
  if (style) {
85
85
  const flattenedStyle = StyleSheet.flatten(style);
86
- return flattenedStyle.opacity != null;
86
+
87
+ return 'opacity' in flattenedStyle && flattenedStyle.opacity != null;
87
88
  }
88
89
 
89
90
  return false;
90
91
  };
91
92
 
92
- export default class Card extends React.Component<Props> {
93
- static defaultProps = {
94
- shadowEnabled: false,
95
- gestureEnabled: true,
96
- gestureVelocityImpact: GESTURE_VELOCITY_IMPACT,
97
- overlay: ({
98
- style,
99
- }: {
100
- style: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
101
- }) =>
102
- style ? (
103
- <Animated.View pointerEvents="none" style={[styles.overlay, style]} />
104
- ) : null,
105
- };
106
-
107
- componentDidMount() {
108
- this.animate({ closing: this.props.closing });
109
- this.isCurrentlyMounted = true;
110
- }
111
-
112
- componentDidUpdate(prevProps: Props) {
113
- const { layout, gestureDirection, closing } = this.props;
114
- const { width, height } = layout;
115
-
116
- if (width !== prevProps.layout.width) {
117
- this.layout.width.setValue(width);
118
- }
119
-
120
- if (height !== prevProps.layout.height) {
121
- this.layout.height.setValue(height);
122
- }
123
-
124
- if (gestureDirection !== prevProps.gestureDirection) {
125
- this.inverted.setValue(getInvertedMultiplier(gestureDirection));
126
- }
127
-
128
- const toValue = this.getAnimateToValue(this.props);
129
-
130
- if (
131
- this.getAnimateToValue(prevProps) !== toValue ||
132
- this.lastToValue !== toValue
133
- ) {
134
- // We need to trigger the animation when route was closed
135
- // Thr route might have been closed by a `POP` action or by a gesture
136
- // When route was closed due to a gesture, the animation would've happened already
137
- // It's still important to trigger the animation so that `onClose` is called
138
- // If `onClose` is not called, cleanup step won't be performed for gestures
139
- this.animate({ closing });
140
- }
141
- }
142
-
143
- componentWillUnmount() {
144
- this.props.gesture.stopAnimation();
145
- this.isCurrentlyMounted = false;
146
- this.handleEndInteraction();
93
+ const getAnimateToValue = ({
94
+ closing: isClosing,
95
+ layout: currentLayout,
96
+ gestureDirection: currentGestureDirection,
97
+ direction: currentDirection,
98
+ preloaded: isPreloaded,
99
+ }: {
100
+ closing?: boolean;
101
+ layout: Layout;
102
+ gestureDirection: GestureDirection;
103
+ direction: LocaleDirection;
104
+ preloaded: boolean;
105
+ }) => {
106
+ if (!isClosing && !isPreloaded) {
107
+ return 0;
147
108
  }
148
109
 
149
- private isCurrentlyMounted = false;
150
-
151
- private isClosing = new Animated.Value(FALSE);
152
-
153
- private inverted = new Animated.Value(
154
- getInvertedMultiplier(this.props.gestureDirection)
110
+ return getDistanceForDirection(
111
+ currentLayout,
112
+ currentGestureDirection,
113
+ currentDirection === 'rtl'
155
114
  );
115
+ };
156
116
 
157
- private layout = {
158
- width: new Animated.Value(this.props.layout.width),
159
- height: new Animated.Value(this.props.layout.height),
160
- };
161
-
162
- private isSwiping = new Animated.Value(FALSE);
163
-
164
- private interactionHandle: number | undefined;
165
-
166
- private pendingGestureCallback: number | undefined;
167
-
168
- private lastToValue: number | undefined;
169
-
170
- private animate = ({
171
- closing,
172
- velocity,
173
- }: {
174
- closing: boolean;
175
- velocity?: number;
176
- }) => {
177
- const { gesture, transitionSpec, onOpen, onClose, onTransition } =
178
- this.props;
179
-
180
- const toValue = this.getAnimateToValue({
181
- ...this.props,
182
- closing,
183
- });
184
-
185
- this.lastToValue = toValue;
186
-
187
- this.isClosing.setValue(closing ? TRUE : FALSE);
117
+ const defaultOverlay = ({
118
+ style,
119
+ }: {
120
+ style: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
121
+ }) =>
122
+ style ? (
123
+ <Animated.View pointerEvents="none" style={[styles.overlay, style]} />
124
+ ) : null;
125
+
126
+ function Card({
127
+ shadowEnabled = false,
128
+ gestureEnabled = true,
129
+ gestureVelocityImpact = GESTURE_VELOCITY_IMPACT,
130
+ overlay = defaultOverlay,
131
+ animated,
132
+ interpolationIndex,
133
+ opening,
134
+ closing,
135
+ next,
136
+ current,
137
+ gesture,
138
+ layout,
139
+ insets,
140
+ direction,
141
+ pageOverflowEnabled,
142
+ gestureDirection,
143
+ onOpen,
144
+ onClose,
145
+ onTransition,
146
+ onGestureBegin,
147
+ onGestureCanceled,
148
+ onGestureEnd,
149
+ children,
150
+ overlayEnabled,
151
+ gestureResponseDistance,
152
+ transitionSpec,
153
+ preloaded,
154
+ styleInterpolator,
155
+ containerStyle: customContainerStyle,
156
+ contentStyle,
157
+ }: Props) {
158
+ const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
159
+
160
+ const didInitiallyAnimate = React.useRef(false);
161
+ const lastToValueRef = React.useRef<number | undefined>(undefined);
162
+
163
+ const interactionHandleRef = React.useRef<number | undefined>(undefined);
164
+ const animationHandleRef = React.useRef<number | undefined>(undefined);
165
+ const pendingGestureCallbackRef =
166
+ React.useRef<ReturnType<typeof setTimeout>>(undefined);
167
+
168
+ const [isClosing] = React.useState(() => new Animated.Value(FALSE));
169
+
170
+ const [inverted] = React.useState(
171
+ () =>
172
+ new Animated.Value(
173
+ getInvertedMultiplier(gestureDirection, direction === 'rtl')
174
+ )
175
+ );
188
176
 
189
- const spec = closing ? transitionSpec.close : transitionSpec.open;
177
+ const [layoutAnim] = React.useState(() => ({
178
+ width: new Animated.Value(layout.width),
179
+ height: new Animated.Value(layout.height),
180
+ }));
190
181
 
191
- const animation =
192
- spec.animation === 'spring' ? Animated.spring : Animated.timing;
182
+ const [isSwiping] = React.useState(() => new Animated.Value(FALSE));
193
183
 
194
- this.setPointerEventsEnabled(!closing);
195
- this.handleStartInteraction();
184
+ const onStartInteraction = useLatestCallback(() => {
185
+ if (interactionHandleRef.current === undefined) {
186
+ interactionHandleRef.current =
187
+ InteractionManager.createInteractionHandle();
188
+ }
189
+ });
196
190
 
197
- clearTimeout(this.pendingGestureCallback);
191
+ const onEndInteraction = useLatestCallback(() => {
192
+ if (interactionHandleRef.current !== undefined) {
193
+ InteractionManager.clearInteractionHandle(interactionHandleRef.current);
194
+ interactionHandleRef.current = undefined;
195
+ }
196
+ });
198
197
 
199
- onTransition?.({ closing, gesture: velocity !== undefined });
200
- animation(gesture, {
201
- ...spec.config,
198
+ const animate = useLatestCallback(
199
+ ({
200
+ closing: isClosingParam,
202
201
  velocity,
203
- toValue,
204
- useNativeDriver,
205
- isInteraction: false,
206
- }).start(({ finished }) => {
207
- this.handleEndInteraction();
202
+ }: {
203
+ closing: boolean;
204
+ velocity?: number;
205
+ }) => {
206
+ const toValue = getAnimateToValue({
207
+ closing: isClosingParam,
208
+ layout,
209
+ gestureDirection,
210
+ direction,
211
+ preloaded,
212
+ });
213
+
214
+ lastToValueRef.current = toValue;
215
+ isClosing.setValue(isClosingParam ? TRUE : FALSE);
216
+
217
+ const spec = isClosingParam ? transitionSpec.close : transitionSpec.open;
218
+ const animation =
219
+ spec.animation === 'spring' ? Animated.spring : Animated.timing;
220
+
221
+ clearTimeout(pendingGestureCallbackRef.current);
222
+
223
+ if (animationHandleRef.current !== undefined) {
224
+ cancelAnimationFrame(animationHandleRef.current);
225
+ }
208
226
 
209
- clearTimeout(this.pendingGestureCallback);
227
+ onTransition?.({
228
+ closing: isClosingParam,
229
+ gesture: velocity !== undefined,
230
+ });
210
231
 
211
- if (finished) {
212
- if (closing) {
232
+ const onFinish = () => {
233
+ if (isClosingParam) {
213
234
  onClose();
214
235
  } else {
215
236
  onOpen();
216
237
  }
217
238
 
218
- if (this.isCurrentlyMounted) {
219
- // Make sure to re-open screen if it wasn't removed
220
- this.forceUpdate();
239
+ animationHandleRef.current = requestAnimationFrame(() => {
240
+ if (didInitiallyAnimate.current) {
241
+ // Make sure to re-open screen if it wasn't removed
242
+ forceUpdate();
243
+ }
244
+ });
245
+ };
246
+
247
+ if (animated) {
248
+ onStartInteraction();
249
+ animation(gesture, {
250
+ ...spec.config,
251
+ velocity,
252
+ toValue,
253
+ useNativeDriver,
254
+ isInteraction: false,
255
+ }).start(({ finished }) => {
256
+ onEndInteraction();
257
+ clearTimeout(pendingGestureCallbackRef.current);
258
+
259
+ if (finished) {
260
+ onFinish();
261
+ }
262
+ });
263
+ } else {
264
+ onFinish();
265
+ }
266
+ }
267
+ );
268
+
269
+ const onGestureStateChange = useLatestCallback(
270
+ ({ nativeEvent }: PanGestureHandlerGestureEvent) => {
271
+ switch (nativeEvent.state) {
272
+ case GestureState.ACTIVE:
273
+ isSwiping.setValue(TRUE);
274
+ onStartInteraction();
275
+ onGestureBegin?.();
276
+ break;
277
+ case GestureState.CANCELLED:
278
+ case GestureState.FAILED: {
279
+ isSwiping.setValue(FALSE);
280
+ onEndInteraction();
281
+
282
+ const velocity =
283
+ gestureDirection === 'vertical' ||
284
+ gestureDirection === 'vertical-inverted'
285
+ ? nativeEvent.velocityY
286
+ : nativeEvent.velocityX;
287
+
288
+ animate({
289
+ closing,
290
+ velocity,
291
+ });
292
+
293
+ onGestureCanceled?.();
294
+ break;
295
+ }
296
+ case GestureState.END: {
297
+ isSwiping.setValue(FALSE);
298
+
299
+ let distance;
300
+ let translation;
301
+ let velocity;
302
+
303
+ if (
304
+ gestureDirection === 'vertical' ||
305
+ gestureDirection === 'vertical-inverted'
306
+ ) {
307
+ distance = layout.height;
308
+ translation = nativeEvent.translationY;
309
+ velocity = nativeEvent.velocityY;
310
+ } else {
311
+ distance = layout.width;
312
+ translation = nativeEvent.translationX;
313
+ velocity = nativeEvent.velocityX;
314
+ }
315
+
316
+ const shouldClose =
317
+ (translation + velocity * gestureVelocityImpact) *
318
+ getInvertedMultiplier(gestureDirection, direction === 'rtl') >
319
+ distance / 2
320
+ ? velocity !== 0 || translation !== 0
321
+ : closing;
322
+
323
+ animate({ closing: shouldClose, velocity });
324
+
325
+ if (shouldClose) {
326
+ // We call onClose with a delay to make sure that the animation has already started
327
+ // This will make sure that the state update caused by this doesn't affect start of animation
328
+ pendingGestureCallbackRef.current = setTimeout(() => {
329
+ onClose();
330
+
331
+ // Trigger an update after we dispatch the action to remove the screen
332
+ // This will make sure that we check if the screen didn't get removed so we can cancel the animation
333
+ forceUpdate();
334
+ }, 32);
335
+ }
336
+
337
+ onGestureEnd?.();
338
+ break;
221
339
  }
222
340
  }
223
- });
224
- };
341
+ }
342
+ );
225
343
 
226
- private getAnimateToValue = ({
227
- closing,
228
- layout,
344
+ React.useLayoutEffect(() => {
345
+ layoutAnim.width.setValue(layout.width);
346
+ layoutAnim.height.setValue(layout.height);
347
+ inverted.setValue(
348
+ getInvertedMultiplier(gestureDirection, direction === 'rtl')
349
+ );
350
+ }, [
229
351
  gestureDirection,
230
- }: {
231
- closing?: boolean;
352
+ direction,
353
+ inverted,
354
+ layoutAnim.width,
355
+ layoutAnim.height,
356
+ layout.width,
357
+ layout.height,
358
+ ]);
359
+
360
+ const previousPropsRef = React.useRef<{
361
+ opening: boolean;
362
+ closing: boolean;
232
363
  layout: Layout;
364
+ direction: LocaleDirection;
233
365
  gestureDirection: GestureDirection;
234
- }) => {
235
- if (!closing) {
236
- return 0;
237
- }
366
+ preloaded: boolean;
367
+ } | null>(null);
238
368
 
239
- return getDistanceForDirection(layout, gestureDirection);
240
- };
369
+ React.useEffect(() => {
370
+ return () => {
371
+ onEndInteraction();
241
372
 
242
- private setPointerEventsEnabled = (enabled: boolean) => {
243
- const pointerEvents = enabled ? 'box-none' : 'none';
373
+ if (animationHandleRef.current) {
374
+ cancelAnimationFrame(animationHandleRef.current);
375
+ }
244
376
 
245
- this.ref.current?.setPointerEvents(pointerEvents);
246
- };
377
+ clearTimeout(pendingGestureCallbackRef.current);
378
+ };
247
379
 
248
- private handleStartInteraction = () => {
249
- if (this.interactionHandle === undefined) {
250
- this.interactionHandle = InteractionManager.createInteractionHandle();
251
- }
252
- };
380
+ // We only want to clean up the animation on unmount
381
+ // eslint-disable-next-line react-hooks/exhaustive-deps
382
+ }, []);
383
+
384
+ const timeoutRef = React.useRef<ReturnType<typeof setTimeout> | null>(null);
253
385
 
254
- private handleEndInteraction = () => {
255
- if (this.interactionHandle !== undefined) {
256
- InteractionManager.clearInteractionHandle(this.interactionHandle);
257
- this.interactionHandle = undefined;
386
+ React.useEffect(() => {
387
+ if (preloaded) {
388
+ return;
258
389
  }
259
- };
260
390
 
261
- private handleGestureStateChange = ({
262
- nativeEvent,
263
- }: PanGestureHandlerGestureEvent) => {
264
- const {
265
- layout,
266
- onClose,
267
- onGestureBegin,
268
- onGestureCanceled,
269
- onGestureEnd,
270
- gestureDirection,
271
- gestureVelocityImpact,
272
- } = this.props;
273
-
274
- switch (nativeEvent.state) {
275
- case GestureState.ACTIVE:
276
- this.isSwiping.setValue(TRUE);
277
- this.handleStartInteraction();
278
- onGestureBegin?.();
279
- break;
280
- case GestureState.CANCELLED: {
281
- this.isSwiping.setValue(FALSE);
282
- this.handleEndInteraction();
283
-
284
- const velocity =
285
- gestureDirection === 'vertical' ||
286
- gestureDirection === 'vertical-inverted'
287
- ? nativeEvent.velocityY
288
- : nativeEvent.velocityX;
289
-
290
- this.animate({ closing: this.props.closing, velocity });
291
-
292
- onGestureCanceled?.();
293
- break;
391
+ if (!didInitiallyAnimate.current) {
392
+ // Animate the card in on initial mount
393
+ // Wrap in setTimeout to ensure animation starts after
394
+ // rending of the screen is done. This is especially important
395
+ // in the new architecture
396
+ // cf., https://github.com/react-navigation/react-navigation/issues/12401
397
+ if (timeoutRef.current) {
398
+ clearTimeout(timeoutRef.current);
294
399
  }
295
- case GestureState.END: {
296
- this.isSwiping.setValue(FALSE);
297
-
298
- let distance;
299
- let translation;
300
- let velocity;
301
-
302
- if (
303
- gestureDirection === 'vertical' ||
304
- gestureDirection === 'vertical-inverted'
305
- ) {
306
- distance = layout.height;
307
- translation = nativeEvent.translationY;
308
- velocity = nativeEvent.velocityY;
309
- } else {
310
- distance = layout.width;
311
- translation = nativeEvent.translationX;
312
- velocity = nativeEvent.velocityX;
313
- }
314
-
315
- const closing =
316
- (translation + velocity * gestureVelocityImpact) *
317
- getInvertedMultiplier(gestureDirection) >
318
- distance / 2
319
- ? velocity !== 0 || translation !== 0
320
- : this.props.closing;
321
-
322
- this.animate({ closing, velocity });
323
-
324
- if (closing) {
325
- // We call onClose with a delay to make sure that the animation has already started
326
- // This will make sure that the state update caused by this doesn't affect start of animation
327
- this.pendingGestureCallback = setTimeout(() => {
328
- onClose();
329
-
330
- // Trigger an update after we dispatch the action to remove the screen
331
- // This will make sure that we check if the screen didn't get removed so we can cancel the animation
332
- this.forceUpdate();
333
- }, 32) as any as number;
334
- }
335
-
336
- onGestureEnd?.();
337
- break;
400
+ timeoutRef.current = setTimeout(() => {
401
+ didInitiallyAnimate.current = true;
402
+ animate({ closing });
403
+ }, 0);
404
+ } else {
405
+ const previousOpening = previousPropsRef.current?.opening;
406
+ const previousToValue = previousPropsRef.current
407
+ ? getAnimateToValue(previousPropsRef.current)
408
+ : null;
409
+
410
+ const toValue = getAnimateToValue({
411
+ closing,
412
+ layout,
413
+ gestureDirection,
414
+ direction,
415
+ preloaded,
416
+ });
417
+
418
+ if (previousToValue !== toValue || lastToValueRef.current !== toValue) {
419
+ // We need to trigger the animation when route was closed
420
+ // The route might have been closed by a `POP` action or by a gesture
421
+ // When route was closed due to a gesture, the animation would've happened already
422
+ // It's still important to trigger the animation so that `onClose` is called
423
+ // If `onClose` is not called, cleanup step won't be performed for gestures
424
+ animate({ closing });
425
+ } else if (
426
+ typeof previousOpening === 'boolean' &&
427
+ opening &&
428
+ !previousOpening
429
+ ) {
430
+ // This can happen when screen somewhere below in the stack comes into focus via rearranging
431
+ // Also reset the animated value to make sure that the animation starts from the beginning
432
+ gesture.setValue(
433
+ getDistanceForDirection(layout, gestureDirection, direction === 'rtl')
434
+ );
435
+
436
+ animate({ closing });
338
437
  }
339
438
  }
340
- };
341
439
 
342
- // Memoize this to avoid extra work on re-render
343
- private getInterpolatedStyle = memoize(
344
- (
345
- styleInterpolator: StackCardStyleInterpolator,
346
- animation: StackCardInterpolationProps
347
- ) => styleInterpolator(animation)
348
- );
440
+ previousPropsRef.current = {
441
+ opening,
442
+ closing,
443
+ layout,
444
+ gestureDirection,
445
+ direction,
446
+ preloaded,
447
+ };
448
+ }, [
449
+ animate,
450
+ closing,
451
+ direction,
452
+ gesture,
453
+ gestureDirection,
454
+ layout,
455
+ opening,
456
+ preloaded,
457
+ ]);
349
458
 
350
- // Keep track of the animation context when deps changes.
351
- private getCardAnimation = memoize(
352
- (
353
- interpolationIndex: number,
354
- current: Animated.AnimatedInterpolation<number>,
355
- next: Animated.AnimatedInterpolation<number> | undefined,
356
- layout: Layout,
357
- insetTop: number,
358
- insetRight: number,
359
- insetBottom: number,
360
- insetLeft: number
361
- ) => ({
459
+ const interpolationProps = React.useMemo(
460
+ () => ({
362
461
  index: interpolationIndex,
363
462
  current: { progress: current },
364
463
  next: next && { progress: next },
365
- closing: this.isClosing,
366
- swiping: this.isSwiping,
367
- inverted: this.inverted,
464
+ closing: isClosing,
465
+ swiping: isSwiping,
466
+ inverted,
368
467
  layouts: {
369
468
  screen: layout,
370
469
  },
371
470
  insets: {
372
- top: insetTop,
373
- right: insetRight,
374
- bottom: insetBottom,
375
- left: insetLeft,
471
+ top: insets.top,
472
+ right: insets.right,
473
+ bottom: insets.bottom,
474
+ left: insets.left,
376
475
  },
377
- })
378
- );
379
-
380
- private gestureActivationCriteria() {
381
- const { layout, gestureDirection, gestureResponseDistance } = this.props;
382
- const enableTrackpadTwoFingerGesture = true;
383
-
384
- const distance =
385
- gestureResponseDistance !== undefined
386
- ? gestureResponseDistance
387
- : gestureDirection === 'vertical' ||
388
- gestureDirection === 'vertical-inverted'
389
- ? GESTURE_RESPONSE_DISTANCE_VERTICAL
390
- : GESTURE_RESPONSE_DISTANCE_HORIZONTAL;
391
-
392
- if (gestureDirection === 'vertical') {
393
- return {
394
- maxDeltaX: 15,
395
- minOffsetY: 5,
396
- hitSlop: { bottom: -layout.height + distance },
397
- enableTrackpadTwoFingerGesture,
398
- };
399
- } else if (gestureDirection === 'vertical-inverted') {
400
- return {
401
- maxDeltaX: 15,
402
- minOffsetY: -5,
403
- hitSlop: { top: -layout.height + distance },
404
- enableTrackpadTwoFingerGesture,
405
- };
406
- } else {
407
- const hitSlop = -layout.width + distance;
408
- const invertedMultiplier = getInvertedMultiplier(gestureDirection);
409
-
410
- if (invertedMultiplier === 1) {
411
- return {
412
- minOffsetX: 5,
413
- maxDeltaY: 20,
414
- hitSlop: { right: hitSlop },
415
- enableTrackpadTwoFingerGesture,
416
- };
417
- } else {
418
- return {
419
- minOffsetX: -5,
420
- maxDeltaY: 20,
421
- hitSlop: { left: hitSlop },
422
- enableTrackpadTwoFingerGesture,
423
- };
424
- }
425
- }
426
- }
427
-
428
- private ref = React.createRef<CardSheetRef>();
429
-
430
- render() {
431
- const {
432
- styleInterpolator,
433
- interpolationIndex,
434
- current,
435
- gesture,
436
- next,
437
- layout,
438
- insets,
439
- overlay,
440
- overlayEnabled,
441
- shadowEnabled,
442
- gestureEnabled,
443
- gestureDirection,
444
- pageOverflowEnabled,
445
- headerDarkContent,
446
- children,
447
- containerStyle: customContainerStyle,
448
- contentStyle,
449
- ...rest
450
- } = this.props;
451
-
452
- const interpolationProps = this.getCardAnimation(
476
+ }),
477
+ [
453
478
  interpolationIndex,
454
479
  current,
455
480
  next,
481
+ isClosing,
482
+ isSwiping,
483
+ inverted,
456
484
  layout,
457
485
  insets.top,
458
486
  insets.right,
459
487
  insets.bottom,
460
- insets.left
461
- );
488
+ insets.left,
489
+ ]
490
+ );
462
491
 
463
- const interpolatedStyle = this.getInterpolatedStyle(
464
- styleInterpolator,
465
- interpolationProps
492
+ const { containerStyle, cardStyle, overlayStyle, shadowStyle } =
493
+ React.useMemo(
494
+ () => styleInterpolator(interpolationProps),
495
+ [styleInterpolator, interpolationProps]
466
496
  );
467
497
 
468
- const { containerStyle, cardStyle, overlayStyle, shadowStyle } =
469
- interpolatedStyle;
470
-
471
- const handleGestureEvent = gestureEnabled
472
- ? Animated.event(
473
- [
474
- {
475
- nativeEvent:
476
- gestureDirection === 'vertical' ||
477
- gestureDirection === 'vertical-inverted'
478
- ? { translationY: gesture }
479
- : { translationX: gesture },
480
- },
481
- ],
482
- { useNativeDriver }
483
- )
484
- : undefined;
485
-
486
- const { backgroundColor } = StyleSheet.flatten(contentStyle || {});
487
- const isTransparent =
488
- typeof backgroundColor === 'string'
489
- ? Color(backgroundColor).alpha() === 0
490
- : false;
491
-
492
- return (
493
- <CardAnimationContext.Provider value={interpolationProps}>
494
- {
495
- // StatusBar messes with translucent status bar on Android
496
- // So we should only enable it on iOS
497
- Platform.OS === 'ios' &&
498
- overlayEnabled &&
499
- next &&
500
- getIsModalPresentation(styleInterpolator) ? (
501
- <ModalStatusBarManager
502
- dark={headerDarkContent}
503
- layout={layout}
504
- insets={insets}
505
- style={cardStyle}
506
- />
507
- ) : null
508
- }
498
+ const onGestureEvent = React.useMemo(
499
+ () =>
500
+ gestureEnabled
501
+ ? Animated.event(
502
+ [
503
+ {
504
+ nativeEvent:
505
+ gestureDirection === 'vertical' ||
506
+ gestureDirection === 'vertical-inverted'
507
+ ? { translationY: gesture }
508
+ : { translationX: gesture },
509
+ },
510
+ ],
511
+ { useNativeDriver }
512
+ )
513
+ : undefined,
514
+ [gesture, gestureDirection, gestureEnabled]
515
+ );
516
+
517
+ const { backgroundColor } = StyleSheet.flatten(contentStyle || {});
518
+
519
+ const isTransparent =
520
+ typeof backgroundColor === 'string'
521
+ ? Color(backgroundColor).alpha() === 0
522
+ : false;
523
+
524
+ return (
525
+ <CardAnimationContext.Provider value={interpolationProps}>
526
+ {Platform.OS !== 'web' ? (
509
527
  <Animated.View
510
528
  style={{
511
529
  // This is a dummy style that doesn't actually change anything visually.
@@ -517,75 +535,64 @@ export default class Card extends React.Component<Props> {
517
535
  // Make sure that this view isn't removed. If this view is removed, our style with animated value won't apply
518
536
  collapsable={false}
519
537
  />
520
- <View
521
- pointerEvents="box-none"
522
- // Make sure this view is not removed on the new architecture, as it causes focus loss during navigation on Android.
523
- // This can happen when the view flattening results in different trees - due to `overflow` style changing in a parent.
524
- collapsable={false}
525
- {...rest}
538
+ ) : null}
539
+ {overlayEnabled ? (
540
+ <View pointerEvents="box-none" style={StyleSheet.absoluteFill}>
541
+ {overlay({ style: overlayStyle })}
542
+ </View>
543
+ ) : null}
544
+ <Animated.View
545
+ pointerEvents="box-none"
546
+ style={[styles.container, containerStyle, customContainerStyle]}
547
+ >
548
+ <PanGestureHandler
549
+ enabled={layout.width !== 0 && gestureEnabled}
550
+ onGestureEvent={onGestureEvent}
551
+ onHandlerStateChange={onGestureStateChange}
552
+ {...gestureActivationCriteria({
553
+ layout,
554
+ direction,
555
+ gestureDirection,
556
+ gestureResponseDistance,
557
+ })}
526
558
  >
527
- {overlayEnabled ? (
528
- <View pointerEvents="box-none" style={StyleSheet.absoluteFill}>
529
- {overlay({ style: overlayStyle })}
530
- </View>
531
- ) : null}
532
559
  <Animated.View
533
- style={[styles.container, containerStyle, customContainerStyle]}
534
560
  pointerEvents="box-none"
561
+ needsOffscreenAlphaCompositing={hasOpacityStyle(cardStyle)}
562
+ style={[styles.container, cardStyle]}
535
563
  >
536
- <PanGestureHandler
537
- enabled={layout.width !== 0 && gestureEnabled}
538
- onGestureEvent={handleGestureEvent}
539
- onHandlerStateChange={this.handleGestureStateChange}
540
- {...this.gestureActivationCriteria()}
541
- >
564
+ {shadowEnabled && shadowStyle && !isTransparent ? (
542
565
  <Animated.View
543
- needsOffscreenAlphaCompositing={hasOpacityStyle(cardStyle)}
544
- style={[styles.container, cardStyle]}
545
- >
546
- {shadowEnabled && shadowStyle && !isTransparent ? (
547
- <Animated.View
548
- style={[
549
- styles.shadow,
550
- gestureDirection === 'horizontal'
551
- ? [styles.shadowHorizontal, styles.shadowLeft]
552
- : gestureDirection === 'horizontal-inverted'
553
- ? [styles.shadowHorizontal, styles.shadowRight]
554
- : gestureDirection === 'vertical'
566
+ pointerEvents="none"
567
+ style={[
568
+ styles.shadow,
569
+ gestureDirection === 'horizontal'
570
+ ? [styles.shadowHorizontal, styles.shadowStart]
571
+ : gestureDirection === 'horizontal-inverted'
572
+ ? [styles.shadowHorizontal, styles.shadowEnd]
573
+ : gestureDirection === 'vertical'
555
574
  ? [styles.shadowVertical, styles.shadowTop]
556
575
  : [styles.shadowVertical, styles.shadowBottom],
557
- { backgroundColor },
558
- shadowStyle,
559
- ]}
560
- pointerEvents="none"
561
- />
562
- ) : null}
563
- <CardSheet
564
- ref={this.ref}
565
- enabled={pageOverflowEnabled}
566
- layout={layout}
567
- style={contentStyle}
568
- >
569
- {children}
570
- </CardSheet>
571
- </Animated.View>
572
- </PanGestureHandler>
576
+ { backgroundColor },
577
+ shadowStyle,
578
+ ]}
579
+ />
580
+ ) : null}
581
+ <CardContent
582
+ enabled={pageOverflowEnabled}
583
+ layout={layout}
584
+ style={contentStyle}
585
+ >
586
+ {children}
587
+ </CardContent>
573
588
  </Animated.View>
574
- </View>
575
- </CardAnimationContext.Provider>
576
- );
577
- }
589
+ </PanGestureHandler>
590
+ </Animated.View>
591
+ </CardAnimationContext.Provider>
592
+ );
578
593
  }
579
594
 
580
- export const getIsModalPresentation = (
581
- cardStyleInterpolator: StackCardStyleInterpolator
582
- ) => {
583
- return (
584
- cardStyleInterpolator === forModalPresentationIOS ||
585
- // Handle custom modal presentation interpolators as well
586
- cardStyleInterpolator.name === 'forModalPresentationIOS'
587
- );
588
- };
595
+ export { Card };
589
596
 
590
597
  const styles = StyleSheet.create({
591
598
  container: {
@@ -597,27 +604,38 @@ const styles = StyleSheet.create({
597
604
  },
598
605
  shadow: {
599
606
  position: 'absolute',
600
- shadowRadius: 5,
601
- shadowColor: '#000',
602
- shadowOpacity: 0.3,
603
607
  },
604
608
  shadowHorizontal: {
605
609
  top: 0,
606
610
  bottom: 0,
607
611
  width: 3,
608
- shadowOffset: { width: -1, height: 1 },
612
+ ...getShadowStyle({
613
+ offset: {
614
+ width: -1,
615
+ height: 1,
616
+ },
617
+ radius: 5,
618
+ opacity: 0.3,
619
+ }),
609
620
  },
610
- shadowLeft: {
611
- left: 0,
621
+ shadowStart: {
622
+ start: 0,
612
623
  },
613
- shadowRight: {
614
- right: 0,
624
+ shadowEnd: {
625
+ end: 0,
615
626
  },
616
627
  shadowVertical: {
617
- left: 0,
618
- right: 0,
628
+ start: 0,
629
+ end: 0,
619
630
  height: 3,
620
- shadowOffset: { width: 1, height: -1 },
631
+ ...getShadowStyle({
632
+ offset: {
633
+ width: 1,
634
+ height: -1,
635
+ },
636
+ radius: 5,
637
+ opacity: 0.3,
638
+ }),
621
639
  },
622
640
  shadowTop: {
623
641
  top: 0,