diff options
| author | Armand Philippot <git@armandphilippot.com> | 2023-11-03 19:34:16 +0100 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2023-11-11 18:15:27 +0100 |
| commit | ddd45e29745b73e7fe1684e197dcff598b375644 (patch) | |
| tree | 8bf01305b5c0d163c52a7dce747ed7a4a4650acb /src/utils/hooks/use-form/use-form-values/use-form-values.ts | |
| parent | 5d3e8a4d0c2ce2ad8f22df857ab3ce54fcfc38ac (diff) | |
feat(hooks): add an useForm hook
* add two "sub"-hooks: useFormValues and useFormSubmit (that
can be used independently)
* handle initial data
* handle custom submit callback
* handle data validation
* handle submit status
Diffstat (limited to 'src/utils/hooks/use-form/use-form-values/use-form-values.ts')
| -rw-r--r-- | src/utils/hooks/use-form/use-form-values/use-form-values.ts | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/src/utils/hooks/use-form/use-form-values/use-form-values.ts b/src/utils/hooks/use-form/use-form-values/use-form-values.ts new file mode 100644 index 0000000..8a0962f --- /dev/null +++ b/src/utils/hooks/use-form/use-form-values/use-form-values.ts @@ -0,0 +1,69 @@ +import { + type ChangeEventHandler, + useCallback, + useState, + type ChangeEvent, +} from 'react'; + +const isBooleanField = ( + target: EventTarget & (HTMLInputElement | HTMLTextAreaElement) +): target is EventTarget & HTMLInputElement => + target.type === 'checkbox' || target.type === 'radio'; + +export type UseFormValuesReturn<T extends Record<string, unknown>> = { + /** + * A method to reset the fields to their initial values. + * + * @returns {void} + */ + reset: () => void; + /** + * A method to handle input or textarea update. + * + * @param {ChangeEvent<HTMLTextAreaElement | HTMLInputElement>} e - The event. + * @returns {void} + */ + update: (e: ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => void; + /** + * The fields values. + */ + values: T; +}; + +/** + * React hook to handle form values update and reset. + * + * @template {object} T - The object keys should match the fields name. + * @param {T} initialValues - The fields initial values. + * @returns {UseFormValuesReturn<T>} An object with values and two methods. + */ +export const useFormValues = <T extends Record<string, unknown>>( + initialValues: T +): UseFormValuesReturn<T> => { + const [values, setValues] = useState(initialValues); + + /** + * Reset the field to their initial values. + */ + const reset = useCallback(() => { + setValues(initialValues); + }, [initialValues]); + + /** + * Handle input and textarea update. + * + * @param {ChangeEvent<HTMLTextAreaElement | HTMLInputElement>} e - The event. + * @returns {void} + */ + const update: ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement> = + useCallback(({ target }) => { + setValues((prevData) => { + return { + ...prevData, + [target.name]: isBooleanField(target) ? target.checked : target.value, + }; + }); + }, []); + + return { values, reset, update }; +}; |
