@amazon-devices/react-navigation__stack 8.0.9000000001 → 8.0.9000000002

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 (76) hide show
  1. package/kepler-compatibility.json +2 -1
  2. package/lib/module/index.js +0 -34
  3. package/lib/module/views/Stack/CardStack.js.map +1 -1
  4. package/lib/typescript/src/views/Stack/CardStack.d.ts.map +1 -1
  5. package/package.json +1 -1
  6. package/src/index.tsx +0 -56
  7. package/lib/module/TransitionConfigs/CardStyleInterpolators.js +0 -394
  8. package/lib/module/TransitionConfigs/HeaderStyleInterpolators.js +0 -262
  9. package/lib/module/TransitionConfigs/TransitionPresets.js +0 -156
  10. package/lib/module/TransitionConfigs/TransitionSpecs.js +0 -124
  11. package/lib/module/navigators/createStackNavigator.js +0 -71
  12. package/lib/module/types.js +0 -4
  13. package/lib/module/utils/CardAnimationContext.js +0 -5
  14. package/lib/module/utils/GestureHandlerRefContext.js +0 -5
  15. package/lib/module/utils/ModalPresentationContext.js +0 -5
  16. package/lib/module/utils/conditional.js +0 -28
  17. package/lib/module/utils/findLastIndex.js +0 -11
  18. package/lib/module/utils/gestureActivationCriteria.js +0 -60
  19. package/lib/module/utils/getDistanceForDirection.js +0 -15
  20. package/lib/module/utils/getInvertedMultiplier.js +0 -15
  21. package/lib/module/utils/getModalRoutesKeys.js +0 -12
  22. package/lib/module/utils/getShadowStyle.js +0 -24
  23. package/lib/module/utils/throttle.js +0 -14
  24. package/lib/module/utils/useCardAnimation.js +0 -12
  25. package/lib/module/utils/useGestureHandlerRef.js +0 -12
  26. package/lib/module/utils/useKeyboardManager.js +0 -90
  27. package/lib/module/views/GestureHandler.android.js +0 -4
  28. package/lib/module/views/GestureHandler.ios.js +0 -4
  29. package/lib/module/views/GestureHandler.js +0 -21
  30. package/lib/module/views/GestureHandler.kepler.js +0 -4
  31. package/lib/module/views/GestureHandlerNative.js +0 -18
  32. package/lib/module/views/Header/Header.js +0 -56
  33. package/lib/module/views/Header/HeaderContainer.js +0 -128
  34. package/lib/module/views/Header/HeaderSegment.js +0 -142
  35. package/lib/module/views/Screens.js +0 -42
  36. package/lib/module/views/Stack/Card.js +0 -433
  37. package/lib/module/views/Stack/CardA11yWrapper.js +0 -43
  38. package/lib/module/views/Stack/CardContainer.js +0 -276
  39. package/lib/module/views/Stack/CardContent.js +0 -74
  40. package/lib/module/views/Stack/CardStack.js +0 -498
  41. package/lib/module/views/Stack/StackView.js +0 -339
  42. package/src/TransitionConfigs/CardStyleInterpolators.tsx +0 -460
  43. package/src/TransitionConfigs/HeaderStyleInterpolators.tsx +0 -286
  44. package/src/TransitionConfigs/TransitionPresets.tsx +0 -182
  45. package/src/TransitionConfigs/TransitionSpecs.tsx +0 -124
  46. package/src/navigators/createStackNavigator.tsx +0 -120
  47. package/src/types.tsx +0 -639
  48. package/src/utils/CardAnimationContext.tsx +0 -7
  49. package/src/utils/GestureHandlerRefContext.tsx +0 -5
  50. package/src/utils/ModalPresentationContext.tsx +0 -3
  51. package/src/utils/conditional.tsx +0 -33
  52. package/src/utils/findLastIndex.tsx +0 -9
  53. package/src/utils/gestureActivationCriteria.tsx +0 -70
  54. package/src/utils/getDistanceForDirection.tsx +0 -19
  55. package/src/utils/getInvertedMultiplier.tsx +0 -17
  56. package/src/utils/getModalRoutesKeys.ts +0 -21
  57. package/src/utils/getShadowStyle.tsx +0 -37
  58. package/src/utils/throttle.tsx +0 -16
  59. package/src/utils/useCardAnimation.tsx +0 -15
  60. package/src/utils/useGestureHandlerRef.tsx +0 -15
  61. package/src/utils/useKeyboardManager.tsx +0 -103
  62. package/src/views/GestureHandler.android.tsx +0 -1
  63. package/src/views/GestureHandler.ios.tsx +0 -1
  64. package/src/views/GestureHandler.kepler.tsx +0 -1
  65. package/src/views/GestureHandler.tsx +0 -23
  66. package/src/views/GestureHandlerNative.tsx +0 -23
  67. package/src/views/Header/Header.tsx +0 -73
  68. package/src/views/Header/HeaderContainer.tsx +0 -191
  69. package/src/views/Header/HeaderSegment.tsx +0 -203
  70. package/src/views/Screens.tsx +0 -45
  71. package/src/views/Stack/Card.tsx +0 -646
  72. package/src/views/Stack/CardA11yWrapper.tsx +0 -67
  73. package/src/views/Stack/CardContainer.tsx +0 -339
  74. package/src/views/Stack/CardContent.tsx +0 -92
  75. package/src/views/Stack/CardStack.tsx +0 -849
  76. package/src/views/Stack/StackView.tsx +0 -485
