@d3vtool/hooks
Version:
Collection of custom React hooks to simplify tasks in your React projects.
106 lines (105 loc) • 4.39 kB
TypeScript
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>>;