UNPKG

@d3vtool/hooks

Version:

Collection of custom React hooks to simplify tasks in your React projects.

106 lines (105 loc) 4.39 kB
import { ObjectValidator, VInfer } from "@d3vtool/utils"; import React, { FormEvent } from "react"; /** * Type definition for form errors, where each key in the FormType * corresponds to a string representing the error message for that field. */ export type FormError<FormType> = { [P in keyof FormType]: string; }; /** * Type definition for a form submission action. This function accepts a form event * and returns a Promise that resolves when the submission process is complete. */ export type FormAction = (event: FormEvent) => Promise<void>; /** * Type definition for a middleware action in the form submission process. * This function returns a Promise that resolves when the middleware logic is complete. */ export type FormMiddlewareAction = () => void | Promise<void>; /** * Type definition for a submit action that forceRenders a form submission and * allows you to specify a middleware action to run before submission. */ export type SubmitAction = (callback: FormMiddlewareAction) => FormAction; export type SetFormDataAction<F> = (key: keyof F, data: F[keyof F], hideErrorMsg?: boolean) => void; export type GetFormDataAction<F> = (key: keyof F) => F[keyof F]; export type RefAction = (instance: HTMLInputElement | HTMLTextAreaElement | null) => void; export type Listeners = { onChange: (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void; onBlur: (event: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>) => void; ref: RefAction; }; export type ResetFieldAction = (keepErrorMsgs?: boolean) => void; /** * Type definition for the hook that provides the form state (F), * the form submission handler (SubmitAction), form error handling (FormError), * and the input reference setup action (SetupInputRefsAction). */ export type UseForm<F> = { formData: F; onSubmit: SubmitAction; formErrors: FormError<F>; setFormData: SetFormDataAction<F>; getFormData: GetFormDataAction<F>; listeners: Listeners; resetFields: ResetFieldAction; }; /** * useForm is a custom React hook for managing form state with validation. It provides * an efficient way to handle form input values, perform validation based on a schema, and * manage errors and submission logic. * * @template FormSchema - The schema used to validate the form, based on an object validator. * * @param defaultFormData - The initial form data object that matches the shape of the form schema. * @param formSchema - The schema used to validate the form fields. This ensures that form values adhere to the schema's validation rules. * * @returns An object containing: * - formData: The current form data as an object that matches the schema shape. * - onSubmit: A function to handle form submission. Pass a callback to execute when the form is successfully validated and submitted. * - formErrors: An object that contains error messages for each form field, keyed by the field name. * - setFormData: A function that allows you to set the form data for a specific field. * - getFormData: A function that allows you to retrieve the form data for a specific field. * - listeners: Event listeners to be passed to the input fields for handling user interactions. * * @example * const schema = Validator.object({ * email: Validator.string().email(), * password: Validator.string().password(), * }); * * const { * formData, onSubmit, formErrors, setFormData, listeners * } = useForm({ * email: "", * password: "", * }, schema); * * @example * const handleOnSubmit = async () => { * // Handle form submission logic here * }; * * <form onSubmit={onSubmit(handleOnSubmit)}> * <input * name="email" // name should be same as in schema key * {...listeners} // Attach listeners here * type="text" * /> * {formErrors.email && <span>{formErrors.email}</span>} * * <input * name="password" // name should be same as in schema key * {...listeners} // Attach listeners here * type="password" * /> * {formErrors.password && <span>{formErrors.password}</span>} * * <button type="submit">Submit</button> * </form> * * // Access individual form data * const email = getFormData('email'); */ export declare function useForm<FormSchema extends ObjectValidator<any>>(defaultFormData: VInfer<FormSchema>, formSchema: FormSchema): UseForm<VInfer<FormSchema>>;