-
Notifications
You must be signed in to change notification settings - Fork 3.1k
/
Copy pathHeaderPageLayout.tsx
119 lines (107 loc) · 5.39 KB
/
HeaderPageLayout.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import React, {useMemo} from 'react';
import type {ReactNode} from 'react';
import {View} from 'react-native';
import type {StyleProp, ViewStyle} from 'react-native';
import useNetwork from '@hooks/useNetwork';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useStyleUtils from '@hooks/useStyleUtils';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
import * as Browser from '@libs/Browser';
import type ChildrenProps from '@src/types/utils/ChildrenProps';
import FixedFooter from './FixedFooter';
import HeaderWithBackButton from './HeaderWithBackButton';
import type HeaderWithBackButtonProps from './HeaderWithBackButton/types';
import ScreenWrapper from './ScreenWrapper';
import ScrollView from './ScrollView';
type HeaderPageLayoutProps = ChildrenProps &
HeaderWithBackButtonProps & {
/** The background color to apply in the upper half of the screen. */
backgroundColor?: string;
/** TestID to apply to the whole section container */
testID: string;
/** A fixed footer to display at the bottom of the page. */
footer?: ReactNode;
/** The image to display in the upper half of the screen. */
headerContent?: ReactNode;
/** Style to apply to the header image container */
headerContainerStyles?: StyleProp<ViewStyle>;
/** Style to apply to the ScrollView container */
scrollViewContainerStyles?: StyleProp<ViewStyle>;
/** Style to apply to the children container */
childrenContainerStyles?: StyleProp<ViewStyle>;
/** Style to apply to the whole section container */
style?: StyleProp<ViewStyle>;
/** Whether or not to show the offline indicator */
shouldShowOfflineIndicatorInWideScreen?: boolean;
};
function HeaderPageLayout({
backgroundColor,
children,
footer,
headerContainerStyles,
scrollViewContainerStyles,
childrenContainerStyles,
style,
headerContent,
shouldShowOfflineIndicatorInWideScreen = false,
testID,
...rest
}: HeaderPageLayoutProps) {
const theme = useTheme();
const styles = useThemeStyles();
const StyleUtils = useStyleUtils();
const {windowHeight} = useWindowDimensions();
const {shouldUseNarrowLayout} = useResponsiveLayout();
const {isOffline} = useNetwork();
const appBGColor = StyleUtils.getBackgroundColorStyle(theme.appBG);
const {titleColor, iconFill} = useMemo(() => {
const isColorfulBackground = (backgroundColor ?? theme.appBG) !== theme.appBG && (backgroundColor ?? theme.highlightBG) !== theme.highlightBG;
return {
titleColor: isColorfulBackground ? theme.textColorfulBackground : undefined,
iconFill: isColorfulBackground ? theme.iconColorfulBackground : undefined,
};
}, [backgroundColor, theme.appBG, theme.highlightBG, theme.iconColorfulBackground, theme.textColorfulBackground]);
return (
<ScreenWrapper
style={[StyleUtils.getBackgroundColorStyle(backgroundColor ?? theme.appBG)]}
shouldEnablePickerAvoiding={false}
includeSafeAreaPaddingBottom={false}
offlineIndicatorStyle={[appBGColor]}
testID={testID}
shouldShowOfflineIndicatorInWideScreen={shouldShowOfflineIndicatorInWideScreen}
>
{({safeAreaPaddingBottomStyle}) => (
<>
<HeaderWithBackButton
// eslint-disable-next-line react/jsx-props-no-spreading
{...rest}
titleColor={titleColor}
iconFill={iconFill}
/>
<View style={[styles.flex1, appBGColor, !isOffline && footer ? safeAreaPaddingBottomStyle : {}]}>
{/** Safari on ios/mac has a bug where overscrolling the page scrollview shows green background color. This is a workaround to fix that. https://github.com/Expensify/App/issues/23422 */}
{Browser.isSafari() && (
<View style={styles.dualColorOverscrollSpacer}>
<View style={[styles.flex1, StyleUtils.getBackgroundColorStyle(backgroundColor ?? theme.appBG)]} />
<View style={[shouldUseNarrowLayout ? styles.flex1 : styles.flex3, appBGColor]} />
</View>
)}
<ScrollView contentContainerStyle={[safeAreaPaddingBottomStyle, style, scrollViewContainerStyles]}>
{!Browser.isSafari() && <View style={styles.overscrollSpacer(backgroundColor ?? theme.appBG, windowHeight)} />}
<View style={[styles.alignItemsCenter, styles.justifyContentEnd, StyleUtils.getBackgroundColorStyle(backgroundColor ?? theme.appBG), headerContainerStyles]}>
{headerContent}
</View>
<View style={[styles.pt5, appBGColor, childrenContainerStyles]}>{children}</View>
</ScrollView>
{!!footer && <FixedFooter>{footer}</FixedFooter>}
</View>
</>
)}
</ScreenWrapper>
);
}
HeaderPageLayout.displayName = 'HeaderPageLayout';
export type {HeaderPageLayoutProps};
export default HeaderPageLayout;