import { useEffect, useState, FormEvent, ChangeEvent, SyntheticEvent } from 'react' import { getValue, setValue } from '../../lib/array' import TextInput from './TextInput' export interface InputProps { id: string, name: string, value: any, onChange: (event: ChangeEvent) => void, onBlur: (event: SyntheticEvent) => void, placeholder: string, label: string } export interface InputPropsOptions { label?: string subtree?: string } interface FormHandler { values: ValueObject, errors: Dict, isSubmitting: boolean, setValues: (values: ValueObject) => void inputProps: (name: string) => InputProps, handleChange: (event: ChangeEvent) => void, handleBlur: (event: SyntheticEvent) => void, handleSubmit: (event: FormEvent, data: any) => void } /** * 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: ValueObject, validate?: (values: Dict) => {}, submit?: (data: any) => {} ): FormHandler { const [values, setValues] = useState(initialValues) const [errors, setErrors] = useState({}) const [isSubmitting, setIsSubmitting] = useState(false) function handleChange(event: ChangeEvent): void { const target = (event.target as HTMLInputElement) console.log('change', values, target.name) setValues({ ...values, [target.name]: target.value }) } function handleBlur(event: SyntheticEvent): void { if (validate) { const validationErrors = validate(values) setErrors(validationErrors) } } function handleSubmit(event: FormEvent, data: any): void { event.preventDefault() if (submit) { submit(data) } } // users[3].name function inputProps(name: string, options?: InputPropsOptions): InputProps { const subtree = options && options.subtree return { id: [subtree, name].join('.'), name: name, value: getValue(values, name), onChange: handleChange, onBlur: handleBlur, placeholder: options && options.label || name, label: options && options.label || name } } return { values, errors, isSubmitting, setValues, inputProps, handleChange, handleBlur, handleSubmit } } export { useFormHandler, TextInput }