import { MutableRefObject, useCallback, useMemo, useState } from 'react'; import buildMapToMessageSetter, { buildMessageSetter, } from '../lib/buildMapToMessageSetter'; import buildObjectStateSetterCallback from '../lib/buildObjectStateSetterCallback'; import { MessageGroupForwardedRefContent } from '../components/MessageGroup'; const useFormUtils = < U extends string, I extends InputIds, M extends MapToInputId, >( ids: I, messageGroupRef: MutableRefObject, ): FormUtils => { const [formValidity, setFormValidity] = useState>({}); const setValidity = useCallback((key: keyof M, value?: boolean) => { setFormValidity( buildObjectStateSetterCallback>(key, value), ); }, []); const setValidityRe = useCallback((re: RegExp, value?: boolean) => { setFormValidity((previous) => { const result: FormValidity = {}; Object.keys(previous).forEach((key) => { const id = key as keyof M; if (re.test(key)) { if (value !== undefined) { result[id] = value; } } else { result[id] = previous[id]; } }); return result; }); }, []); const buildFinishInputTestBatchFunction = useCallback( (key: keyof M) => (result: boolean) => { setValidity(key, result); }, [setValidity], ); const buildInputFirstRenderFunction = useCallback( (key: keyof M) => ({ isValid }: InputFirstRenderFunctionArgs) => { setValidity(key, isValid); }, [setValidity], ); const isFormInvalid = useMemo( () => Object.values(formValidity).some((isInputValid) => !isInputValid), [formValidity], ); const msgSetters = useMemo( () => buildMapToMessageSetter(ids, messageGroupRef), [ids, messageGroupRef], ); const setMsgSetter = useCallback( (id: keyof M, setter?: MessageSetter, isOverwrite?: boolean) => { if (!msgSetters[id] || isOverwrite) { msgSetters[id] = setter ?? buildMessageSetter(String(id), messageGroupRef); } }, [messageGroupRef, msgSetters], ); return { buildFinishInputTestBatchFunction, buildInputFirstRenderFunction, formValidity, isFormInvalid, msgSetters, setFormValidity, setMsgSetter, setValidity, setValidityRe, }; }; export default useFormUtils;