export interface UseForm { values: T; errors: Partial>; touched: Partial>; 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>) => boolean; resetForm: () => void; updateSubmissionStatus: (status: "idle" | "submitting" | "success" | "error") => void; resetSubmissionStatus: () => void; } export interface FormState { values: T; errors: Partial>; touched: Partial>; } 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>`): An object storing validation errors for each field. * - **touched** (`Partial>`): 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) => 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>) => 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 ( *
{ e.preventDefault(); handleSubmit(); }}> * form.setFieldValue("username", e.target.value)} * /> * {form.errors.username && {form.errors.username}} * *
* ); * ``` */ export declare function useForm(initialValues: T): { submissionStatus: FormSubmissionStatus; setFieldValue: (field: keyof T, value: T[keyof T]) => void; batchSetfieldValues: (newValues: Partial) => 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>) => boolean; resetForm: () => void; updateSubmissionStatus: (status: "idle" | "submitting" | "success" | "error") => void; resetSubmissionStatus: () => void; values: T; errors: Partial>; touched: Partial>; };