@@ -1,70 +0,0 @@
1
- import type { LocaleDirection } from '@amazon-devices/react-navigation__native';
2
-
3
- import type { GestureDirection, Layout } from '../types';
4
- import { getInvertedMultiplier } from './getInvertedMultiplier';
5
-
6
- /**
7
- * The distance of touch start from the edge of the screen where the gesture will be recognized
8
- */
9
- const GESTURE_RESPONSE_DISTANCE_HORIZONTAL = 50;
10
- const GESTURE_RESPONSE_DISTANCE_VERTICAL = 135;
11
-
12
- export const gestureActivationCriteria = ({
13
- direction,
14
- gestureDirection,
15
- gestureResponseDistance,
16
- layout,
17
- }: {
18
- direction: LocaleDirection;
19
- gestureDirection: GestureDirection;
20
- gestureResponseDistance?: number;
21
- layout: Layout;
22
- }) => {
23
- const enableTrackpadTwoFingerGesture = true;
24
-
25
- const distance =
26
- gestureResponseDistance !== undefined
27
- ? gestureResponseDistance
28
- : gestureDirection === 'vertical' ||
29
- gestureDirection === 'vertical-inverted'
30
- ? GESTURE_RESPONSE_DISTANCE_VERTICAL
31
- : GESTURE_RESPONSE_DISTANCE_HORIZONTAL;
32
-
33
- if (gestureDirection === 'vertical') {
34
- return {
35
- maxDeltaX: 15,
36
- minOffsetY: 5,
37
- hitSlop: { bottom: -layout.height + distance },
38
- enableTrackpadTwoFingerGesture,
39
- };
40
- } else if (gestureDirection === 'vertical-inverted') {
41
- return {
42
- maxDeltaX: 15,
43
- minOffsetY: -5,
44
- hitSlop: { top: -layout.height + distance },
45
- enableTrackpadTwoFingerGesture,
46
- };
47
- } else {
48
- const hitSlop = -layout.width + distance;
49
- const invertedMultiplier = getInvertedMultiplier(
50
- gestureDirection,
51
- direction === 'rtl'
52
- );
53
-
54
- if (invertedMultiplier === 1) {
55
- return {
56
- minOffsetX: 5,
57
- maxDeltaY: 20,
58
- hitSlop: { right: hitSlop },
59
- enableTrackpadTwoFingerGesture,
60
- };
61
- } else {
62
- return {
63
- minOffsetX: -5,
64
- maxDeltaY: 20,
65
- hitSlop: { left: hitSlop },
66
- enableTrackpadTwoFingerGesture,
67
- };
68
- }
69
- }
70
- };
@@ -1,19 +0,0 @@
1
- import type { GestureDirection, Layout } from '../types';
2
- import { getInvertedMultiplier } from './getInvertedMultiplier';
3
-
4
- export function getDistanceForDirection(
5
- layout: Layout,
6
- gestureDirection: GestureDirection,
7
- isRTL: boolean
8
- ): number {
9
- const multiplier = getInvertedMultiplier(gestureDirection, isRTL);
10
-
11
- switch (gestureDirection) {
12
- case 'vertical':
13
- case 'vertical-inverted':
14
- return layout.height * multiplier;
15
- case 'horizontal':
16
- case 'horizontal-inverted':
17
- return layout.width * multiplier;
18
- }
19
- }
@@ -1,17 +0,0 @@
1
- import type { GestureDirection } from '../types';
2
-
3
- export function getInvertedMultiplier(
4
- gestureDirection: GestureDirection,
5
- isRTL: boolean
6
- ): 1 | -1 {
7
- switch (gestureDirection) {
8
- case 'vertical':
9
- return 1;
10
- case 'vertical-inverted':
11
- return -1;
12
- case 'horizontal':
13
- return isRTL ? -1 : 1;
14
- case 'horizontal-inverted':
15
- return isRTL ? 1 : -1;
16
- }
17
- }
@@ -1,21 +0,0 @@
1
- import type { Route } from '@amazon-devices/react-navigation__native';
2
-
3
- import type { StackDescriptorMap } from '../types';
4
-
5
- export const getModalRouteKeys = (
6
- routes: Route<string>[],
7
- descriptors: StackDescriptorMap
8
- ) =>
9
- routes.reduce<string[]>((acc, route) => {
10
- const { presentation } = descriptors[route.key]?.options ?? {};
11
-
12
- if (
13
- (acc.length && !presentation) ||
14
- presentation === 'modal' ||
15
- presentation === 'transparentModal'
16
- ) {
17
- acc.push(route.key);
18
- }
19
-
20
- return acc;
21
- }, []);
@@ -1,37 +0,0 @@
1
- import Color from 'color';
2
- import { Platform } from 'react-native';
3
-
4
- type ShadowConfig = {
5
- offset: {
6
- width: number;
7
- height: number;
8
- };
9
- radius: number;
10
- opacity: number;
11
- color?: string;
12
- };
13
-
14
- export function getShadowStyle({
15
- offset,
16
- radius,
17
- opacity,
18
- color = '#000',
19
- }: ShadowConfig) {
20
- const result = Platform.select({
21
- web: {
22
- boxShadow: `${offset.width}px ${offset.height}px ${radius}px ${Color(
23
- color
24
- )
25
- .alpha(opacity)
26
- .toString()}`,
27
- },
28
- default: {
29
- shadowOffset: offset,
30
- shadowRadius: radius,
31
- shadowColor: color,
32
- shadowOpacity: opacity,
33
- },
34
- });
35
-
36
- return result;
37
- }
@@ -1,16 +0,0 @@
1
- export function throttle<T extends (...args: any[]) => void>(
2
- func: T,
3
- duration: number
4
- ): T {
5
- let timeout: ReturnType<typeof setTimeout> | undefined;
6
-
7
- return function (this: unknown, ...args) {
8
- if (timeout == null) {
9
- func.apply(this, args);
10
-
11
- timeout = setTimeout(() => {
12
- timeout = undefined;
13
- }, duration);
14
- }
15
- } as T;
16
- }
@@ -1,15 +0,0 @@
1
- import * as React from 'react';
2
-
3
- import { CardAnimationContext } from './CardAnimationContext';
4
-
5
- export 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
- }
@@ -1,15 +0,0 @@
1
- import * as React from 'react';
2
-
3
- import { GestureHandlerRefContext } from './GestureHandlerRefContext';
4
-
5
- export function useGestureHandlerRef() {
6
- const ref = React.useContext(GestureHandlerRefContext);
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
- }
@@ -1,103 +0,0 @@
1
- import * as React from 'react';
2
- import { type HostInstance, Keyboard, TextInput } from 'react-native';
3
-
4
- export function useKeyboardManager(isEnabled: () => boolean) {
5
- // Numeric id of the previously focused text input
6
- // When a gesture didn't change the tab, we can restore the focused input with this
7
- const previouslyFocusedTextInputRef = React.useRef<HostInstance>(undefined);
8
- const startTimestampRef = React.useRef<number>(0);
9
- const keyboardTimeoutRef = React.useRef<NodeJS.Timeout>(undefined);
10
-
11
- const clearKeyboardTimeout = React.useCallback(() => {
12
- if (keyboardTimeoutRef.current !== undefined) {
13
- clearTimeout(keyboardTimeoutRef.current);
14
- keyboardTimeoutRef.current = undefined;
15
- }
16
- }, []);
17
-
18
- const onPageChangeStart = React.useCallback(() => {
19
- if (!isEnabled()) {
20
- return;
21
- }
22
-
23
- clearKeyboardTimeout();
24
-
25
- const input = TextInput.State.currentlyFocusedInput();
26
-
27
- // When a page change begins, blur the currently focused input
28
- input?.blur();
29
-
30
- // Store the id of this input so we can refocus it if change was cancelled
31
- previouslyFocusedTextInputRef.current = input;
32
-
33
- // Store timestamp for touch start
34
- startTimestampRef.current = Date.now();
35
- }, [clearKeyboardTimeout, isEnabled]);
36
-
37
- const onPageChangeConfirm = React.useCallback(
38
- (force: boolean) => {
39
- if (!isEnabled()) {
40
- return;
41
- }
42
-
43
- clearKeyboardTimeout();
44
-
45
- if (force) {
46
- // Always dismiss input, even if we don't have a ref to it
47
- // We might not have the ref if onPageChangeStart was never called
48
- // This can happen if page change was not from a gesture
49
- Keyboard.dismiss();
50
- } else {
51
- const input = previouslyFocusedTextInputRef.current;
52
-
53
- // Dismiss the keyboard only if an input was a focused before
54
- // This makes sure we don't dismiss input on going back and focusing an input
55
- input?.blur();
56
- }
57
-
58
- // Cleanup the ID on successful page change
59
- previouslyFocusedTextInputRef.current = undefined;
60
- },
61
- [clearKeyboardTimeout, isEnabled]
62
- );
63
-
64
- const onPageChangeCancel = React.useCallback(() => {
65
- if (!isEnabled()) {
66
- return;
67
- }
68
-
69
- clearKeyboardTimeout();
70
-
71
- // The page didn't change, we should restore the focus of text input
72
- const input = previouslyFocusedTextInputRef.current;
73
-
74
- if (input) {
75
- // If the interaction was super short we should make sure keyboard won't hide again.
76
-
77
- // Too fast input refocus will result only in keyboard flashing on screen and hiding right away.
78
- // During first ~100ms keyboard will be dismissed no matter what,
79
- // so we have to make sure it won't interrupt input refocus logic.
80
- // That's why when the interaction is shorter than 100ms we add delay so it won't hide once again.
81
- // Subtracting timestamps makes us sure the delay is executed only when needed.
82
- if (Date.now() - startTimestampRef.current < 100) {
83
- keyboardTimeoutRef.current = setTimeout(() => {
84
- input?.focus();
85
- previouslyFocusedTextInputRef.current = undefined;
86
- }, 100);
87
- } else {
88
- input?.focus();
89
- previouslyFocusedTextInputRef.current = undefined;
90
- }
91
- }
92
- }, [clearKeyboardTimeout, isEnabled]);
93
-
94
- React.useEffect(() => {
95
- return () => clearKeyboardTimeout();
96
- }, [clearKeyboardTimeout]);
97
-
98
- return {
99
- onPageChangeStart,
100
- onPageChangeConfirm,
101
- onPageChangeCancel,
102
- };
103
- }
@@ -1 +0,0 @@
1
- export * from './GestureHandlerNative';
@@ -1 +0,0 @@
1
- export * from './GestureHandlerNative';
@@ -1 +0,0 @@
1
- export * from './GestureHandlerNative';
@@ -1,23 +0,0 @@
1
- import * as React from 'react';
2
- import { View } from 'react-native';
3
- import type { PanGestureHandlerProperties } from '@amazon-devices/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 '@amazon-devices/react-native-gesture-handler';
@@ -1,23 +0,0 @@
1
- import * as React from 'react';
2
- import {
3
- PanGestureHandler as PanGestureHandlerNative,
4
- type PanGestureHandlerProperties,
5
- } from '@amazon-devices/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 '@amazon-devices/react-native-gesture-handler';
20
- export {
21
- GestureHandlerRootView,
22
- State as GestureState,
23
- } from '@amazon-devices/react-native-gesture-handler';
@@ -1,73 +0,0 @@
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 { ModalPresentationContext } from '../../utils/ModalPresentationContext';
8
- import { throttle } from '../../utils/throttle';
9
- import { HeaderSegment } from './HeaderSegment';
10
-
11
- export const Header = 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
- throttle(() => {
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
- backHref={back ? back.href : undefined}
70
- styleInterpolator={styleInterpolator}
71
- />
72
- );
73
- });
@@ -1,191 +0,0 @@
1
- import { getHeaderTitle, HeaderBackContext } from '@amazon-devices/react-navigation__elements';
2
- import {
3
- NavigationContext,
4
- NavigationRouteContext,
5
- type ParamListBase,
6
- type Route,
7
- useLinkBuilder,
8
- } from '@amazon-devices/react-navigation__native';
9
- import * as React from 'react';
10
- import { type StyleProp, StyleSheet, View, type ViewStyle } from 'react-native';
11
-
12
- import {
13
- forNoAnimation,
14
- forSlideLeft,
15
- forSlideRight,
16
- forSlideUp,
17
- } from '../../TransitionConfigs/HeaderStyleInterpolators';
18
- import type {
19
- Layout,
20
- Scene,
21
- StackHeaderMode,
22
- StackHeaderProps,
23
- StackNavigationProp,
24
- } from '../../types';
25
- import { Header } from './Header';
26
-
27
- export type Props = {
28
- mode: StackHeaderMode;
29
- layout: Layout;
30
- scenes: (Scene | undefined)[];
31
- getPreviousScene: (props: { route: Route<string> }) => Scene | undefined;
32
- getFocusedRoute: () => Route<string>;
33
- onContentHeightChange?: (props: {
34
- route: Route<string>;
35
- height: number;
36
- }) => void;
37
- style?: StyleProp<ViewStyle>;
38
- };
39
-
40
- export function HeaderContainer({
41
- mode,
42
- scenes,
43
- layout,
44
- getPreviousScene,
45
- getFocusedRoute,
46
- onContentHeightChange,
47
- style,
48
- }: Props) {
49
- const focusedRoute = getFocusedRoute();
50
- const parentHeaderBack = React.useContext(HeaderBackContext);
51
- const { buildHref } = useLinkBuilder();
52
-
53
- return (
54
- <View pointerEvents="box-none" style={style}>
55
- {/* We render header only on two top-most headers as
56
- a workaround for https://github.com/react-navigation/react-navigation/issues/12456.
57
- If the header is persisted, it might be placed incorrectly when navigating back. */}
58
- {scenes.slice(-2).map((scene, i, self) => {
59
- if ((mode === 'screen' && i !== self.length - 1) || !scene) {
60
- return null;
61
- }
62
-
63
- const {
64
- header,
65
- headerMode,
66
- headerShown = true,
67
- headerTransparent,
68
- headerStyleInterpolator,
69
- } = scene.descriptor.options;
70
-
71
- if (headerMode !== mode || !headerShown) {
72
- return null;
73
- }
74
-
75
- const isFocused = focusedRoute.key === scene.descriptor.route.key;
76
- const previousScene = getPreviousScene({
77
- route: scene.descriptor.route,
78
- });
79
-
80
- let headerBack = parentHeaderBack;
81
-
82
- if (previousScene) {
83
- const { options, route } = previousScene.descriptor;
84
-
85
- headerBack = previousScene
86
- ? {
87
- title: getHeaderTitle(options, route.name),
88
- href: buildHref(route.name, route.params),
89
- }
90
- : parentHeaderBack;
91
- }
92
-
93
- // If the screen is next to a headerless screen, we need to make the header appear static
94
- // This makes the header look like it's moving with the screen
95
- const previousDescriptor = self[i - 1]?.descriptor;
96
- const nextDescriptor = self[i + 1]?.descriptor;
97
-
98
- const {
99
- headerShown: previousHeaderShown = true,
100
- headerMode: previousHeaderMode,
101
- } = previousDescriptor?.options || {};
102
-
103
- // If any of the next screens don't have a header or header is part of the screen
104
- // Then we need to move this header offscreen so that it doesn't cover it
105
- const nextHeaderlessScene = self.slice(i + 1).find((scene) => {
106
- const {
107
- headerShown: currentHeaderShown = true,
108
- headerMode: currentHeaderMode,
109
- } = scene?.descriptor.options || {};
110
-
111
- return currentHeaderShown === false || currentHeaderMode === 'screen';
112
- });
113
-
114
- const { gestureDirection: nextHeaderlessGestureDirection } =
115
- nextHeaderlessScene?.descriptor.options || {};
116
-
117
- const isHeaderStatic =
118
- ((previousHeaderShown === false || previousHeaderMode === 'screen') &&
119
- // We still need to animate when coming back from next scene
120
- // A hacky way to check this is if the next scene exists
121
- !nextDescriptor) ||
122
- nextHeaderlessScene;
123
-
124
- const props: StackHeaderProps = {
125
- layout,
126
- back: headerBack,
127
- progress: scene.progress,
128
- options: scene.descriptor.options,
129
- route: scene.descriptor.route,
130
- navigation: scene.descriptor
131
- .navigation as StackNavigationProp<ParamListBase>,
132
- styleInterpolator:
133
- mode === 'float'
134
- ? isHeaderStatic
135
- ? nextHeaderlessGestureDirection === 'vertical' ||
136
- nextHeaderlessGestureDirection === 'vertical-inverted'
137
- ? forSlideUp
138
- : nextHeaderlessGestureDirection === 'horizontal-inverted'
139
- ? forSlideRight
140
- : forSlideLeft
141
- : headerStyleInterpolator
142
- : forNoAnimation,
143
- };
144
-
145
- return (
146
- <NavigationContext.Provider
147
- key={scene.descriptor.route.key}
148
- value={scene.descriptor.navigation}
149
- >
150
- <NavigationRouteContext.Provider value={scene.descriptor.route}>
151
- <View
152
- onLayout={
153
- onContentHeightChange
154
- ? (e) => {
155
- const { height } = e.nativeEvent.layout;
156
-
157
- onContentHeightChange({
158
- route: scene.descriptor.route,
159
- height,
160
- });
161
- }
162
- : undefined
163
- }
164
- pointerEvents={isFocused ? 'box-none' : 'none'}
165
- aria-hidden={!isFocused}
166
- style={
167
- // Avoid positioning the focused header absolutely
168
- // Otherwise accessibility tools don't seem to be able to find it
169
- (mode === 'float' && !isFocused) || headerTransparent
170
- ? styles.header
171
- : null
172
- }
173
- >
174
- {header !== undefined ? header(props) : <Header {...props} />}
175
- </View>
176
- </NavigationRouteContext.Provider>
177
- </NavigationContext.Provider>
178
- );
179
- })}
180
- </View>
181
- );
182
- }
183
-
184
- const styles = StyleSheet.create({
185
- header: {
186
- position: 'absolute',
187
- top: 0,
188
- start: 0,
189
- end: 0,
190
- },
191
- });