UNPKG

lynx-form-x

Version:

LynxFormX is a lightweight and intuitive form library built for the Lynx framework for mobile development. It streamlines form management by automatically binding fields, handling validation, and providing easy-to-use hooks for custom field manipulation—a

78 lines (77 loc) • 3.1 kB
import { useCallback, useReducer } from '@lynx-js/react'; import { ZodObject, ZodTransformer } from 'zod'; import { reset, setError, setIsSubmitting, setTouched, setValue, } from '../reducers/formActions.js'; import { formReducer, } from '../reducers/formReducer.jsx'; export const useForm = (onSubmit, initialValues, validate, schema) => { const [state, dispatch] = useReducer((formReducer), { values: initialValues || {}, errors: {}, touched: {}, isSubmitting: false, }); const validateField = useCallback((field, value) => { if (schema) { const result = schema.safeParse(value !== undefined ? { ...state.values, [field]: value } : state.values); console.log(result.error?.format()); setFormError(field, (result.error?.format())[field]?._errors[0] || ''); } else if (validate) { const errors = validate({ ...state.values, [field]: value }); setFormError(field, errors[field] || ''); } }, [validate, schema, setFormError]); const handleInput = useCallback((field) => (e) => { const value = e.detail.value; setFormValue(field, value); validateField(field, value); }, [state.values, validateField]); const handleBlur = useCallback((field) => () => { setTouched(dispatch, field, true); validateField(field); }, [state.values, validateField]); const handleSubmit = useCallback(() => { if (schema) { const errors = schema.safeParse(state.values).error?.format(); if (errors) { for (const [field, value] of Object.entries(errors)) { const parsedValue = value; if (parsedValue?._errors) setFormError(field, parsedValue?._errors[0]); } return; } } else if (validate) { const errors = validate(state.values); if (Object.keys(errors).length > 0) { Object.keys(errors).forEach((field) => { setFormError(field, errors[field] || ''); }); return; } } setIsSubmitting(dispatch, true); Promise.resolve(onSubmit(state.values, { setValue: setFormValue, setError: setFormError })).finally(() => setIsSubmitting(dispatch, false)); }, [validate, schema, state.values, onSubmit, setFormError, setFormValue]); const resetForm = useCallback(() => reset(dispatch, initialValues), [initialValues]); function setFormValue(field, value) { setValue(dispatch, field, value); } function setFormError(field, error) { setError(dispatch, field, error); } return { values: state.values, errors: state.errors, touched: state.touched, handleInput, handleBlur, handleSubmit, resetForm, setValue: setFormValue, setError: setFormError, isSubmitting: state.isSubmitting, }; };