xref: /expo/home/components/Views.tsx (revision 94dbd83c)
1import { useTheme } from '@react-navigation/native';
2import * as React from 'react';
3import { ScrollViewProps, View } from 'react-native';
4import { ScrollView } from 'react-native-gesture-handler';
5
6import Colors, { ColorTheme } from '../constants/Colors';
7
8type ViewProps = View['props'];
9interface Props extends ViewProps {
10  lightBackgroundColor?: string;
11  darkBackgroundColor?: string;
12  lightBorderColor?: string;
13  darkBorderColor?: string;
14}
15
16interface StyledScrollViewProps extends ScrollViewProps {
17  lightBackgroundColor?: string;
18  darkBackgroundColor?: string;
19}
20
21type ThemedColors = keyof typeof Colors.light & keyof typeof Colors.dark;
22
23function useThemeName(): ColorTheme {
24  const theme = useTheme();
25  return theme.dark ? ColorTheme.DARK : ColorTheme.LIGHT;
26}
27function useThemeBackgroundColor(props: Props | StyledScrollViewProps, colorName: ThemedColors) {
28  const themeName = useThemeName();
29  const colorFromProps =
30    themeName === ColorTheme.DARK ? props.darkBackgroundColor : props.lightBackgroundColor;
31
32  if (colorFromProps) {
33    return colorFromProps;
34  } else {
35    return Colors[themeName][colorName];
36  }
37}
38
39function useThemeBorderColor(props: Props, colorName: ThemedColors) {
40  const themeName = useThemeName();
41  const colorFromProps =
42    themeName === ColorTheme.DARK ? props.darkBorderColor : props.lightBorderColor;
43
44  if (colorFromProps) {
45    return colorFromProps;
46  } else {
47    return Colors[themeName][colorName];
48  }
49}
50
51export const StyledScrollView = React.forwardRef(
52  (props: StyledScrollViewProps, ref?: React.Ref<ScrollView>) => {
53    const { style, ...otherProps } = props;
54    const backgroundColor = useThemeBackgroundColor(props, 'absolute');
55
56    return <ScrollView {...otherProps} style={[{ backgroundColor }, style]} ref={ref} />;
57  }
58);
59
60export const StyledView = (props: Props) => {
61  const {
62    style,
63    lightBackgroundColor: _lightBackgroundColor,
64    darkBackgroundColor: _darkBackgroundColor,
65    lightBorderColor: _lightBorderColor,
66    darkBorderColor: _darkBorderColor,
67    ...otherProps
68  } = props;
69
70  const backgroundColor = useThemeBackgroundColor(props, 'cardBackground');
71  const borderColor = useThemeBorderColor(props, 'cardSeparator');
72
73  return (
74    <View
75      style={[
76        {
77          backgroundColor,
78          borderColor,
79        },
80        style,
81      ]}
82      {...otherProps}
83    />
84  );
85};
86