import { useEffect, useState, FormEvent, ChangeEvent, SyntheticEvent } from 'react' import TextInput from './TextInput' export interface InputProps { id: string, name: string, value: any, onChange: (event: SyntheticEvent) => void, onBlur: (event: SyntheticEvent) => void, placeholder: string, label: string } interface FormHandler { inputProps: (name: string) => InputProps, handleChange: (event: SyntheticEvent) => void, handleBlur: (event: SyntheticEvent) => void, values: Dict, errors: Dict, isSubmitting: boolean } /** * Provides hooks for forms. * * @remarks * You can use it like this * ```ts * const {inputParams, formParams} = useFormHandler() * ``` * * @param initialValues - Initial values of inputs * @param validate - validation function for the form * @returns hooks to handle the form */ function useFormHandler( initialValues: Dict, validate?: (values: Dict) => {} ): FormHandler { console.log('useFormHandler called.', initialValues) const [values, setValues] = useState(initialValues) const [errors, setErrors] = useState({}) const [isSubmitting, setIsSubmitting] = useState(false) useEffect(() => { if (isSubmitting) { const noErrors = Object.keys(errors).length === 0 if (noErrors) { console.log('no errors while submitting.') } else { console.log('errors while submitting,') } setIsSubmitting(false) } }, [errors]) function handleChange(event: SyntheticEvent): void { setValues({ ...values, [(event.target as HTMLInputElement).name]: (event.target as HTMLInputElement).value }) } function handleBlur(event: SyntheticEvent): void { if (validate) { const validationErrors = validate(values) setErrors(validationErrors) } } function inputProps(name: string, label?: string): InputProps { if (!values.hasOwnProperty(name)) { throw Error(`${name} is not an existing field.`) } return { id: name, name, value: values[name], onChange: handleChange, onBlur: handleBlur, placeholder: label || name, label: label || name } } return { inputProps, handleChange, handleBlur, values, errors, isSubmitting } } export { useFormHandler, TextInput }