You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
93 lines
2.4 KiB
93 lines
2.4 KiB
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<U>, |
|
M extends MapToInputId<U, I>, |
|
>( |
|
ids: I, |
|
messageGroupRef: MutableRefObject<MessageGroupForwardedRefContent>, |
|
): FormUtils<M> => { |
|
const [formValidity, setFormValidity] = useState<FormValidity<M>>({}); |
|
|
|
const setValidity = useCallback((key: keyof M, value?: boolean) => { |
|
setFormValidity( |
|
buildObjectStateSetterCallback<FormValidity<M>>(key, value), |
|
); |
|
}, []); |
|
|
|
const setValidityRe = useCallback((re: RegExp, value?: boolean) => { |
|
setFormValidity((previous) => { |
|
const result: FormValidity<M> = {}; |
|
|
|
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<U, I, M>(ids, messageGroupRef), |
|
[ids, messageGroupRef], |
|
); |
|
|
|
const setMsgSetter = useCallback( |
|
(id: keyof M, setter?: MessageSetter, isOverwrite?: boolean) => { |
|
if (!msgSetters[id] || isOverwrite) { |
|
msgSetters[id] = |
|
setter ?? buildMessageSetter<M>(String(id), messageGroupRef); |
|
} |
|
}, |
|
[messageGroupRef, msgSetters], |
|
); |
|
|
|
return { |
|
buildFinishInputTestBatchFunction, |
|
buildInputFirstRenderFunction, |
|
formValidity, |
|
isFormInvalid, |
|
msgSetters, |
|
setFormValidity, |
|
setMsgSetter, |
|
setValidity, |
|
setValidityRe, |
|
}; |
|
}; |
|
|
|
export default useFormUtils;
|
|
|