@amazon-devices/react-navigation__stack 2.0.1758683737

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 (242) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +5 -0
  3. package/SystemBundles/ed2637c0b74cd42ce066fca701acc5cb0850978c5296fae5bd715d5e4c67b128.bundle +29321 -0
  4. package/SystemBundles/ed2637c0b74cd42ce066fca701acc5cb0850978c5296fae5bd715d5e4c67b128.map +1 -0
  5. package/SystemModules/amzn__react-navigation__stack-2.modules.txt +95 -0
  6. package/SystemModules/amzn__react-navigation__stack-2.private.modules.txt +258 -0
  7. package/SystemModules/keplerscript-system-bundle-config.json +7 -0
  8. package/THIRD_PARTY_NOTICES.txt +24 -0
  9. package/kepler-compatibility.json +8 -0
  10. package/kepler-transformed-package-info.json +3 -0
  11. package/lib/commonjs/TransitionConfigs/CardStyleInterpolators.js +353 -0
  12. package/lib/commonjs/TransitionConfigs/CardStyleInterpolators.js.map +1 -0
  13. package/lib/commonjs/TransitionConfigs/HeaderStyleInterpolators.js +259 -0
  14. package/lib/commonjs/TransitionConfigs/HeaderStyleInterpolators.js.map +1 -0
  15. package/lib/commonjs/TransitionConfigs/TransitionPresets.js +134 -0
  16. package/lib/commonjs/TransitionConfigs/TransitionPresets.js.map +1 -0
  17. package/lib/commonjs/TransitionConfigs/TransitionSpecs.js +100 -0
  18. package/lib/commonjs/TransitionConfigs/TransitionSpecs.js.map +1 -0
  19. package/lib/commonjs/index.js +69 -0
  20. package/lib/commonjs/index.js.map +1 -0
  21. package/lib/commonjs/navigators/createStackNavigator.js +82 -0
  22. package/lib/commonjs/navigators/createStackNavigator.js.map +1 -0
  23. package/lib/commonjs/types.js +6 -0
  24. package/lib/commonjs/types.js.map +1 -0
  25. package/lib/commonjs/utils/CardAnimationContext.js +11 -0
  26. package/lib/commonjs/utils/CardAnimationContext.js.map +1 -0
  27. package/lib/commonjs/utils/GestureHandlerRefContext.js +11 -0
  28. package/lib/commonjs/utils/GestureHandlerRefContext.js.map +1 -0
  29. package/lib/commonjs/utils/ModalPresentationContext.js +12 -0
  30. package/lib/commonjs/utils/ModalPresentationContext.js.map +1 -0
  31. package/lib/commonjs/utils/conditional.js +32 -0
  32. package/lib/commonjs/utils/conditional.js.map +1 -0
  33. package/lib/commonjs/utils/debounce.js +19 -0
  34. package/lib/commonjs/utils/debounce.js.map +1 -0
  35. package/lib/commonjs/utils/findLastIndex.js +15 -0
  36. package/lib/commonjs/utils/findLastIndex.js.map +1 -0
  37. package/lib/commonjs/utils/getDistanceForDirection.js +20 -0
  38. package/lib/commonjs/utils/getDistanceForDirection.js.map +1 -0
  39. package/lib/commonjs/utils/getInvertedMultiplier.js +20 -0
  40. package/lib/commonjs/utils/getInvertedMultiplier.js.map +1 -0
  41. package/lib/commonjs/utils/memoize.js +33 -0
  42. package/lib/commonjs/utils/memoize.js.map +1 -0
  43. package/lib/commonjs/utils/useCardAnimation.js +19 -0
  44. package/lib/commonjs/utils/useCardAnimation.js.map +1 -0
  45. package/lib/commonjs/utils/useGestureHandlerRef.js +19 -0
  46. package/lib/commonjs/utils/useGestureHandlerRef.js.map +1 -0
  47. package/lib/commonjs/utils/useKeyboardManager.js +96 -0
  48. package/lib/commonjs/utils/useKeyboardManager.js.map +1 -0
  49. package/lib/commonjs/views/GestureHandler.android.js +17 -0
  50. package/lib/commonjs/views/GestureHandler.android.js.map +1 -0
  51. package/lib/commonjs/views/GestureHandler.ios.js +17 -0
  52. package/lib/commonjs/views/GestureHandler.ios.js.map +1 -0
  53. package/lib/commonjs/views/GestureHandler.js +24 -0
  54. package/lib/commonjs/views/GestureHandler.js.map +1 -0
  55. package/lib/commonjs/views/GestureHandlerNative.js +34 -0
  56. package/lib/commonjs/views/GestureHandlerNative.js.map +1 -0
  57. package/lib/commonjs/views/Header/Header.js +61 -0
  58. package/lib/commonjs/views/Header/Header.js.map +1 -0
  59. package/lib/commonjs/views/Header/HeaderContainer.js +127 -0
  60. package/lib/commonjs/views/Header/HeaderContainer.js.map +1 -0
  61. package/lib/commonjs/views/Header/HeaderSegment.js +139 -0
  62. package/lib/commonjs/views/Header/HeaderSegment.js.map +1 -0
  63. package/lib/commonjs/views/ModalStatusBarManager.js +42 -0
  64. package/lib/commonjs/views/ModalStatusBarManager.js.map +1 -0
  65. package/lib/commonjs/views/Screens.js +44 -0
  66. package/lib/commonjs/views/Screens.js.map +1 -0
  67. package/lib/commonjs/views/Stack/Card.js +469 -0
  68. package/lib/commonjs/views/Stack/Card.js.map +1 -0
  69. package/lib/commonjs/views/Stack/CardContainer.js +259 -0
  70. package/lib/commonjs/views/Stack/CardContainer.js.map +1 -0
  71. package/lib/commonjs/views/Stack/CardSheet.js +54 -0
  72. package/lib/commonjs/views/Stack/CardSheet.js.map +1 -0
  73. package/lib/commonjs/views/Stack/CardStack.js +442 -0
  74. package/lib/commonjs/views/Stack/CardStack.js.map +1 -0
  75. package/lib/commonjs/views/Stack/StackView.js +333 -0
  76. package/lib/commonjs/views/Stack/StackView.js.map +1 -0
  77. package/lib/module/TransitionConfigs/CardStyleInterpolators.js +338 -0
  78. package/lib/module/TransitionConfigs/CardStyleInterpolators.js.map +1 -0
  79. package/lib/module/TransitionConfigs/HeaderStyleInterpolators.js +248 -0
  80. package/lib/module/TransitionConfigs/HeaderStyleInterpolators.js.map +1 -0
  81. package/lib/module/TransitionConfigs/TransitionPresets.js +128 -0
  82. package/lib/module/TransitionConfigs/TransitionPresets.js.map +1 -0
  83. package/lib/module/TransitionConfigs/TransitionSpecs.js +94 -0
  84. package/lib/module/TransitionConfigs/TransitionSpecs.js.map +1 -0
  85. package/lib/module/index.js +33 -0
  86. package/lib/module/index.js.map +1 -0
  87. package/lib/module/navigators/createStackNavigator.js +73 -0
  88. package/lib/module/navigators/createStackNavigator.js.map +1 -0
  89. package/lib/module/types.js +2 -0
  90. package/lib/module/types.js.map +1 -0
  91. package/lib/module/utils/CardAnimationContext.js +3 -0
  92. package/lib/module/utils/CardAnimationContext.js.map +1 -0
  93. package/lib/module/utils/GestureHandlerRefContext.js +3 -0
  94. package/lib/module/utils/GestureHandlerRefContext.js.map +1 -0
  95. package/lib/module/utils/ModalPresentationContext.js +4 -0
  96. package/lib/module/utils/ModalPresentationContext.js.map +1 -0
  97. package/lib/module/utils/conditional.js +26 -0
  98. package/lib/module/utils/conditional.js.map +1 -0
  99. package/lib/module/utils/debounce.js +13 -0
  100. package/lib/module/utils/debounce.js.map +1 -0
  101. package/lib/module/utils/findLastIndex.js +9 -0
  102. package/lib/module/utils/findLastIndex.js.map +1 -0
  103. package/lib/module/utils/getDistanceForDirection.js +13 -0
  104. package/lib/module/utils/getDistanceForDirection.js.map +1 -0
  105. package/lib/module/utils/getInvertedMultiplier.js +14 -0
  106. package/lib/module/utils/getInvertedMultiplier.js.map +1 -0
  107. package/lib/module/utils/memoize.js +27 -0
  108. package/lib/module/utils/memoize.js.map +1 -0
  109. package/lib/module/utils/useCardAnimation.js +10 -0
  110. package/lib/module/utils/useCardAnimation.js.map +1 -0
  111. package/lib/module/utils/useGestureHandlerRef.js +10 -0
  112. package/lib/module/utils/useGestureHandlerRef.js.map +1 -0
  113. package/lib/module/utils/useKeyboardManager.js +88 -0
  114. package/lib/module/utils/useKeyboardManager.js.map +1 -0
  115. package/lib/module/views/GestureHandler.android.js +2 -0
  116. package/lib/module/views/GestureHandler.android.js.map +1 -0
  117. package/lib/module/views/GestureHandler.ios.js +2 -0
  118. package/lib/module/views/GestureHandler.ios.js.map +1 -0
  119. package/lib/module/views/GestureHandler.js +16 -0
  120. package/lib/module/views/GestureHandler.js.map +1 -0
  121. package/lib/module/views/GestureHandlerNative.js +14 -0
  122. package/lib/module/views/GestureHandlerNative.js.map +1 -0
  123. package/lib/module/views/Header/Header.js +52 -0
  124. package/lib/module/views/Header/Header.js.map +1 -0
  125. package/lib/module/views/Header/HeaderContainer.js +118 -0
  126. package/lib/module/views/Header/HeaderContainer.js.map +1 -0
  127. package/lib/module/views/Header/HeaderSegment.js +130 -0
  128. package/lib/module/views/Header/HeaderSegment.js.map +1 -0
  129. package/lib/module/views/ModalStatusBarManager.js +34 -0
  130. package/lib/module/views/ModalStatusBarManager.js.map +1 -0
  131. package/lib/module/views/Screens.js +34 -0
  132. package/lib/module/views/Screens.js.map +1 -0
  133. package/lib/module/views/Stack/Card.js +458 -0
  134. package/lib/module/views/Stack/Card.js.map +1 -0
  135. package/lib/module/views/Stack/CardContainer.js +250 -0
  136. package/lib/module/views/Stack/CardContainer.js.map +1 -0
  137. package/lib/module/views/Stack/CardSheet.js +46 -0
  138. package/lib/module/views/Stack/CardSheet.js.map +1 -0
  139. package/lib/module/views/Stack/CardStack.js +432 -0
  140. package/lib/module/views/Stack/CardStack.js.map +1 -0
  141. package/lib/module/views/Stack/StackView.js +323 -0
  142. package/lib/module/views/Stack/StackView.js.map +1 -0
  143. package/lib/typescript/src/TransitionConfigs/CardStyleInterpolators.d.ts +35 -0
  144. package/lib/typescript/src/TransitionConfigs/CardStyleInterpolators.d.ts.map +1 -0
  145. package/lib/typescript/src/TransitionConfigs/HeaderStyleInterpolators.d.ts +23 -0
  146. package/lib/typescript/src/TransitionConfigs/HeaderStyleInterpolators.d.ts.map +1 -0
  147. package/lib/typescript/src/TransitionConfigs/TransitionPresets.d.ts +42 -0
  148. package/lib/typescript/src/TransitionConfigs/TransitionPresets.d.ts.map +1 -0
  149. package/lib/typescript/src/TransitionConfigs/TransitionSpecs.d.ts +36 -0
  150. package/lib/typescript/src/TransitionConfigs/TransitionSpecs.d.ts.map +1 -0
  151. package/lib/typescript/src/index.d.ts +29 -0
  152. package/lib/typescript/src/index.d.ts.map +1 -0
  153. package/lib/typescript/src/navigators/createStackNavigator.d.ts +8 -0
  154. package/lib/typescript/src/navigators/createStackNavigator.d.ts.map +1 -0
  155. package/lib/typescript/src/types.d.ts +481 -0
  156. package/lib/typescript/src/types.d.ts.map +1 -0
  157. package/lib/typescript/src/utils/CardAnimationContext.d.ts +5 -0
  158. package/lib/typescript/src/utils/CardAnimationContext.d.ts.map +1 -0
  159. package/lib/typescript/src/utils/GestureHandlerRefContext.d.ts +4 -0
  160. package/lib/typescript/src/utils/GestureHandlerRefContext.d.ts.map +1 -0
  161. package/lib/typescript/src/utils/ModalPresentationContext.d.ts +4 -0
  162. package/lib/typescript/src/utils/ModalPresentationContext.d.ts.map +1 -0
  163. package/lib/typescript/src/utils/conditional.d.ts +10 -0
  164. package/lib/typescript/src/utils/conditional.d.ts.map +1 -0
  165. package/lib/typescript/src/utils/debounce.d.ts +2 -0
  166. package/lib/typescript/src/utils/debounce.d.ts.map +1 -0
  167. package/lib/typescript/src/utils/findLastIndex.d.ts +2 -0
  168. package/lib/typescript/src/utils/findLastIndex.d.ts.map +1 -0
  169. package/lib/typescript/src/utils/getDistanceForDirection.d.ts +3 -0
  170. package/lib/typescript/src/utils/getDistanceForDirection.d.ts.map +1 -0
  171. package/lib/typescript/src/utils/getInvertedMultiplier.d.ts +3 -0
  172. package/lib/typescript/src/utils/getInvertedMultiplier.d.ts.map +1 -0
  173. package/lib/typescript/src/utils/memoize.d.ts +2 -0
  174. package/lib/typescript/src/utils/memoize.d.ts.map +1 -0
  175. package/lib/typescript/src/utils/useCardAnimation.d.ts +2 -0
  176. package/lib/typescript/src/utils/useCardAnimation.d.ts.map +1 -0
  177. package/lib/typescript/src/utils/useGestureHandlerRef.d.ts +3 -0
  178. package/lib/typescript/src/utils/useGestureHandlerRef.d.ts.map +1 -0
  179. package/lib/typescript/src/utils/useKeyboardManager.d.ts +6 -0
  180. package/lib/typescript/src/utils/useKeyboardManager.d.ts.map +1 -0
  181. package/lib/typescript/src/views/GestureHandler.android.d.ts +2 -0
  182. package/lib/typescript/src/views/GestureHandler.android.d.ts.map +1 -0
  183. package/lib/typescript/src/views/GestureHandler.d.ts +14 -0
  184. package/lib/typescript/src/views/GestureHandler.d.ts.map +1 -0
  185. package/lib/typescript/src/views/GestureHandler.ios.d.ts +2 -0
  186. package/lib/typescript/src/views/GestureHandler.ios.d.ts.map +1 -0
  187. package/lib/typescript/src/views/GestureHandlerNative.d.ts +6 -0
  188. package/lib/typescript/src/views/GestureHandlerNative.d.ts.map +1 -0
  189. package/lib/typescript/src/views/Header/Header.d.ts +5 -0
  190. package/lib/typescript/src/views/Header/Header.d.ts.map +1 -0
  191. package/lib/typescript/src/views/Header/HeaderContainer.d.ts +20 -0
  192. package/lib/typescript/src/views/Header/HeaderContainer.d.ts.map +1 -0
  193. package/lib/typescript/src/views/Header/HeaderSegment.d.ts +14 -0
  194. package/lib/typescript/src/views/Header/HeaderSegment.d.ts.map +1 -0
  195. package/lib/typescript/src/views/ModalStatusBarManager.d.ts +12 -0
  196. package/lib/typescript/src/views/ModalStatusBarManager.d.ts.map +1 -0
  197. package/lib/typescript/src/views/Screens.d.ts +13 -0
  198. package/lib/typescript/src/views/Screens.d.ts.map +1 -0
  199. package/lib/typescript/src/views/Stack/Card.d.ts +76 -0
  200. package/lib/typescript/src/views/Stack/Card.d.ts.map +1 -0
  201. package/lib/typescript/src/views/Stack/CardContainer.d.ts +63 -0
  202. package/lib/typescript/src/views/Stack/CardContainer.d.ts.map +1 -0
  203. package/lib/typescript/src/views/Stack/CardSheet.d.ts +15 -0
  204. package/lib/typescript/src/views/Stack/CardSheet.d.ts.map +1 -0
  205. package/lib/typescript/src/views/Stack/CardStack.d.ts +67 -0
  206. package/lib/typescript/src/views/Stack/CardStack.d.ts.map +1 -0
  207. package/lib/typescript/src/views/Stack/StackView.d.ts +122 -0
  208. package/lib/typescript/src/views/Stack/StackView.d.ts.map +1 -0
  209. package/package.json +1 -0
  210. package/src/TransitionConfigs/CardStyleInterpolators.tsx +394 -0
  211. package/src/TransitionConfigs/HeaderStyleInterpolators.tsx +268 -0
  212. package/src/TransitionConfigs/TransitionPresets.tsx +152 -0
  213. package/src/TransitionConfigs/TransitionSpecs.tsx +96 -0
  214. package/src/index.tsx +51 -0
  215. package/src/navigators/createStackNavigator.tsx +136 -0
  216. package/src/types.tsx +547 -0
  217. package/src/utils/CardAnimationContext.tsx +7 -0
  218. package/src/utils/GestureHandlerRefContext.tsx +5 -0
  219. package/src/utils/ModalPresentationContext.tsx +5 -0
  220. package/src/utils/conditional.tsx +33 -0
  221. package/src/utils/debounce.tsx +17 -0
  222. package/src/utils/findLastIndex.tsx +12 -0
  223. package/src/utils/getDistanceForDirection.tsx +18 -0
  224. package/src/utils/getInvertedMultiplier.tsx +18 -0
  225. package/src/utils/memoize.tsx +33 -0
  226. package/src/utils/useCardAnimation.tsx +15 -0
  227. package/src/utils/useGestureHandlerRef.tsx +15 -0
  228. package/src/utils/useKeyboardManager.tsx +105 -0
  229. package/src/views/GestureHandler.android.tsx +1 -0
  230. package/src/views/GestureHandler.ios.tsx +1 -0
  231. package/src/views/GestureHandler.tsx +23 -0
  232. package/src/views/GestureHandlerNative.tsx +23 -0
  233. package/src/views/Header/Header.tsx +72 -0
  234. package/src/views/Header/HeaderContainer.tsx +186 -0
  235. package/src/views/Header/HeaderSegment.tsx +205 -0
  236. package/src/views/ModalStatusBarManager.tsx +50 -0
  237. package/src/views/Screens.tsx +43 -0
  238. package/src/views/Stack/Card.tsx +628 -0
  239. package/src/views/Stack/CardContainer.tsx +320 -0
  240. package/src/views/Stack/CardSheet.tsx +61 -0
  241. package/src/views/Stack/CardStack.tsx +717 -0
  242. package/src/views/Stack/StackView.tsx +474 -0
