Created
July 5, 2022 07:19
-
-
Save harrisrobin/128ee10cf582b037987952e542ae60e7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from "react" | |
import { KeyboardAvoidingView, Platform } from "react-native" | |
import { StatusBar } from "expo-status-bar" | |
import { ScreenProps } from "./screen.props" | |
import { isNonScrolling, offsets, variants } from "./screen.variants" | |
import { useAppColorScheme } from "@zaboca/ui/hooks/use-app-color-scheme" | |
import { useThemeColor } from "@zaboca/ui/hooks/use-theme-color" | |
import { View } from "@zaboca/ui/view" | |
import { useSafeAreaInsets } from "@zaboca/ui/dimensions" | |
import { ScrollView } from "@zaboca/ui/scroll-view" | |
const isIos = Platform.OS === "ios" | |
function ScreenWithoutScrolling(props: ScreenProps) { | |
const insets = useSafeAreaInsets() | |
const preset = variants.fixed | |
const { colorScheme } = useAppColorScheme() | |
const backgroundColor = useThemeColor("background") | |
const backgroundStyle = props.backgroundColor | |
? { backgroundColor: props.backgroundColor } | |
: { backgroundColor: backgroundColor } | |
const insetStyle = { paddingTop: props.unsafe ? 0 : insets.top } | |
const footerComponent = props.footerComponent || null | |
const statusBarStyle = | |
props.barStyle || colorScheme === "dark" ? "light" : "dark" | |
return ( | |
<KeyboardAvoidingView | |
style={[preset.outer, backgroundStyle]} | |
behavior={isIos ? "padding" : undefined} | |
keyboardVerticalOffset={offsets[props.keyboardOffset || "none"]} | |
> | |
<StatusBar style={statusBarStyle || "auto"} /> | |
<View | |
sx={{ | |
...props.sx, | |
}} | |
// @ts-expect-error TODO(Harirs): figure out how to avoid ThemeUICSSObject conflict with ViewStyle | |
style={[preset.inner, insetStyle]} | |
> | |
{props.children} | |
<View | |
sx={{ | |
paddingBottom: insets.bottom, | |
}} | |
> | |
{Boolean(footerComponent) && footerComponent} | |
</View> | |
</View> | |
</KeyboardAvoidingView> | |
) | |
} | |
function ScreenWithScrolling(props: ScreenProps) { | |
const insets = useSafeAreaInsets() | |
const preset = variants.scroll | |
const { colorScheme } = useAppColorScheme() | |
const backgroundColor = useThemeColor("background") | |
const backgroundStyle = props.backgroundColor | |
? { backgroundColor: props.backgroundColor } | |
: { backgroundColor: backgroundColor } | |
const insetStyle = { paddingTop: props.unsafe ? 0 : insets.top } | |
const footerComponent = props.footerComponent || null | |
const statusBarStyle = | |
props.barStyle || colorScheme === "dark" ? "light" : "dark" | |
return ( | |
<KeyboardAvoidingView | |
style={[preset.outer, backgroundStyle]} | |
behavior={isIos ? "padding" : undefined} | |
keyboardVerticalOffset={offsets[props.keyboardOffset || "none"]} | |
> | |
<StatusBar style={statusBarStyle || "auto"} /> | |
<View | |
sx={{ | |
...preset.outer, | |
...backgroundStyle, | |
...insetStyle, | |
}} | |
> | |
<ScrollView | |
ref={props.scrollRef} | |
sx={{ | |
...preset.outer, | |
...backgroundStyle, | |
}} | |
contentContainerSx={{ | |
...preset.inner, | |
...props.sx, | |
}} | |
keyboardShouldPersistTaps={ | |
props.keyboardShouldPersistTaps || "handled" | |
} | |
refreshControl={props.refreshControl} | |
> | |
{props.children} | |
</ScrollView> | |
<View | |
sx={{ | |
paddingBottom: insets.bottom, | |
}} | |
> | |
{Boolean(footerComponent) && footerComponent} | |
</View> | |
</View> | |
</KeyboardAvoidingView> | |
) | |
} | |
/** | |
* The starting component on every screen in the app. | |
* | |
* @param props The screen props | |
*/ | |
export function Screen(props: ScreenProps): JSX.Element { | |
if (isNonScrolling(props.variant)) { | |
return <ScreenWithoutScrolling {...props} /> | |
} else { | |
return <ScreenWithScrolling {...props} /> | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment