@vuehookform/core 0.4.4 → 0.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,37 @@
1
+ import { InjectionKey } from 'vue';
2
+ import { UseFormReturn } from './types';
3
+ import { ZodType } from 'zod';
4
+ /**
5
+ * Injection key for form context
6
+ */
7
+ export declare const FormContextKey: InjectionKey<UseFormReturn<ZodType>>;
8
+ /**
9
+ * Provide form methods to child components via Vue's dependency injection.
10
+ *
11
+ * Call this in a parent component's setup function after calling useForm().
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * // Parent component
16
+ * const form = useForm({ schema })
17
+ * provideForm(form)
18
+ * ```
19
+ *
20
+ * @param methods - The return value from useForm()
21
+ */
22
+ export declare function provideForm<TSchema extends ZodType>(methods: UseFormReturn<TSchema>): void;
23
+ /**
24
+ * Access form methods in a child component via Vue's dependency injection.
25
+ *
26
+ * Must be used within a component tree where provideForm() has been called.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * // Child component
31
+ * const { register, formState } = useFormContext()
32
+ * ```
33
+ *
34
+ * @returns The form methods from the parent component's useForm() call
35
+ * @throws Error if used outside of a FormProvider context
36
+ */
37
+ export declare function useFormContext<TSchema extends ZodType>(): UseFormReturn<TSchema>;
@@ -0,0 +1,48 @@
1
+ import { Ref } from 'vue';
2
+ import { RegisterOptions } from '../types';
3
+ /**
4
+ * Extract the actual HTMLInputElement from a ref value.
5
+ * Handles both native elements and Vue component instances (PrimeVue, Vuetify, etc.)
6
+ *
7
+ * Vue component libraries typically expose:
8
+ * - $el: The root DOM element of the component
9
+ * - Some components wrap inputs in divs, so we may need to query for the input
10
+ *
11
+ * @param refValue - The value from fieldRef.value (HTMLInputElement, Component, or null)
12
+ * @returns The underlying HTMLInputElement, or null if not found
13
+ */
14
+ export declare function getInputElement(refValue: unknown): HTMLInputElement | null;
15
+ /**
16
+ * Get a focusable element from a ref value.
17
+ * Works with both native elements and Vue component instances.
18
+ *
19
+ * @param refValue - The value from fieldRef.value
20
+ * @returns The focusable HTMLElement, or null if not found
21
+ */
22
+ export declare function getFocusableElement(refValue: unknown): HTMLElement | null;
23
+ /**
24
+ * Sync values from uncontrolled DOM inputs to form data
25
+ *
26
+ * This reads the current DOM state from uncontrolled inputs and updates
27
+ * the formData object. Used before form submission and when getting values.
28
+ *
29
+ * Handles type coercion for:
30
+ * - checkbox: returns boolean (el.checked)
31
+ * - number/range: returns number (el.valueAsNumber)
32
+ * - all other types: returns string (el.value)
33
+ *
34
+ * @param fieldRefs - Map of field names to their DOM element refs
35
+ * @param fieldOptions - Map of field names to their registration options
36
+ * @param formData - The reactive form data object to update
37
+ */
38
+ export declare function syncUncontrolledInputs(fieldRefs: Map<string, Ref<unknown>>, fieldOptions: Map<string, RegisterOptions>, formData: Record<string, unknown>): void;
39
+ /**
40
+ * Update a single DOM element with a new value
41
+ *
42
+ * Handles both checkbox and text inputs appropriately.
43
+ * Supports both native elements and Vue component instances.
44
+ *
45
+ * @param refValue - The ref value (HTMLInputElement, Vue component, or null)
46
+ * @param value - The value to set
47
+ */
48
+ export declare function updateDomElement(refValue: unknown, value: unknown): void;
@@ -0,0 +1,53 @@
1
+ import { ShallowRef } from 'vue';
2
+ /**
3
+ * Mark a field as dirty (value has changed from default).
4
+ * Optimized to skip clone if already dirty.
5
+ *
6
+ * @param dirtyFields - The reactive dirty fields record
7
+ * @param fieldName - Name of the field to mark as dirty
8
+ */
9
+ export declare function markFieldDirty(dirtyFields: ShallowRef<Record<string, boolean>>, fieldName: string): void;
10
+ /**
11
+ * Mark a field as touched (user has interacted with it).
12
+ * Optimized to skip clone if already touched.
13
+ *
14
+ * @param touchedFields - The reactive touched fields record
15
+ * @param fieldName - Name of the field to mark as touched
16
+ */
17
+ export declare function markFieldTouched(touchedFields: ShallowRef<Record<string, boolean>>, fieldName: string): void;
18
+ /**
19
+ * Clear dirty state for a field.
20
+ *
21
+ * @param dirtyFields - The reactive dirty fields record
22
+ * @param fieldName - Name of the field to clear
23
+ */
24
+ export declare function clearFieldDirty(dirtyFields: ShallowRef<Record<string, boolean>>, fieldName: string): void;
25
+ /**
26
+ * Clear touched state for a field.
27
+ *
28
+ * @param touchedFields - The reactive touched fields record
29
+ * @param fieldName - Name of the field to clear
30
+ */
31
+ export declare function clearFieldTouched(touchedFields: ShallowRef<Record<string, boolean>>, fieldName: string): void;
32
+ /**
33
+ * Clear errors for a field and its nested paths.
34
+ * Optimized with early exit if nothing to delete.
35
+ *
36
+ * @param errors - The reactive errors record
37
+ * @param fieldName - Name of the field (clears exact match and all nested paths)
38
+ */
39
+ export declare function clearFieldErrors<T>(errors: ShallowRef<Record<string, T>>, fieldName: string): void;
40
+ /**
41
+ * Update field dirty state based on value comparison with default.
42
+ * Field is dirty only if current value differs from default value.
43
+ *
44
+ * Uses lazy hash computation - default hashes are computed on first access
45
+ * and cached for subsequent comparisons.
46
+ *
47
+ * @param dirtyFields - The reactive dirty fields record
48
+ * @param defaultValues - The original default values
49
+ * @param defaultValueHashes - Cache of hashed default values
50
+ * @param fieldName - Name of the field to check
51
+ * @param currentValue - The current value to compare against default
52
+ */
53
+ export declare function updateFieldDirtyState(dirtyFields: ShallowRef<Record<string, boolean>>, defaultValues: Record<string, unknown>, defaultValueHashes: Map<string, string>, fieldName: string, currentValue: unknown): void;
@@ -0,0 +1,117 @@
1
+ import { Ref, ShallowRef } from 'vue';
2
+ import { ZodType } from 'zod';
3
+ import { UseFormOptions, FieldErrors, FieldErrorValue, InferSchema, RegisterOptions, FieldArrayItem, FieldArrayRules } from '../types';
4
+ /**
5
+ * Internal state for field array management.
6
+ * Tracks items, their indices, and array-level validation rules.
7
+ *
8
+ * @internal This interface is used internally by useFieldArray and should not be
9
+ * directly instantiated by consumers.
10
+ */
11
+ export interface FieldArrayState {
12
+ /** Reactive list of field array items with stable keys for Vue reconciliation */
13
+ items: Ref<FieldArrayItem[]>;
14
+ /** Raw array values (kept in sync with formData) */
15
+ values: unknown[];
16
+ /** O(1) lookup cache mapping item keys to their current indices */
17
+ indexCache: Map<string, number>;
18
+ /** Optional validation rules for the array itself (minLength, maxLength, custom) */
19
+ rules?: FieldArrayRules;
20
+ }
21
+ /**
22
+ * Cached event handlers for a field.
23
+ * These are created once per field registration and reused to prevent
24
+ * unnecessary re-renders and closure recreation.
25
+ *
26
+ * @internal This interface is used internally by useFieldRegistration and should not be
27
+ * directly instantiated by consumers.
28
+ */
29
+ export interface FieldHandlers {
30
+ /** Handler for input events, triggers validation based on mode */
31
+ onInput: (e: Event) => Promise<void>;
32
+ /** Handler for blur events, marks field as touched and may trigger validation */
33
+ onBlur: () => Promise<void>;
34
+ /** Ref callback to capture the DOM element reference */
35
+ refCallback: (el: unknown) => void;
36
+ }
37
+ /**
38
+ * Shared form context containing all reactive state.
39
+ * This is the central state container passed to sub-modules via dependency injection.
40
+ *
41
+ * The context is organized into several categories:
42
+ * - **Form Data**: Raw form values and their defaults
43
+ * - **Form State**: Validation errors, touched/dirty tracking, submission state
44
+ * - **Field Tracking**: DOM refs, registration options, field arrays
45
+ * - **Validation**: Caching, debouncing, and async validation coordination
46
+ * - **Configuration**: Form options and disabled state
47
+ *
48
+ * @typeParam FormValues - The inferred type from the Zod schema
49
+ *
50
+ * @internal This interface is used internally by useForm and its sub-modules.
51
+ * Consumers should use the public API returned by useForm() instead.
52
+ */
53
+ export interface FormContext<FormValues> {
54
+ /** Reactive form data object containing current field values */
55
+ formData: Record<string, unknown>;
56
+ /** Original default values used for reset() and dirty detection */
57
+ defaultValues: Record<string, unknown>;
58
+ /** Current validation errors keyed by field path */
59
+ errors: ShallowRef<FieldErrors<FormValues>>;
60
+ /** Record of field paths that have been touched (blurred) */
61
+ touchedFields: ShallowRef<Record<string, boolean>>;
62
+ /** Record of field paths that differ from default values */
63
+ dirtyFields: ShallowRef<Record<string, boolean>>;
64
+ /** Whether the form is currently being submitted */
65
+ isSubmitting: Ref<boolean>;
66
+ /** Whether async default values are being loaded */
67
+ isLoading: Ref<boolean>;
68
+ /** Number of times the form has been submitted */
69
+ submitCount: Ref<number>;
70
+ /** Error that occurred while loading async default values */
71
+ defaultValuesError: Ref<unknown>;
72
+ /** Whether the last submission completed successfully */
73
+ isSubmitSuccessful: Ref<boolean>;
74
+ /** Set of field paths currently being validated (for isValidating state) */
75
+ validatingFields: ShallowRef<Set<string>>;
76
+ /** External errors (e.g., from server) merged with validation errors */
77
+ externalErrors: ShallowRef<FieldErrors<FormValues>>;
78
+ /** Timers for delayed error display per field */
79
+ errorDelayTimers: Map<string, ReturnType<typeof setTimeout>>;
80
+ /** Pending errors waiting for delay timer to complete */
81
+ pendingErrors: Map<string, FieldErrorValue>;
82
+ /** DOM element refs for registered uncontrolled fields */
83
+ fieldRefs: Map<string, Ref<HTMLInputElement | null>>;
84
+ /** Registration options per field path */
85
+ fieldOptions: Map<string, RegisterOptions>;
86
+ /** Field array state for array fields managed by fields() */
87
+ fieldArrays: Map<string, FieldArrayState>;
88
+ /** Cached event handlers to prevent recreation on re-render */
89
+ fieldHandlers: Map<string, FieldHandlers>;
90
+ /** Debounce timers for custom async validation per field */
91
+ debounceTimers: Map<string, ReturnType<typeof setTimeout>>;
92
+ /** Request IDs for canceling stale async validation results */
93
+ validationRequestIds: Map<string, number>;
94
+ /** Generation counter incremented on reset to cancel in-flight validations */
95
+ resetGeneration: Ref<number>;
96
+ /** Cache of validation results keyed by field path and value hash */
97
+ validationCache: Map<string, {
98
+ hash: string;
99
+ isValid: boolean;
100
+ }>;
101
+ /** Debounce timers for schema validation per field */
102
+ schemaValidationTimers: Map<string, ReturnType<typeof setTimeout>>;
103
+ /** Set of field paths with persistent errors (survive validation cycles) */
104
+ persistentErrorFields: Set<string>;
105
+ /** Hashed default values for value-comparison dirty detection */
106
+ defaultValueHashes: Map<string, string>;
107
+ /** Whether the entire form is disabled */
108
+ isDisabled: Ref<boolean>;
109
+ /** Original options passed to useForm() */
110
+ options: UseFormOptions<ZodType>;
111
+ /** Cleanup function to stop all watchers and prevent memory leaks */
112
+ cleanup: () => void;
113
+ }
114
+ /**
115
+ * Create a new form context with all reactive state initialized
116
+ */
117
+ export declare function createFormContext<TSchema extends ZodType>(options: UseFormOptions<TSchema>): FormContext<InferSchema<TSchema>>;
@@ -0,0 +1,8 @@
1
+ import { FormContext } from './formContext';
2
+ import { FieldArray, FieldArrayOptions, Path } from '../types';
3
+ /**
4
+ * Create field array management functions
5
+ */
6
+ export declare function createFieldArrayManager<FormValues>(ctx: FormContext<FormValues>, validate: (fieldPath?: string) => Promise<boolean>, setFocus: (name: string) => void): {
7
+ fields: <TPath extends Path<FormValues>>(name: TPath, options?: FieldArrayOptions) => FieldArray;
8
+ };
@@ -0,0 +1,9 @@
1
+ import { FormContext } from './formContext';
2
+ import { RegisterOptions, RegisterReturn, UnregisterOptions, Path } from '../types';
3
+ /**
4
+ * Create field registration functions
5
+ */
6
+ export declare function createFieldRegistration<FormValues>(ctx: FormContext<FormValues>, validate: (fieldPath?: string) => Promise<boolean>): {
7
+ register: <TPath extends Path<FormValues>>(name: TPath, registerOptions?: RegisterOptions) => RegisterReturn;
8
+ unregister: <TPath extends Path<FormValues>>(name: TPath, options?: UnregisterOptions) => void;
9
+ };
@@ -0,0 +1,8 @@
1
+ import { FormContext } from './formContext';
2
+ /**
3
+ * Create validation functions for form
4
+ */
5
+ export declare function createValidation<FormValues>(ctx: FormContext<FormValues>): {
6
+ validate: (fieldPath?: string) => Promise<boolean>;
7
+ clearAllPendingErrors: () => void;
8
+ };
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Vue Hook Form - TypeScript-first form library for Vue 3
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * import { useForm } from './lib'
7
+ * import { z } from 'zod'
8
+ *
9
+ * const schema = z.object({
10
+ * email: z.email(),
11
+ * name: z.string().min(2)
12
+ * })
13
+ *
14
+ * const { register, handleSubmit, formState } = useForm({ schema })
15
+ * ```
16
+ */
17
+ export { useForm } from './useForm';
18
+ export { provideForm, useFormContext, FormContextKey } from './context';
19
+ export { useWatch, type UseWatchOptions } from './useWatch';
20
+ export { useController, type UseControllerOptions, type UseControllerReturn, type ControllerFieldProps, } from './useController';
21
+ export { useFormState, type UseFormStateOptions, type FormStateKey } from './useFormState';
22
+ export { isFieldError } from './types';
23
+ export type { UseFormOptions, UseFormReturn, UseFormReturn as Control, RegisterOptions, RegisterReturn, FormState, FieldState, FieldErrors, FieldError, FieldErrorValue, ErrorOption, SetErrorsOptions, FieldArray, FieldArrayItem, FieldArrayOptions, FieldArrayRules, FieldArrayFocusOptions, InferSchema, FormValues, FormPath, Path, PathValue, ArrayElement, ArrayPath, FieldPath, ValidationMode, SetFocusOptions, ResetOptions, ResetFieldOptions, AsyncDefaultValues, TriggerOptions, SetValueOptions, UnregisterOptions, CriteriaMode, } from './types';
24
+ export { get, set, unset, clearPathCache } from './utils/paths';