import type { DeepPartial, FieldValues, UseFormHandleSubmit, UseFormReturn, } from "react-hook-form"; import { useForm } from "react-hook-form"; import type { RefObject } from "react"; import type { KeyboardAwareScrollViewRef } from "react-native-keyboard-controller"; import { useAtlantisContext } from "../../AtlantisContext"; import { useAtlantisFormContext } from "../context/AtlantisFormContext"; import type { InternalFormProps } from "../types"; type UseInternalFormProps = Pick< InternalFormProps, | "mode" | "reValidateMode" | "initialValues" | "formRef" | "localCacheKey" | "localCacheExclude" | "localCacheId" | "UNSAFE_allowDiscardLocalCacheWhenOffline" > & { scrollViewRef?: RefObject; readonly saveButtonHeight: number; readonly messageBannerHeight: number; }; interface UseInternalForm { readonly formMethods: UseFormReturn; readonly handleSubmit: UseFormHandleSubmit; readonly isSubmitting: boolean; readonly isDirty: boolean; readonly removeListenerRef: RefObject<() => void>; readonly setLocalCache: (data: DeepPartial) => void; } export function useInternalForm({ mode, reValidateMode, initialValues, formRef, localCacheKey, localCacheId, scrollViewRef, saveButtonHeight, messageBannerHeight, UNSAFE_allowDiscardLocalCacheWhenOffline = false, }: UseInternalFormProps): UseInternalForm { const { useConfirmBeforeBack, useInternalFormLocalCache } = useAtlantisFormContext(); const { isOnline } = useAtlantisContext(); const formMethods = useForm({ mode, reValidateMode, defaultValues: initialValues, shouldFocusError: false, }); const clientSideSaveOn = localCacheKey && localCacheKey !== "INVALID"; const { setLocalCache, removeLocalCache } = useInternalFormLocalCache( formMethods, localCacheKey, { id: localCacheId, }, ); const { handleSubmit, formState: { isSubmitting, isDirty }, } = formMethods; if (formRef) { formRef.current = { ...formMethods, saveButtonHeight, messageBannerHeight, scrollViewRef, }; } const shouldRemoveCacheOnBack = UNSAFE_allowDiscardLocalCacheWhenOffline ? true : isOnline; const removeListenerRef = useConfirmBeforeBack({ alwaysPreventBack: isSubmitting, shouldShowAlert: isDirty, onAcceptEvent: shouldRemoveCacheOnBack ? removeLocalCache : undefined, showLostProgressMessage: shouldRemoveCacheOnBack || !clientSideSaveOn ? true : false, }); return { setLocalCache, formMethods, handleSubmit, isSubmitting, isDirty, removeListenerRef, }; }