@@ -0,0 +1,15 @@
1
+ import * as React from 'react';
2
+
3
+ import CardAnimationContext from './CardAnimationContext';
4
+
5
+ export default function useCardAnimation() {
6
+ const animation = React.useContext(CardAnimationContext);
7
+
8
+ if (animation === undefined) {
9
+ throw new Error(
10
+ "Couldn't find values for card animation. Are you inside a screen in Stack?"
11
+ );
12
+ }
13
+
14
+ return animation;
15
+ }
@@ -0,0 +1,15 @@
1
+ import * as React from 'react';
2
+
3
+ import StackGestureRefContext from './GestureHandlerRefContext';
4
+
5
+ export default function useGestureHandlerRef() {
6
+ const ref = React.useContext(StackGestureRefContext);
7
+
8
+ if (ref === undefined) {
9
+ throw new Error(
10
+ "Couldn't find a ref for gesture handler. Are you inside a screen in Stack?"
11
+ );
12
+ }
13
+
14
+ return ref;
15
+ }
@@ -0,0 +1,105 @@
1
+ import * as React from 'react';
2
+ import { HostComponent, Keyboard, TextInput } from 'react-native';
3
+
4
+ type InputRef = React.ElementRef<HostComponent<unknown>> | undefined;
5
+
6
+ export default function useKeyboardManager(isEnabled: () => boolean) {
7
+ // Numeric id of the previously focused text input
8
+ // When a gesture didn't change the tab, we can restore the focused input with this
9
+ const previouslyFocusedTextInputRef = React.useRef<InputRef>(undefined);
10
+ const startTimestampRef = React.useRef<number>(0);
11
+ const keyboardTimeoutRef = React.useRef<any>();
12
+
13
+ const clearKeyboardTimeout = React.useCallback(() => {
14
+ if (keyboardTimeoutRef.current !== undefined) {
15
+ clearTimeout(keyboardTimeoutRef.current);
16
+ keyboardTimeoutRef.current = undefined;
17
+ }
18
+ }, []);
19
+
20
+ const onPageChangeStart = React.useCallback(() => {
21
+ if (!isEnabled()) {
22
+ return;
23
+ }
24
+
25
+ clearKeyboardTimeout();
26
+
27
+ const input: InputRef = TextInput.State.currentlyFocusedInput();
28
+
29
+ // When a page change begins, blur the currently focused input
30
+ input?.blur();
31
+
32
+ // Store the id of this input so we can refocus it if change was cancelled
33
+ previouslyFocusedTextInputRef.current = input;
34
+
35
+ // Store timestamp for touch start
36
+ startTimestampRef.current = Date.now();
37
+ }, [clearKeyboardTimeout, isEnabled]);
38
+
39
+ const onPageChangeConfirm = React.useCallback(
40
+ (force: boolean) => {
41
+ if (!isEnabled()) {
42
+ return;
43
+ }
44
+
45
+ clearKeyboardTimeout();
46
+
47
+ if (force) {
48
+ // Always dismiss input, even if we don't have a ref to it
49
+ // We might not have the ref if onPageChangeStart was never called
50
+ // This can happen if page change was not from a gesture
51
+ Keyboard.dismiss();
52
+ } else {
53
+ const input = previouslyFocusedTextInputRef.current;
54
+
55
+ // Dismiss the keyboard only if an input was a focused before
56
+ // This makes sure we don't dismiss input on going back and focusing an input
57
+ input?.blur();
58
+ }
59
+
60
+ // Cleanup the ID on successful page change
61
+ previouslyFocusedTextInputRef.current = undefined;
62
+ },
63
+ [clearKeyboardTimeout, isEnabled]
64
+ );
65
+
66
+ const onPageChangeCancel = React.useCallback(() => {
67
+ if (!isEnabled()) {
68
+ return;
69
+ }
70
+
71
+ clearKeyboardTimeout();
72
+
73
+ // The page didn't change, we should restore the focus of text input
74
+ const input = previouslyFocusedTextInputRef.current;
75
+
76
+ if (input) {
77
+ // If the interaction was super short we should make sure keyboard won't hide again.
78
+
79
+ // Too fast input refocus will result only in keyboard flashing on screen and hiding right away.
80
+ // During first ~100ms keyboard will be dismissed no matter what,
81
+ // so we have to make sure it won't interrupt input refocus logic.
82
+ // That's why when the interaction is shorter than 100ms we add delay so it won't hide once again.
83
+ // Subtracting timestamps makes us sure the delay is executed only when needed.
84
+ if (Date.now() - startTimestampRef.current < 100) {
85
+ keyboardTimeoutRef.current = setTimeout(() => {
86
+ input?.focus();
87
+ previouslyFocusedTextInputRef.current = undefined;
88
+ }, 100);
89
+ } else {
90
+ input?.focus();
91
+ previouslyFocusedTextInputRef.current = undefined;
92
+ }
93
+ }
94
+ }, [clearKeyboardTimeout, isEnabled]);
95
+
96
+ React.useEffect(() => {
97
+ return () => clearKeyboardTimeout();
98
+ }, [clearKeyboardTimeout]);
99
+
100
+ return {
101
+ onPageChangeStart,
102
+ onPageChangeConfirm,
103
+ onPageChangeCancel,
104
+ };
105
+ }
@@ -0,0 +1 @@
1
+ export * from './GestureHandlerNative';
@@ -0,0 +1 @@
1
+ export * from './GestureHandlerNative';
@@ -0,0 +1,23 @@
1
+ import * as React from 'react';
2
+ import { View } from 'react-native';
3
+ import type { PanGestureHandlerProperties } from 'react-native-gesture-handler';
4
+
5
+ const Dummy: any = ({ children }: { children: React.ReactNode }) => (
6
+ <>{children}</>
7
+ );
8
+
9
+ export const PanGestureHandler =
10
+ Dummy as React.ComponentType<PanGestureHandlerProperties>;
11
+
12
+ export const GestureHandlerRootView = View;
13
+
14
+ export const GestureState = {
15
+ UNDETERMINED: 0,
16
+ FAILED: 1,
17
+ BEGAN: 2,
18
+ CANCELLED: 3,
19
+ ACTIVE: 4,
20
+ END: 5,
21
+ };
22
+
23
+ export type { PanGestureHandlerGestureEvent } from 'react-native-gesture-handler';
@@ -0,0 +1,23 @@
1
+ import * as React from 'react';
2
+ import {
3
+ PanGestureHandler as PanGestureHandlerNative,
4
+ PanGestureHandlerProperties,
5
+ } from 'react-native-gesture-handler';
6
+
7
+ import GestureHandlerRefContext from '../utils/GestureHandlerRefContext';
8
+
9
+ export function PanGestureHandler(props: PanGestureHandlerProperties) {
10
+ const gestureRef = React.useRef<PanGestureHandlerNative>(null);
11
+
12
+ return (
13
+ <GestureHandlerRefContext.Provider value={gestureRef}>
14
+ <PanGestureHandlerNative {...props} ref={gestureRef} />
15
+ </GestureHandlerRefContext.Provider>
16
+ );
17
+ }
18
+
19
+ export type { PanGestureHandlerGestureEvent } from 'react-native-gesture-handler';
20
+ export {
21
+ GestureHandlerRootView,
22
+ State as GestureState,
23
+ } from 'react-native-gesture-handler';
@@ -0,0 +1,72 @@
1
+ import { getHeaderTitle, HeaderShownContext } from '@amazon-devices/react-navigation__elements';
2
+ import { StackActions } from '@amazon-devices/react-navigation__native';
3
+ import * as React from 'react';
4
+ import { useSafeAreaInsets } from '@amazon-devices/react-native-safe-area-context';
5
+
6
+ import type { StackHeaderProps } from '../../types';
7
+ import debounce from '../../utils/debounce';
8
+ import ModalPresentationContext from '../../utils/ModalPresentationContext';
9
+ import HeaderSegment from './HeaderSegment';
10
+
11
+ export default React.memo(function Header({
12
+ back,
13
+ layout,
14
+ progress,
15
+ options,
16
+ route,
17
+ navigation,
18
+ styleInterpolator,
19
+ }: StackHeaderProps) {
20
+ const insets = useSafeAreaInsets();
21
+
22
+ let previousTitle;
23
+
24
+ // The label for the left back button shows the title of the previous screen
25
+ // If a custom label is specified, we use it, otherwise use previous screen's title
26
+ if (options.headerBackTitle !== undefined) {
27
+ previousTitle = options.headerBackTitle;
28
+ } else if (back) {
29
+ previousTitle = back.title;
30
+ }
31
+
32
+ // eslint-disable-next-line react-hooks/exhaustive-deps
33
+ const goBack = React.useCallback(
34
+ debounce(() => {
35
+ if (navigation.isFocused() && navigation.canGoBack()) {
36
+ navigation.dispatch({
37
+ ...StackActions.pop(),
38
+ source: route.key,
39
+ });
40
+ }
41
+ }, 50),
42
+ [navigation, route.key]
43
+ );
44
+
45
+ const isModal = React.useContext(ModalPresentationContext);
46
+ const isParentHeaderShown = React.useContext(HeaderShownContext);
47
+
48
+ const statusBarHeight =
49
+ options.headerStatusBarHeight !== undefined
50
+ ? options.headerStatusBarHeight
51
+ : isModal || isParentHeaderShown
52
+ ? 0
53
+ : insets.top;
54
+
55
+ return (
56
+ <HeaderSegment
57
+ {...options}
58
+ title={getHeaderTitle(options, route.name)}
59
+ progress={progress}
60
+ layout={layout}
61
+ modal={isModal}
62
+ headerBackTitle={
63
+ options.headerBackTitle !== undefined
64
+ ? options.headerBackTitle
65
+ : previousTitle
66
+ }
67
+ headerStatusBarHeight={statusBarHeight}
68
+ onGoBack={back ? goBack : undefined}
69
+ styleInterpolator={styleInterpolator}
70
+ />
71
+ );
72
+ });
@@ -0,0 +1,186 @@
1
+ import { getHeaderTitle, HeaderBackContext } from '@amazon-devices/react-navigation__elements';
2
+ import {
3
+ NavigationContext,
4
+ NavigationRouteContext,
5
+ ParamListBase,
6
+ Route,
7
+ } from '@amazon-devices/react-navigation__native';
8
+ import * as React from 'react';
9
+ import { Animated, StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
10
+
11
+ import {
12
+ forNoAnimation,
13
+ forSlideLeft,
14
+ forSlideRight,
15
+ forSlideUp,
16
+ } from '../../TransitionConfigs/HeaderStyleInterpolators';
17
+ import type {
18
+ Layout,
19
+ Scene,
20
+ StackHeaderMode,
21
+ StackHeaderProps,
22
+ StackNavigationProp,
23
+ } from '../../types';
24
+ import Header from './Header';
25
+
26
+ export type Props = {
27
+ mode: StackHeaderMode;
28
+ layout: Layout;
29
+ scenes: (Scene | undefined)[];
30
+ getPreviousScene: (props: { route: Route<string> }) => Scene | undefined;
31
+ getFocusedRoute: () => Route<string>;
32
+ onContentHeightChange?: (props: {
33
+ route: Route<string>;
34
+ height: number;
35
+ }) => void;
36
+ style?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
37
+ };
38
+
39
+ export default function HeaderContainer({
40
+ mode,
41
+ scenes,
42
+ layout,
43
+ getPreviousScene,
44
+ getFocusedRoute,
45
+ onContentHeightChange,
46
+ style,
47
+ }: Props) {
48
+ const focusedRoute = getFocusedRoute();
49
+ const parentHeaderBack = React.useContext(HeaderBackContext);
50
+
51
+ return (
52
+ <Animated.View pointerEvents="box-none" style={style}>
53
+ {scenes.slice(-3).map((scene, i, self) => {
54
+ if ((mode === 'screen' && i !== self.length - 1) || !scene) {
55
+ return null;
56
+ }
57
+
58
+ const {
59
+ header,
60
+ headerMode,
61
+ headerShown = true,
62
+ headerTransparent,
63
+ headerStyleInterpolator,
64
+ } = scene.descriptor.options;
65
+
66
+ if (headerMode !== mode || !headerShown) {
67
+ return null;
68
+ }
69
+
70
+ const isFocused = focusedRoute.key === scene.descriptor.route.key;
71
+ const previousScene = getPreviousScene({
72
+ route: scene.descriptor.route,
73
+ });
74
+
75
+ let headerBack = parentHeaderBack;
76
+
77
+ if (previousScene) {
78
+ const { options, route } = previousScene.descriptor;
79
+
80
+ headerBack = previousScene
81
+ ? { title: getHeaderTitle(options, route.name) }
82
+ : parentHeaderBack;
83
+ }
84
+
85
+ // If the screen is next to a headerless screen, we need to make the header appear static
86
+ // This makes the header look like it's moving with the screen
87
+ const previousDescriptor = self[i - 1]?.descriptor;
88
+ const nextDescriptor = self[i + 1]?.descriptor;
89
+
90
+ const {
91
+ headerShown: previousHeaderShown = true,
92
+ headerMode: previousHeaderMode,
93
+ } = previousDescriptor?.options || {};
94
+
95
+ // If any of the next screens don't have a header or header is part of the screen
96
+ // Then we need to move this header offscreen so that it doesn't cover it
97
+ const nextHeaderlessScene = self.slice(i + 1).find((scene) => {
98
+ const {
99
+ headerShown: currentHeaderShown = true,
100
+ headerMode: currentHeaderMode,
101
+ } = scene?.descriptor.options || {};
102
+
103
+ return currentHeaderShown === false || currentHeaderMode === 'screen';
104
+ });
105
+
106
+ const { gestureDirection: nextHeaderlessGestureDirection } =
107
+ nextHeaderlessScene?.descriptor.options || {};
108
+
109
+ const isHeaderStatic =
110
+ ((previousHeaderShown === false || previousHeaderMode === 'screen') &&
111
+ // We still need to animate when coming back from next scene
112
+ // A hacky way to check this is if the next scene exists
113
+ !nextDescriptor) ||
114
+ nextHeaderlessScene;
115
+
116
+ const props: StackHeaderProps = {
117
+ layout,
118
+ back: headerBack,
119
+ progress: scene.progress,
120
+ options: scene.descriptor.options,
121
+ route: scene.descriptor.route,
122
+ navigation: scene.descriptor
123
+ .navigation as StackNavigationProp<ParamListBase>,
124
+ styleInterpolator:
125
+ mode === 'float'
126
+ ? isHeaderStatic
127
+ ? nextHeaderlessGestureDirection === 'vertical' ||
128
+ nextHeaderlessGestureDirection === 'vertical-inverted'
129
+ ? forSlideUp
130
+ : nextHeaderlessGestureDirection === 'horizontal-inverted'
131
+ ? forSlideRight
132
+ : forSlideLeft
133
+ : headerStyleInterpolator
134
+ : forNoAnimation,
135
+ };
136
+
137
+ return (
138
+ <NavigationContext.Provider
139
+ key={scene.descriptor.route.key}
140
+ value={scene.descriptor.navigation}
141
+ >
142
+ <NavigationRouteContext.Provider value={scene.descriptor.route}>
143
+ <View
144
+ onLayout={
145
+ onContentHeightChange
146
+ ? (e) => {
147
+ const { height } = e.nativeEvent.layout;
148
+
149
+ onContentHeightChange({
150
+ route: scene.descriptor.route,
151
+ height,
152
+ });
153
+ }
154
+ : undefined
155
+ }
156
+ pointerEvents={isFocused ? 'box-none' : 'none'}
157
+ accessibilityElementsHidden={!isFocused}
158
+ importantForAccessibility={
159
+ isFocused ? 'auto' : 'no-hide-descendants'
160
+ }
161
+ style={
162
+ // Avoid positioning the focused header absolutely
163
+ // Otherwise accessibility tools don't seem to be able to find it
164
+ (mode === 'float' && !isFocused) || headerTransparent
165
+ ? styles.header
166
+ : null
167
+ }
168
+ >
169
+ {header !== undefined ? header(props) : <Header {...props} />}
170
+ </View>
171
+ </NavigationRouteContext.Provider>
172
+ </NavigationContext.Provider>
173
+ );
174
+ })}
175
+ </Animated.View>
176
+ );
177
+ }
178
+
179
+ const styles = StyleSheet.create({
180
+ header: {
181
+ position: 'absolute',
182
+ top: 0,
183
+ left: 0,
184
+ right: 0,
185
+ },
186
+ });
@@ -0,0 +1,205 @@
1
+ import {
2
+ getDefaultHeaderHeight,
3
+ Header,
4
+ HeaderBackButton,
5
+ HeaderBackButtonProps,
6
+ HeaderTitle,
7
+ } from '@amazon-devices/react-navigation__elements';
8
+ import * as React from 'react';
9
+ import {
10
+ Animated,
11
+ LayoutChangeEvent,
12
+ Platform,
13
+ StyleSheet,
14
+ ViewStyle,
15
+ } from 'react-native';
16
+
17
+ import type {
18
+ Layout,
19
+ SceneProgress,
20
+ StackHeaderOptions,
21
+ StackHeaderStyleInterpolator,
22
+ } from '../../types';
23
+ import memoize from '../../utils/memoize';
24
+
25
+ type Props = Omit<StackHeaderOptions, 'headerStatusBarHeight'> & {
26
+ headerStatusBarHeight: number;
27
+ layout: Layout;
28
+ title: string;
29
+ modal: boolean;
30
+ onGoBack?: () => void;
31
+ progress: SceneProgress;
32
+ styleInterpolator: StackHeaderStyleInterpolator;
33
+ };
34
+
35
+ export default function HeaderSegment(props: Props) {
36
+ const [leftLabelLayout, setLeftLabelLayout] = React.useState<
37
+ Layout | undefined
38
+ >(undefined);
39
+
40
+ const [titleLayout, setTitleLayout] = React.useState<Layout | undefined>(
41
+ undefined
42
+ );
43
+
44
+ const handleTitleLayout = (e: LayoutChangeEvent) => {
45
+ const { height, width } = e.nativeEvent.layout;
46
+
47
+ setTitleLayout((titleLayout) => {
48
+ if (
49
+ titleLayout &&
50
+ height === titleLayout.height &&
51
+ width === titleLayout.width
52
+ ) {
53
+ return titleLayout;
54
+ }
55
+
56
+ return { height, width };
57
+ });
58
+ };
59
+
60
+ const handleLeftLabelLayout = (e: LayoutChangeEvent) => {
61
+ const { height, width } = e.nativeEvent.layout;
62
+
63
+ if (
64
+ leftLabelLayout &&
65
+ height === leftLabelLayout.height &&
66
+ width === leftLabelLayout.width
67
+ ) {
68
+ return;
69
+ }
70
+
71
+ setLeftLabelLayout({ height, width });
72
+ };
73
+
74
+ const getInterpolatedStyle = memoize(
75
+ (
76
+ styleInterpolator: StackHeaderStyleInterpolator,
77
+ layout: Layout,
78
+ current: Animated.AnimatedInterpolation<number>,
79
+ next: Animated.AnimatedInterpolation<number> | undefined,
80
+ titleLayout: Layout | undefined,
81
+ leftLabelLayout: Layout | undefined,
82
+ headerHeight: number
83
+ ) =>
84
+ styleInterpolator({
85
+ current: { progress: current },
86
+ next: next && { progress: next },
87
+ layouts: {
88
+ header: {
89
+ height: headerHeight,
90
+ width: layout.width,
91
+ },
92
+ screen: layout,
93
+ title: titleLayout,
94
+ leftLabel: leftLabelLayout,
95
+ },
96
+ })
97
+ );
98
+
99
+ const {
100
+ progress,
101
+ layout,
102
+ modal,
103
+ onGoBack,
104
+ headerTitle: title,
105
+ headerLeft: left = onGoBack
106
+ ? (props: HeaderBackButtonProps) => <HeaderBackButton {...props} />
107
+ : undefined,
108
+ headerRight: right,
109
+ headerBackImage,
110
+ headerBackTitle,
111
+ headerBackTitleVisible = Platform.OS === 'ios',
112
+ headerTruncatedBackTitle,
113
+ headerBackAccessibilityLabel,
114
+ headerBackTestID,
115
+ headerBackAllowFontScaling,
116
+ headerBackTitleStyle,
117
+ headerTitleContainerStyle,
118
+ headerLeftContainerStyle,
119
+ headerRightContainerStyle,
120
+ headerBackgroundContainerStyle,
121
+ headerStyle: customHeaderStyle,
122
+ headerStatusBarHeight,
123
+ styleInterpolator,
124
+ ...rest
125
+ } = props;
126
+
127
+ const defaultHeight = getDefaultHeaderHeight(
128
+ layout,
129
+ modal,
130
+ headerStatusBarHeight
131
+ );
132
+
133
+ const { height = defaultHeight } = StyleSheet.flatten(
134
+ customHeaderStyle || {}
135
+ ) as ViewStyle;
136
+
137
+ const {
138
+ titleStyle,
139
+ leftButtonStyle,
140
+ leftLabelStyle,
141
+ rightButtonStyle,
142
+ backgroundStyle,
143
+ } = getInterpolatedStyle(
144
+ styleInterpolator,
145
+ layout,
146
+ progress.current,
147
+ progress.next,
148
+ titleLayout,
149
+ headerBackTitle ? leftLabelLayout : undefined,
150
+ typeof height === 'number' ? height : defaultHeight
151
+ );
152
+
153
+ const headerLeft: StackHeaderOptions['headerLeft'] = left
154
+ ? (props) =>
155
+ left({
156
+ ...props,
157
+ backImage: headerBackImage,
158
+ accessibilityLabel: headerBackAccessibilityLabel,
159
+ testID: headerBackTestID,
160
+ allowFontScaling: headerBackAllowFontScaling,
161
+ onPress: onGoBack,
162
+ label: headerBackTitle,
163
+ truncatedLabel: headerTruncatedBackTitle,
164
+ labelStyle: [leftLabelStyle, headerBackTitleStyle],
165
+ onLabelLayout: handleLeftLabelLayout,
166
+ screenLayout: layout,
167
+ titleLayout,
168
+ canGoBack: Boolean(onGoBack),
169
+ })
170
+ : undefined;
171
+
172
+ const headerRight: StackHeaderOptions['headerRight'] = right
173
+ ? (props) =>
174
+ right({
175
+ ...props,
176
+ canGoBack: Boolean(onGoBack),
177
+ })
178
+ : undefined;
179
+
180
+ const headerTitle: StackHeaderOptions['headerTitle'] =
181
+ typeof title !== 'function'
182
+ ? (props) => <HeaderTitle {...props} onLayout={handleTitleLayout} />
183
+ : (props) => title({ ...props, onLayout: handleTitleLayout });
184
+
185
+ return (
186
+ <Header
187
+ modal={modal}
188
+ layout={layout}
189
+ headerTitle={headerTitle}
190
+ headerLeft={headerLeft}
191
+ headerLeftLabelVisible={headerBackTitleVisible}
192
+ headerRight={headerRight}
193
+ headerTitleContainerStyle={[titleStyle, headerTitleContainerStyle]}
194
+ headerLeftContainerStyle={[leftButtonStyle, headerLeftContainerStyle]}
195
+ headerRightContainerStyle={[rightButtonStyle, headerRightContainerStyle]}
196
+ headerBackgroundContainerStyle={[
197
+ backgroundStyle,
198
+ headerBackgroundContainerStyle,
199
+ ]}
200
+ headerStyle={customHeaderStyle}
201
+ headerStatusBarHeight={headerStatusBarHeight}
202
+ {...rest}
203
+ />
204
+ );
205
+ }