import { MutableRefObject, useCallback, useMemo, useState } from 'react'; import buildObjectStateSetterCallback, { buildRegExpObjectStateSetterCallback, } from '../lib/buildObjectStateSetterCallback'; import { Message } from '../components/MessageBox'; 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 setMessage = useCallback( (key: keyof M, message?: Message) => { messageGroupRef?.current?.setMessage?.call(null, String(key), message); }, [messageGroupRef], ); const setMessageRe = useCallback( (re: RegExp, message?: Message) => { messageGroupRef?.current?.setMessageRe?.call(null, re, message); }, [messageGroupRef], ); const setValidity = useCallback((key: keyof M, value?: boolean) => { setFormValidity( buildObjectStateSetterCallback>(key, value), ); }, []); const setValidityRe = useCallback((re: RegExp, value?: boolean) => { setFormValidity( buildRegExpObjectStateSetterCallback>(re, value), ); }, []); const unsetKey = useCallback( (key: keyof M) => { setMessage(key); setValidity(key); }, [setMessage, setValidity], ); const unsetKeyRe = useCallback( (re: RegExp) => { setMessageRe(re); setValidityRe(re); }, [setMessageRe, setValidityRe], ); 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 buildInputUnmountFunction = useCallback( (key: keyof M) => () => { unsetKey(key); }, [unsetKey], ); const isFormInvalid = useMemo( () => Object.values(formValidity).some((isInputValid) => !isInputValid), [formValidity], ); return { buildFinishInputTestBatchFunction, buildInputFirstRenderFunction, buildInputUnmountFunction, formValidity, isFormInvalid, setFormValidity, setMessage, setMessageRe, setValidity, setValidityRe, unsetKey, unsetKeyRe, }; }; export default useFormUtils;