import { Dispatch, MutableRefObject, SetStateAction, useCallback, useMemo, useState, } from 'react'; import buildMapToMessageSetter from '../lib/buildMapToMessageSetter'; import buildObjectStateSetterCallback from '../lib/buildObjectStateSetterCallback'; import { MessageGroupForwardedRefContent } from '../components/MessageGroup'; type FormValidity = { [K in keyof T]?: boolean; }; const useFormUtils = < U extends string, I extends InputIds, M extends MapToInputId, >( ids: I, messageGroupRef: MutableRefObject, ): { buildFinishInputTestBatchFunction: ( key: keyof M, ) => (result: boolean) => void; buildInputFirstRenderFunction: ( key: keyof M, ) => ({ isRequired }: { isRequired: boolean }) => void; formValidity: FormValidity; isFormInvalid: boolean; msgSetters: MapToMessageSetter; setFormValidity: Dispatch>>; } => { const [formValidity, setFormValidity] = useState>({}); const buildFinishInputTestBatchFunction = useCallback( (key: keyof M) => (result: boolean) => { setFormValidity( buildObjectStateSetterCallback>(key, result), ); }, [], ); const buildInputFirstRenderFunction = useCallback( (key: keyof M) => ({ isRequired }: { isRequired: boolean }) => { setFormValidity( buildObjectStateSetterCallback>(key, !isRequired), ); }, [], ); const isFormInvalid = useMemo( () => Object.values(formValidity).some((isInputValid) => !isInputValid), [formValidity], ); const msgSetters = useMemo( () => buildMapToMessageSetter(ids, messageGroupRef), [ids, messageGroupRef], ); return { buildFinishInputTestBatchFunction, buildInputFirstRenderFunction, formValidity, isFormInvalid, msgSetters, setFormValidity, }; }; export default useFormUtils;