Untitled

mail@pastecode.io avatar
unknown
plain_text
3 years ago
3.5 kB
2
Indexable
import { KeyboardAvoidingView, StatusBar, View, ViewStyle } from 'react-native';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
import { useTheme } from '@hooks/useTheme';
import { Header } from '../header';
import { isNonScrolling, offsets, presets } from './screen.presets';
import { ScreenProps } from './screen.props';

function ScreenWithoutScrolling(props: ScreenProps) {
  const insets = useSafeAreaInsets();
  const theme = useTheme();
  const preset = presets.fixed;
  const style = props.style || {};
  const backgroundStyle: ViewStyle = {
    backgroundColor: 'white',
  };
  if (props.bg) {
    backgroundStyle.backgroundColor = theme.colors[props.bg] || props.bg;
  }
  if (props.backgroundColor) {
    backgroundStyle.backgroundColor = props.backgroundColor;
  }

  const insetStyle = props.unsafe
    ? {}
    : {
        paddingBottom: props.noPaddingBottom ? 0 : insets.bottom,
        paddingTop: props.header ? 0 : insets.top,
      };
  const ScreenHeader = props.header ? Header : View;

  const statusBarPropsDefault = {
    barStyle: props.barStyle,
    backgroundColor: 'transparent',
    translucent: true,
    ...props.statusBarProps,
  };

  return (
    <KeyboardAvoidingView
      style={[preset.outer, backgroundStyle, props.containerStyle]}
      keyboardVerticalOffset={offsets[props.keyboardOffset || 'none']}
      {...props.keyboardAvoidingViewProps}
    >
      <StatusBar {...statusBarPropsDefault} />
      <ScreenHeader {...props.header} />

      <View style={[preset.inner, insetStyle, style]}>{props.children}</View>
    </KeyboardAvoidingView>
  );
}

function ScreenWithScrolling(props: ScreenProps) {
  const insets = useSafeAreaInsets();
  const preset = presets.scroll;
  const theme = useTheme();
  const { safeAreaViewProps = { edges: ['left', 'right'] } } = props;
  const backgroundStyle: ViewStyle = {
    backgroundColor: 'white',
  };
  if (props.bg) {
    backgroundStyle.backgroundColor = theme.colors[props.bg] || props.bg;
  }
  if (props.backgroundColor) {
    backgroundStyle.backgroundColor = props.backgroundColor;
  }
  const wrapperProps = props.wrapperProps;
  const ScreenHeader = props.header ? Header : View;

  const statusBarPropsDefault = {
    barStyle: props.barStyle,
    backgroundColor: 'transparent',
    ...props.statusBarProps,
  };

  const insetStyle = props.unsafe
    ? {}
    : {
        paddingBottom: props.noPaddingBottom ? 0 : insets.bottom,
        paddingTop: props.header ? 0 : insets.top,
      };
  return (
    <View style={[preset.outer, backgroundStyle, props.containerStyle]}>
      <StatusBar {...statusBarPropsDefault} />
      <ScreenHeader {...props.header} />
      <KeyboardAwareScrollView
        {...props.keyboardAwareScrollViewProps}
        showsVerticalScrollIndicator={false}
      >
        <SafeAreaView
          {...wrapperProps}
          {...safeAreaViewProps}
          style={[preset.outer, props.unsafe ? {} : insetStyle, props.style]}
        >
          {props.children}
        </SafeAreaView>
      </KeyboardAwareScrollView>
    </View>
  );
}

/**
 * The starting component on every screen in the app.
 *
 * @param props The screen props
 */
export const Screen = (props: ScreenProps) => {
  if (!props.variant || isNonScrolling(props.variant)) {
    return <ScreenWithoutScrolling {...props} />;
  } else {
    return <ScreenWithScrolling {...props} />;
  }
};