import { useEffect, useState } from 'react' export enum FormMode { OnChange = 'onChange', OnBlur = 'onBlur' } export type ErrorSchema = { [k in keyof T]: ErrorSchema | string } export type ValidationFunction = (value: T) => Partial> export default (defaultValue: T, validationFunction?: ValidationFunction, mode: FormMode = FormMode.OnBlur) => { const [formState, setFormState] = useState(defaultValue) const [errors, setErrors] = useState>>({}) const [showValidationErrors, setShowValidationErrors] = useState(false) useEffect(() => { if (showValidationErrors) { validate() } }, [formState]) const handleChange = (value: T) => { setFormState(value) } const handleSubmit = () => { return { formState, isValid: validate() } } const validate = (): boolean => { setShowValidationErrors(true) const isValid = (e: any): boolean => { for (let k in e) { if (e[k] instanceof Object) { if (!isValid(e[k])) { return false } } else if (e[k]) { return false } } return true } if (validationFunction) { const validationErrors = validationFunction(formState) setErrors(validationErrors) return isValid(validationErrors) } return true } return { formState, errors, showValidationErrors, handleSubmit, handleChange, mode } }