diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx index ea11e22174..248e545c3e 100644 --- a/src/components/Layout.tsx +++ b/src/components/Layout.tsx @@ -1,12 +1,17 @@ import React, {useContext, useMemo} from 'react' -import {View, ViewStyle} from 'react-native' +import {StyleSheet, View, ViewProps, ViewStyle} from 'react-native' import {StyleProp} from 'react-native' +import { + KeyboardAwareScrollView, + KeyboardAwareScrollViewProps, +} from 'react-native-keyboard-controller' +import Animated, {AnimatedScrollViewProps} from 'react-native-reanimated' import {useSafeAreaInsets} from 'react-native-safe-area-context' +import {isWeb} from '#/platform/detection' import {ViewHeader} from '#/view/com/util/ViewHeader' -import {ScrollView} from '#/view/com/util/Views' import {CenteredView} from '#/view/com/util/Views' -import {atoms as a} from '#/alf' +import {atoms as a, useBreakpoints, useTheme, ViewStyleProp} from '#/alf' // Every screen should have a Layout component wrapping it. // This component provides a default padding for the top of the screen. @@ -18,19 +23,21 @@ const LayoutContext = React.createContext({ withinScrollView: false, }) +export type ScreenProps = React.ComponentProps & { + disableTopPadding?: boolean + style?: StyleProp +} + /** * Every screen should have a Layout.Screen component wrapping it. * This component provides a default padding for the top of the screen * and height/minHeight */ -let Screen = ({ +export const Screen = React.memo(function Screen({ disableTopPadding = false, style, ...props -}: React.ComponentProps & { - disableTopPadding?: boolean - style?: StyleProp -}): React.ReactNode => { +}: ScreenProps) { const {top} = useSafeAreaInsets() const context = useMemo( () => ({ @@ -52,13 +59,11 @@ let Screen = ({ /> ) -} -Screen = React.memo(Screen) -export {Screen} +}) -let Header = ( +export const Header = React.memo(function Header( props: React.ComponentProps, -): React.ReactNode => { +) { const {withinScrollView} = useContext(LayoutContext) if (!withinScrollView) { return ( @@ -69,18 +74,19 @@ let Header = ( } else { return } -} -Header = React.memo(Header) -export {Header} +}) -let Content = ({ +export type ContentProps = AnimatedScrollViewProps & { + style?: StyleProp + contentContainerStyle?: StyleProp +} + +export const Content = React.memo(function Content({ + children, style, contentContainerStyle, ...props -}: React.ComponentProps & { - style?: StyleProp - contentContainerStyle?: StyleProp -}): React.ReactNode => { +}: ContentProps) { const context = useContext(LayoutContext) const newContext = useMemo( () => ({...context, withinScrollView: true}), @@ -88,13 +94,141 @@ let Content = ({ ) return ( - + + {isWeb ? ( + // @ts-ignore web only -esb +
{children}
+ ) : ( + children + )} +
) +}) + +export type KeyboardAwareContentProps = KeyboardAwareScrollViewProps & { + children: React.ReactNode + contentContainerStyle?: StyleProp } -Content = React.memo(Content) -export {Content} + +export const KeyboardAwareContent = React.forwardRef(function LayoutScrollView( + {children, style, contentContainerStyle, ...props}: KeyboardAwareContentProps, + _ref: React.Ref, +) { + return ( + + {isWeb ?
{children}
: children} +
+ ) +}) + +export const Center = React.forwardRef(function LayoutContent( + {children, style, ...props}: ViewProps, + ref: React.Ref, +) { + const t = useTheme() + const {gtMobile} = useBreakpoints() + return ( + <> + {gtMobile && ( + + )} + + {children} + + + ) +}) + +export function Gutter({ + children, + top, + bottom, + style, +}: ViewStyleProp & { + children: React.ReactNode + top?: boolean + bottom?: boolean +}) { + const {gtMobile} = useBreakpoints() + return ( + + {children} + + ) +} + +const styles = StyleSheet.create({ + scrollViewCommonStyles: { + width: '100%', + }, + scrollViewContentContainer: { + paddingBottom: 100, + }, + /** + * Applied last to ensure they override any locally-defined styles. Use sparingly. + */ + scrollViewOverrideStyles: { + /* + * Ensures fixed items within `ScrollView` are fixed relative to window. + */ + transform: 'unset', + }, +})