UNPKG

react-fatless-form

Version:

A lightweight React form package designed for simplicity that simplifies form handling and validation without unnecessary complexity or bloat.

111 lines (110 loc) 5.69 kB
export interface UseForm<T> { values: T; errors: Partial<Record<keyof T, string>>; touched: Partial<Record<keyof T, boolean>>; submissionStatus: "idle" | "submitting" | "success" | "error"; setFieldValue: (field: keyof T, value: T[keyof T]) => void; setFieldArrayValue: (field: keyof T, value: string | string[]) => void; setFieldError: (field: keyof T, error: string) => void; setFieldTouched: (field: keyof T, touched: boolean) => void; validate: (validateFn: (values: T) => Partial<Record<keyof T, string>>) => boolean; resetForm: () => void; updateSubmissionStatus: (status: "idle" | "submitting" | "success" | "error") => void; resetSubmissionStatus: () => void; } export interface FormState<T> { values: T; errors: Partial<Record<keyof T, string>>; touched: Partial<Record<keyof T, boolean>>; } export type FormSubmissionStatus = "idle" | "submitting" | "success" | "error"; /** * A custom React hook for managing form state, validation, submission lifecycle, and interactions. * * This hook provides a robust solution for handling form values, validation, errors, submission status, * and user interactions. It is designed to be flexible and reusable for various form use cases. * * @template T - The shape of the form's values, defining keys and their respective types. * * @param {T} initialValues - The initial state of the form's values, determining the default structure of the form. * * @returns {object} A collection of state and functions for managing the form: * * **State:** * - **values** (`T`): The current state of the form's values. * - **errors** (`Partial<Record<keyof T, string>>`): An object storing validation errors for each field. * - **touched** (`Partial<Record<keyof T, boolean>>`): An object tracking whether a field has been interacted with. * - **submissionStatus** (`"idle" | "submitting" | "success" | "error"`): The current status of the form submission. * * **Functions:** * - **setFieldValue** (`(field: keyof T, value: T[keyof T]) => void`): Updates the value of a specific field. * - **batchSetfieldValues** (`(newValues: Partial<T>) => void`): Updates multiple field values at once. * - **setFieldArrayValue** (`(field: keyof T, value: string | string[]) => void`): Sets the value of a field as a string or an array of strings. * - **setFieldError** (`(field: keyof T, error: string) => void`): Sets an error message for a specific field. * - **setFieldTouched** (`(field: keyof T, touched: boolean) => void`): Marks a field as touched or untouched. * - **validate** (`(validateFn: (values: T) => Partial<Record<keyof T, string>>) => boolean`): * Validates the form using a custom validation function. * - `validateFn` receives the current `values` and should return an object with field-specific error messages. * - Returns `true` if validation passes (no errors), otherwise `false`. * - **resetForm** (`() => void`): Resets the form's values, errors, and touched fields to their initial state. * - **updateSubmissionStatus** (`(status: "idle" | "submitting" | "success" | "error") => void`): Updates the `submissionStatus` to reflect the current state of submission. * - **resetSubmissionStatus** (`() => void`): Resets the `submissionStatus` to `"idle"`. Useful for reusing the form or clearing transient submission states. * * **Design Philosophy:** * - **Separation of Concerns**: Core responsibilities like state updates and validation are modular and reusable. * - **Flexibility**: Provides developers full control over the submission and validation process. * - **Future-Proofing**: Allows for evolving workflows without tightly coupling submission logic to form state management. * * @example * ```tsx * const form = useForm({ username: "", age: 0 }); * * const validateForm = (values) => { * const errors = {}; * if (!values.username) errors.username = "Username is required"; * if (values.age <= 0) errors.age = "Age must be positive"; * return errors; * }; * * const handleSubmit = async () => { * if (!form.validate(validateForm(form.values))) { * console.warn("Validation failed"); * return; * } * form.updateSubmissionStatus("submitting"); * try { * await apiCall(form.values); * form.updateSubmissionStatus("success"); * } catch (error) { * console.error("Error during submission:", error); * form.updateSubmissionStatus("error"); * } * }; * * return ( * <form onSubmit={(e) => { e.preventDefault(); handleSubmit(); }}> * <input * value={form.values.username} * onChange={(e) => form.setFieldValue("username", e.target.value)} * /> * {form.errors.username && <span>{form.errors.username}</span>} * <button type="submit">Submit</button> * </form> * ); * ``` */ export declare function useForm<T>(initialValues: T): { submissionStatus: FormSubmissionStatus; setFieldValue: (field: keyof T, value: T[keyof T]) => void; batchSetfieldValues: (newValues: Partial<T>) => void; setFieldArrayValue: (field: keyof T, value: string | string[]) => void; setFieldError: (field: keyof T, error: string) => void; setFieldTouched: (field: keyof T, touched: boolean) => void; validate: (validateFn: (values: T) => Partial<Record<keyof T, string>>) => boolean; resetForm: () => void; updateSubmissionStatus: (status: "idle" | "submitting" | "success" | "error") => void; resetSubmissionStatus: () => void; values: T; errors: Partial<Record<keyof T, string>>; touched: Partial<Record<keyof T, boolean>>; };