From ddd45e29745b73e7fe1684e197dcff598b375644 Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Fri, 3 Nov 2023 19:34:16 +0100 Subject: 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 --- .../use-form/use-form-values/use-form-values.ts | 69 ++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 src/utils/hooks/use-form/use-form-values/use-form-values.ts (limited to 'src/utils/hooks/use-form/use-form-values/use-form-values.ts') 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> = { + /** + * A method to reset the fields to their initial values. + * + * @returns {void} + */ + reset: () => void; + /** + * A method to handle input or textarea update. + * + * @param {ChangeEvent} e - The event. + * @returns {void} + */ + update: (e: ChangeEvent) => 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} An object with values and two methods. + */ +export const useFormValues = >( + initialValues: T +): UseFormValuesReturn => { + 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} e - The event. + * @returns {void} + */ + const update: ChangeEventHandler = + useCallback(({ target }) => { + setValues((prevData) => { + return { + ...prevData, + [target.name]: isBooleanField(target) ? target.checked : target.value, + }; + }); + }, []); + + return { values, reset, update }; +}; -- cgit v1.2.3