import type { ErrorLike } from '@apollo/client' import type { FieldValues, FormState, UseFormHandleSubmit, UseFormTrigger } from 'react-hook-form' import type { SetOptional } from 'type-fest' export type MinimalUseFormReturn = { formState: FormState trigger: UseFormTrigger } export type UseFormComposeOptions = { /** The form that is used to submit */ form: MinimalUseFormReturn /** Method to submit the form */ submit: ReturnType> /** Identifier of the specific */ key: string /** * To submit multiple forms we need to define a sequence how the forms are structured so they can * be submitted in that sequence. * * One form might depend on another form, so we first submit the first form, then the second, etc. */ step: number } export type FormStateAll = Pick< FormState, 'isSubmitting' | 'isSubmitted' | 'isSubmitSuccessful' | 'isValid' > export type ButtonState = { /** When the submit is called, isSubmit will be set to true */ isSubmitting: boolean /** After the submission is done, isSubmitted is set to true */ isSubmitted: boolean /** After the submission is successful, isSubmitSuccessful will be true */ isSubmitSuccessful: boolean } export type ComposedSubmitRenderComponentProps = { submit: () => Promise buttonState: ButtonState error?: ErrorLike } export type ComposedFormState = { forms: { [step: number]: UseFormComposeOptions | SetOptional } isCompleting: boolean buttonState: ButtonState formState: FormStateAll submitted: boolean error?: ErrorLike } /** Register a new form with the useFormCompose hook */ export type RegisterAction = { type: 'REGISTER' } & Pick /** Assign the current state to the form */ export type AssignAction = { type: 'ASSIGN' } & UseFormComposeOptions /** Cleanup the form if the useFromCompose hook changes */ export type UnregisterAction = { type: 'UNREGISTER' } & Pick /** Recalculate the combined formstate */ export type FormStateAction = { type: 'FORMSTATE' } /** Submit all forms and call onSubmitComplete?.() when done */ export type SubmitAction = { type: 'SUBMIT' } export type SubmittingAction = { type: 'SUBMITTING' } export type SubmittedAction = { type: 'SUBMITTED'; isSubmitSuccessful: boolean } export type Actions = | AssignAction | RegisterAction | UnregisterAction | FormStateAction | SubmitAction | SubmittingAction | SubmittedAction export type ComposedFormReducer = React.Reducer export type ComposedFormContext = [React.ReducerState, React.Dispatch]