import { useHeaderHeight as useHeaderHeightOG } from '@react-navigation/elements' import { createContext, forwardRef, useContext, useState } from 'react' import { KeyboardAvoidingView, Platform } from 'react-native' import { ScrollView, TamaguiElement, YStack, YStackProps, useWindowDimensions, withStaticProperties, } from 'tamagui' const useHeaderHeight = () => { try { return useHeaderHeightOG() // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (_error) { return 0 } } const FormWrapperContext = createContext<{ height: number } | null>(null) /** * this utility component is for creating forms where we want to * push the action button to the bottom of the screen on native * it also handles keyboard avoidance * * wrap the fields inside Body and the actions in Footer * * you may use asChild on the wrapper as well */ const Wrapper = forwardRef(function Wrapper(props, ref) { const [height, setHeight] = useState(0) return ( { setHeight(event.nativeEvent.layout.height) }} ref={ref} gap="$4" f={1} jc="center" $gtSm={{ w: '100%', maw: 600, als: 'center', }} $sm={{ jc: 'space-between' }} {...props} /> ) }) const Body = forwardRef(function Body(props, ref) { return ( ) }) /** * on native, this will be pushed to the bottom of the screen */ const Footer = forwardRef(function Footer(props, ref) { const dimensions = useWindowDimensions() const headerHeight = useHeaderHeight() const formWrapperContext = useContext(FormWrapperContext) const modalOffsetFromTop = formWrapperContext ? dimensions.height - formWrapperContext.height : headerHeight return ( ) }) export const FormWrapper = withStaticProperties(Wrapper, { Body, Footer, })