import {forwardRef, memo, useContext, useMemo} from 'react' import {StyleSheet, View, type ViewProps, type ViewStyle} from 'react-native' import {type StyleProp} from 'react-native' import { KeyboardAwareScrollView, type KeyboardAwareScrollViewProps, } from 'react-native-keyboard-controller' import Animated, { type AnimatedScrollViewProps, useAnimatedProps, } from 'react-native-reanimated' import {useSafeAreaInsets} from 'react-native-safe-area-context' import {isWeb} from '#/platform/detection' import {useShellLayout} from '#/state/shell/shell-layout' import { atoms as a, useBreakpoints, useLayoutBreakpoints, useTheme, web, } from '#/alf' import {useDialogContext} from '#/components/Dialog' import {CENTER_COLUMN_OFFSET, SCROLLBAR_OFFSET} from '#/components/Layout/const' import {ScrollbarOffsetContext} from '#/components/Layout/context' export * from '#/components/Layout/const' export * as Header from '#/components/Layout/Header' export type ScreenProps = React.ComponentProps & { style?: StyleProp noInsetTop?: boolean } /** * Outermost component of every screen */ export const Screen = memo(function Screen({ style, noInsetTop, ...props }: ScreenProps) { const {top} = useSafeAreaInsets() return ( <> {isWeb && } ) }) export type ContentProps = AnimatedScrollViewProps & { style?: StyleProp contentContainerStyle?: StyleProp ignoreTabletLayoutOffset?: boolean } /** * Default scroll view for simple pages */ export const Content = memo( forwardRef(function Content( { children, style, contentContainerStyle, ignoreTabletLayoutOffset, ...props }, ref, ) { const t = useTheme() const {footerHeight} = useShellLayout() const animatedProps = useAnimatedProps(() => { return { scrollIndicatorInsets: { bottom: footerHeight.get(), top: 0, right: 1, }, } satisfies AnimatedScrollViewProps }) return ( {isWeb ? (
{/* @ts-expect-error web only -esb */} {children}
) : ( children )}
) }), ) const scrollViewStyles = StyleSheet.create({ common: { width: '100%', }, contentContainer: { paddingBottom: 100, }, }) export type KeyboardAwareContentProps = KeyboardAwareScrollViewProps & { children: React.ReactNode contentContainerStyle?: StyleProp } /** * Default scroll view for simple pages. * * BE SURE TO TEST THIS WHEN USING, it's untested as of writing this comment. */ export const KeyboardAwareContent = memo(function LayoutKeyboardAwareContent({ children, style, contentContainerStyle, ...props }: KeyboardAwareContentProps) { return ( {isWeb ?
{children}
: children}
) }) /** * Utility component to center content within the screen */ export const Center = memo(function LayoutCenter({ children, style, ignoreTabletLayoutOffset, ...props }: ViewProps & {ignoreTabletLayoutOffset?: boolean}) { const {isWithinOffsetView} = useContext(ScrollbarOffsetContext) const {gtMobile} = useBreakpoints() const {centerColumnOffset} = useLayoutBreakpoints() const {isWithinDialog} = useDialogContext() const ctx = useMemo(() => ({isWithinOffsetView: true}), []) return ( {children} ) }) /** * Only used within `Layout.Screen`, not for reuse */ const WebCenterBorders = memo(function LayoutWebCenterBorders() { const t = useTheme() const {gtMobile} = useBreakpoints() const {centerColumnOffset} = useLayoutBreakpoints() return gtMobile ? ( ) : null })