UNPKG

@explita/daily-toolset-form

Version:

A lightweight form toolkit for React built with developer ergonomics in mind. Includes a flexible Form component, useForm, useField, and useFormContext hooks for managing form state and validation with ease. Designed to simplify complex forms while remain

79 lines (78 loc) 3.89 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useFormContext = useFormContext; const react_1 = require("react"); const form_1 = require("../providers/form"); function isZodSchema(schema) { return typeof schema === "object" && schema !== null && "_def" in schema; } /** * useFormContext is a hook that provides a form instance. The form instance * contains the form state and methods to update the form state. The hook is * generic and can be used with any schema type. * * The hook will use the schema and default values provided in the props to * update the form state. If the `schema` prop is provided, the hook will * validate the form state using the provided schema. If the `defaultValues` * prop is provided, the hook will update the form state with the provided * default values. * * The hook will also accept an `errors` prop, which should be an object with * the same shape as the form state. The hook will update the form errors with * the provided errors. * * The hook must be used within a Form component. * * @param {Object} [props] - The props for useFormContext. * @param {Schema} [props.schema] - The schema to use for form validation. * @param {DefaultValues} [props.defaultValues] - The default values for the form. * @param {Record<keyof DefaultValues, string | undefined>} [props.errors] - The errors for the form. * @returns {UseFormHook<DefaultValues>} The form instance. */ function useFormContext(props) { const form = (0, react_1.use)(form_1.FormContext); if (!form) { throw new Error("useFormContext must be used within a FormProvider"); } const previousErrorsRef = (0, react_1.useRef)({}); const previousDefaultValuesRef = (0, react_1.useRef)({}); (0, react_1.useEffect)(() => { if ((props === null || props === void 0 ? void 0 : props.schema) && isZodSchema(props.schema)) { form.setSchema(props.schema); } }, [form, props === null || props === void 0 ? void 0 : props.schema]); (0, react_1.useEffect)(() => { if (props === null || props === void 0 ? void 0 : props.defaultValues) { const previousDefaultValues = previousDefaultValuesRef.current; const valuesEqual = Object.keys(previousDefaultValues).length === Object.keys(props.defaultValues).length && Object.keys(props.defaultValues).every((key) => previousDefaultValues[key] === props.defaultValues[key]); if (!valuesEqual) { form.setValues(props.defaultValues); previousDefaultValuesRef.current = props.defaultValues; // Update the ref to the new state } } }, [form, props === null || props === void 0 ? void 0 : props.defaultValues]); (0, react_1.useEffect)(() => { if (props === null || props === void 0 ? void 0 : props.errors) { if (Object.keys(props.errors).length === 0) { // Only clear errors if they are different from the previous state if (Object.keys(previousErrorsRef.current).length > 0) { form.setErrors({}); previousErrorsRef.current = {}; // Update the ref to the new state } } else { const hasErrorsChanged = Object.keys(props.errors).length !== Object.keys(previousErrorsRef.current).length || Object.keys(props.errors).some((key) => previousErrorsRef.current[key] !== props.errors[key]); if (hasErrorsChanged) { form.setErrors(props.errors); previousErrorsRef.current = props.errors; // Update the ref to the new state } } } }, [form, props === null || props === void 0 ? void 0 : props.errors]); // @ts-ignore return form; }