@vuehookform/core 0.1.0

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 @@
1
+ {"version":3,"file":"vuehookform.cjs","names":["result: unknown","current: Record<string, unknown>","types: Record<string, string | string[]>","newErrors: Record<string, string | FieldError>","result: Record<string, unknown>","FormContextKey: InjectionKey<UseFormReturn<ZodType>>","result: Record<string, unknown>","result: Partial<FormState<InferSchema<TSchema>>>"],"sources":["../src/lib/utils/paths.ts","../src/lib/core/formContext.ts","../src/lib/core/useValidation.ts","../src/lib/core/useFieldRegistration.ts","../src/lib/core/useFieldArray.ts","../src/lib/useForm.ts","../src/lib/context.ts","../src/lib/useWatch.ts","../src/lib/useController.ts","../src/lib/useFormState.ts"],"sourcesContent":["/**\n * Get value from object using dot notation path\n * @example get({ user: { name: 'John' } }, 'user.name') => 'John'\n */\nexport function get(obj: Record<string, unknown>, path: string): unknown {\n if (!path) return obj\n\n const keys = path.split('.')\n let result: unknown = obj\n\n for (const key of keys) {\n if (result === null || result === undefined) {\n return undefined\n }\n result = (result as Record<string, unknown>)[key]\n }\n\n return result\n}\n\n/**\n * Set value in object using dot notation path\n * @example set({}, 'user.name', 'John') => { user: { name: 'John' } }\n */\nexport function set(obj: Record<string, unknown>, path: string, value: unknown): void {\n if (!path) return\n\n const keys = path.split('.')\n\n // Prototype pollution protection\n const UNSAFE_KEYS = ['__proto__', 'constructor', 'prototype']\n if (keys.some((k) => UNSAFE_KEYS.includes(k))) return\n const lastKey = keys.pop()!\n let current: Record<string, unknown> = obj\n\n // Create nested objects as needed\n for (const key of keys) {\n if (!(key in current) || typeof current[key] !== 'object') {\n // Check if next key is a number to create array vs object\n const nextKey = keys[keys.indexOf(key) + 1]\n current[key] = nextKey && /^\\d+$/.test(nextKey) ? [] : {}\n }\n current = current[key] as Record<string, unknown>\n }\n\n current[lastKey] = value\n}\n\n/**\n * Delete value from object using dot notation path\n * @example unset({ user: { name: 'John' } }, 'user.name') => { user: {} }\n */\nexport function unset(obj: Record<string, unknown>, path: string): void {\n if (!path) return\n\n const keys = path.split('.')\n const lastKey = keys.pop()!\n let current: Record<string, unknown> = obj\n\n for (const key of keys) {\n if (!(key in current)) return\n current = current[key] as Record<string, unknown>\n }\n\n delete current[lastKey]\n}\n\n/**\n * Check if path exists in object\n */\nexport function has(obj: Record<string, unknown>, path: string): boolean {\n return get(obj, path) !== undefined\n}\n\n/**\n * Generate a unique ID for field array items\n */\nlet idCounter = 0\nexport function generateId(): string {\n return `field_${Date.now()}_${idCounter++}`\n}\n\n/**\n * Check if a path represents an array index\n * @example isArrayPath('users.0') => true\n * @example isArrayPath('users.name') => false\n */\nexport function isArrayPath(path: string): boolean {\n const lastSegment = path.split('.').pop()\n return /^\\d+$/.test(lastSegment || '')\n}\n\n/**\n * Get parent path\n * @example getParentPath('user.addresses.0.street') => 'user.addresses.0'\n */\nexport function getParentPath(path: string): string | undefined {\n const segments = path.split('.')\n if (segments.length <= 1) return undefined\n segments.pop()\n return segments.join('.')\n}\n\n/**\n * Get field name from path\n * @example getFieldName('user.addresses.0.street') => 'street'\n */\nexport function getFieldName(path: string): string {\n return path.split('.').pop() || path\n}\n","import { reactive, ref, shallowRef, type Ref, type ShallowRef } from 'vue'\nimport type { ZodType } from 'zod'\nimport type {\n UseFormOptions,\n FieldErrors,\n InferSchema,\n RegisterOptions,\n FieldArrayItem,\n} from '../types'\n\n/**\n * Internal state for field array management\n */\nexport interface FieldArrayState {\n items: Ref<FieldArrayItem[]>\n values: unknown[]\n}\n\n/**\n * Shared form context containing all reactive state\n * This is passed to sub-modules via dependency injection\n */\nexport interface FormContext<FormValues> {\n // Reactive form data\n formData: Record<string, unknown>\n defaultValues: Record<string, unknown>\n\n // Form state\n errors: ShallowRef<FieldErrors<FormValues>>\n touchedFields: Ref<Record<string, boolean>>\n dirtyFields: Ref<Record<string, boolean>>\n isSubmitting: Ref<boolean>\n isLoading: Ref<boolean>\n submitCount: Ref<number>\n\n // Field tracking\n fieldRefs: Map<string, Ref<HTMLInputElement | null>>\n fieldOptions: Map<string, RegisterOptions>\n fieldArrays: Map<string, FieldArrayState>\n\n // Debounce tracking for async validation\n debounceTimers: Map<string, ReturnType<typeof setTimeout>>\n validationRequestIds: Map<string, number>\n\n // Options\n options: UseFormOptions<ZodType>\n}\n\n/**\n * Create a new form context with all reactive state initialized\n */\nexport function createFormContext<TSchema extends ZodType>(\n options: UseFormOptions<TSchema>,\n): FormContext<InferSchema<TSchema>> {\n type FormValues = InferSchema<TSchema>\n\n // Form data storage\n const formData = reactive<Record<string, unknown>>({})\n const defaultValues = reactive<Record<string, unknown>>({})\n\n // Check if defaultValues is a function (async) or an object (sync)\n const isAsyncDefaults = typeof options.defaultValues === 'function'\n const isLoading = ref(isAsyncDefaults)\n\n if (isAsyncDefaults) {\n // Async default values - load them\n const asyncFn = options.defaultValues as () => Promise<Partial<FormValues>>\n asyncFn()\n .then((values) => {\n Object.assign(defaultValues, values)\n Object.assign(formData, values)\n isLoading.value = false\n })\n .catch((error) => {\n console.error('Failed to load async default values:', error)\n isLoading.value = false\n })\n } else if (options.defaultValues) {\n // Sync default values\n Object.assign(defaultValues, options.defaultValues)\n Object.assign(formData, defaultValues)\n }\n\n // Form state - using Record instead of Set for per-field tracking\n const errors = shallowRef<FieldErrors<FormValues>>({})\n const touchedFields = ref<Record<string, boolean>>({})\n const dirtyFields = ref<Record<string, boolean>>({})\n const isSubmitting = ref(false)\n const submitCount = ref(0)\n\n // Field registration tracking\n const fieldRefs = new Map<string, Ref<HTMLInputElement | null>>()\n const fieldOptions = new Map<string, RegisterOptions>()\n\n // Field array tracking for dynamic arrays\n const fieldArrays = new Map<string, FieldArrayState>()\n\n // Debounce tracking for async validation\n const debounceTimers = new Map<string, ReturnType<typeof setTimeout>>()\n const validationRequestIds = new Map<string, number>()\n\n return {\n formData,\n defaultValues,\n errors,\n touchedFields,\n dirtyFields,\n isSubmitting,\n isLoading,\n submitCount,\n fieldRefs,\n fieldOptions,\n fieldArrays,\n debounceTimers,\n validationRequestIds,\n options: options as UseFormOptions<ZodType>,\n }\n}\n","import type { FormContext } from './formContext'\nimport type { FieldErrors, FieldError } from '../types'\nimport { set, get } from '../utils/paths'\n\n/**\n * Helper to clear errors for a specific field path and its children\n */\nfunction clearFieldErrors<T>(\n errors: FieldErrors<T>,\n fieldPath: string,\n): FieldErrors<T> {\n const newErrors = { ...errors }\n for (const key of Object.keys(newErrors)) {\n if (key === fieldPath || key.startsWith(`${fieldPath}.`)) {\n delete newErrors[key as keyof typeof newErrors]\n }\n }\n return newErrors as FieldErrors<T>\n}\n\n/**\n * Group errors by field path for multi-error support\n */\nfunction groupErrorsByPath(\n issues: Array<{ path: (string | number)[]; message: string; code: string }>,\n): Map<string, Array<{ type: string; message: string }>> {\n const grouped = new Map<string, Array<{ type: string; message: string }>>()\n\n for (const issue of issues) {\n const path = issue.path.join('.')\n const existing = grouped.get(path) || []\n existing.push({ type: issue.code, message: issue.message })\n grouped.set(path, existing)\n }\n\n return grouped\n}\n\n/**\n * Convert grouped errors to FieldError format\n * Single error = string (backward compatible)\n * Multiple errors = FieldError with types\n */\nfunction createFieldError(errors: Array<{ type: string; message: string }>): string | FieldError {\n if (errors.length === 1) {\n // Single error - return string for backward compatibility\n return errors[0].message\n }\n\n // Multiple errors - return structured FieldError\n const types: Record<string, string | string[]> = {}\n for (const err of errors) {\n const existing = types[err.type]\n if (existing) {\n // Multiple errors of same type - make array\n types[err.type] = Array.isArray(existing)\n ? [...existing, err.message]\n : [existing, err.message]\n } else {\n types[err.type] = err.message\n }\n }\n\n return {\n type: errors[0].type,\n message: errors[0].message,\n types,\n }\n}\n\n/**\n * Create validation functions for form\n */\nexport function createValidation<FormValues>(ctx: FormContext<FormValues>) {\n /**\n * Validate a single field or entire form\n */\n async function validate(fieldPath?: string): Promise<boolean> {\n // Use safeParseAsync to avoid throwing\n const result = await ctx.options.schema.safeParseAsync(ctx.formData)\n\n if (result.success) {\n // Clear errors on success\n if (fieldPath) {\n ctx.errors.value = clearFieldErrors(ctx.errors.value, fieldPath)\n } else {\n ctx.errors.value = {} as FieldErrors<FormValues>\n }\n return true\n }\n\n // Validation failed - process errors\n const zodErrors = result.error.issues\n\n if (fieldPath) {\n // Single field validation - filter to only this field's errors\n const fieldErrors = zodErrors.filter((issue) => {\n const path = issue.path.join('.')\n return path === fieldPath || path.startsWith(`${fieldPath}.`)\n })\n\n if (fieldErrors.length === 0) {\n // This specific field is valid, clear its errors\n ctx.errors.value = clearFieldErrors(ctx.errors.value, fieldPath)\n return true\n }\n\n // Update only this field's errors (merge with existing), with multi-error support\n let newErrors = clearFieldErrors(ctx.errors.value, fieldPath)\n const grouped = groupErrorsByPath(fieldErrors)\n\n for (const [path, errors] of grouped) {\n set(newErrors, path, createFieldError(errors))\n }\n\n ctx.errors.value = newErrors as FieldErrors<FormValues>\n return false\n }\n\n // Full form validation with multi-error support\n const newErrors: Record<string, string | FieldError> = {}\n const grouped = groupErrorsByPath(zodErrors)\n\n for (const [path, errors] of grouped) {\n set(newErrors, path, createFieldError(errors))\n }\n\n ctx.errors.value = newErrors as FieldErrors<FormValues>\n return false\n }\n\n return { validate }\n}\n","import { computed, ref } from 'vue'\nimport type { FormContext } from './formContext'\nimport type {\n RegisterOptions,\n RegisterReturn,\n FieldErrors,\n Path,\n} from '../types'\nimport { get, set, unset } from '../utils/paths'\n\n/**\n * Create field registration functions\n */\nexport function createFieldRegistration<FormValues>(\n ctx: FormContext<FormValues>,\n validate: (fieldPath?: string) => Promise<boolean>,\n) {\n /**\n * Register an input field\n */\n function register<TPath extends Path<FormValues>>(\n name: TPath,\n registerOptions?: RegisterOptions,\n ): RegisterReturn {\n const fieldRef = ref<HTMLInputElement | null>(null)\n ctx.fieldRefs.set(name, fieldRef)\n\n if (registerOptions) {\n ctx.fieldOptions.set(name, registerOptions)\n }\n\n // Initialize field value if not set\n if (get(ctx.formData, name) === undefined) {\n const defaultValue = get(ctx.defaultValues, name)\n if (defaultValue !== undefined) {\n set(ctx.formData, name, defaultValue)\n }\n }\n\n /**\n * Run custom field validation with optional debouncing\n */\n const runCustomValidation = async (fieldName: string, value: unknown, requestId: number) => {\n const fieldOpts = ctx.fieldOptions.get(fieldName)\n if (!fieldOpts?.validate || fieldOpts.disabled) {\n return\n }\n\n const error = await fieldOpts.validate(value)\n\n // Check if this is still the latest request (race condition handling)\n const latestRequestId = ctx.validationRequestIds.get(fieldName)\n if (requestId !== latestRequestId) {\n return // Stale request, ignore result\n }\n\n if (error) {\n ctx.errors.value = { ...ctx.errors.value, [fieldName]: error } as FieldErrors<FormValues>\n } else {\n // Clear the error if validation passes\n const newErrors = { ...ctx.errors.value }\n delete newErrors[fieldName as keyof typeof newErrors]\n ctx.errors.value = newErrors as FieldErrors<FormValues>\n }\n }\n\n /**\n * Handle field input (fires on every keystroke)\n */\n const onInput = async (e: Event) => {\n const target = e.target as HTMLInputElement\n const value = target.type === 'checkbox' ? target.checked : target.value\n\n // Update form data\n set(ctx.formData, name, value)\n\n // Mark as dirty using Record\n ctx.dirtyFields.value = { ...ctx.dirtyFields.value, [name]: true }\n\n // Validate based on mode\n if (\n ctx.options.mode === 'onChange' ||\n (ctx.options.mode === 'onTouched' && ctx.touchedFields.value[name]) ||\n (ctx.touchedFields.value[name] && ctx.options.reValidateMode === 'onChange')\n ) {\n await validate(name)\n }\n\n // Custom validation with optional debouncing\n const fieldOpts = ctx.fieldOptions.get(name)\n if (fieldOpts?.validate && !fieldOpts.disabled) {\n // Generate a new request ID for race condition handling\n const requestId = Date.now() + Math.random()\n ctx.validationRequestIds.set(name, requestId)\n\n const debounceMs = fieldOpts.validateDebounce || 0\n\n if (debounceMs > 0) {\n // Cancel any existing debounce timer\n const existingTimer = ctx.debounceTimers.get(name)\n if (existingTimer) {\n clearTimeout(existingTimer)\n }\n\n // Set new debounce timer\n const timer = setTimeout(() => {\n ctx.debounceTimers.delete(name)\n runCustomValidation(name, value, requestId)\n }, debounceMs)\n\n ctx.debounceTimers.set(name, timer)\n } else {\n // No debounce, run immediately\n await runCustomValidation(name, value, requestId)\n }\n }\n }\n\n /**\n * Handle field blur\n */\n const onBlur = async (_e: Event) => {\n // Mark as touched using Record\n ctx.touchedFields.value = { ...ctx.touchedFields.value, [name]: true }\n\n // Validate based on mode\n if (\n ctx.options.mode === 'onBlur' ||\n ctx.options.mode === 'onTouched' ||\n (ctx.submitCount.value > 0 && ctx.options.reValidateMode === 'onBlur')\n ) {\n await validate(name)\n }\n }\n\n /**\n * Ref callback to store element reference\n */\n const refCallback = (el: unknown) => {\n const previousEl = fieldRef.value\n fieldRef.value = el as HTMLInputElement | null\n\n // Set initial value for uncontrolled inputs\n if (el && !registerOptions?.controlled && el instanceof HTMLInputElement) {\n const value = get(ctx.formData, name)\n if (value !== undefined) {\n if (el.type === 'checkbox') {\n el.checked = value as boolean\n } else {\n el.value = value as string\n }\n }\n }\n\n // Handle shouldUnregister when element is removed (ref becomes null)\n if (previousEl && !el) {\n const shouldUnreg =\n registerOptions?.shouldUnregister ?? ctx.options.shouldUnregister ?? false\n\n if (shouldUnreg) {\n // Clear form data for this field\n unset(ctx.formData, name)\n\n // Clear errors for this field\n const newErrors = { ...ctx.errors.value }\n delete newErrors[name as keyof typeof newErrors]\n ctx.errors.value = newErrors as FieldErrors<FormValues>\n\n // Clear touched/dirty state\n const newTouched = { ...ctx.touchedFields.value }\n delete newTouched[name]\n ctx.touchedFields.value = newTouched\n\n const newDirty = { ...ctx.dirtyFields.value }\n delete newDirty[name]\n ctx.dirtyFields.value = newDirty\n\n // Clean up refs and options\n ctx.fieldRefs.delete(name)\n ctx.fieldOptions.delete(name)\n\n // Clean up debounce timers\n const timer = ctx.debounceTimers.get(name)\n if (timer) {\n clearTimeout(timer)\n ctx.debounceTimers.delete(name)\n }\n ctx.validationRequestIds.delete(name)\n }\n }\n }\n\n return {\n name,\n ref: refCallback,\n onInput,\n onBlur,\n ...(registerOptions?.controlled && {\n value: computed({\n get: () => get(ctx.formData, name),\n set: (val) => {\n set(ctx.formData, name, val)\n ctx.dirtyFields.value = { ...ctx.dirtyFields.value, [name]: true }\n },\n }),\n }),\n }\n }\n\n /**\n * Unregister a field to clean up refs and options\n */\n function unregister<TPath extends Path<FormValues>>(name: TPath): void {\n ctx.fieldRefs.delete(name)\n ctx.fieldOptions.delete(name)\n\n // Clean up debounce timers\n const timer = ctx.debounceTimers.get(name)\n if (timer) {\n clearTimeout(timer)\n ctx.debounceTimers.delete(name)\n }\n ctx.validationRequestIds.delete(name)\n }\n\n return { register, unregister }\n}\n","import { ref } from 'vue'\nimport type { FormContext } from './formContext'\nimport type { FieldArray, FieldArrayItem, Path } from '../types'\nimport { get, set, generateId } from '../utils/paths'\n\n/**\n * Create field array management functions\n */\nexport function createFieldArrayManager<FormValues>(\n ctx: FormContext<FormValues>,\n validate: (fieldPath?: string) => Promise<boolean>,\n) {\n /**\n * Manage dynamic field arrays\n */\n function fields<TPath extends Path<FormValues>>(name: TPath): FieldArray {\n // Get or create field array entry\n let fieldArray = ctx.fieldArrays.get(name)\n\n if (!fieldArray) {\n const existingValues = (get(ctx.formData, name) || []) as unknown[]\n fieldArray = {\n items: ref<FieldArrayItem[]>([]),\n values: existingValues,\n }\n ctx.fieldArrays.set(name, fieldArray)\n\n // Initialize form data if needed\n if (!get(ctx.formData, name)) {\n set(ctx.formData, name, [] as unknown[])\n }\n }\n\n // Capture reference for closures\n const fa = fieldArray\n\n /**\n * Helper to create items with dynamic index lookup\n * Uses getters so index is always current, not stale\n */\n const createItem = (key: string): FieldArrayItem => ({\n key,\n get index() {\n return fa.items.value.findIndex((item) => item.key === key)\n },\n remove() {\n const currentIndex = fa.items.value.findIndex((item) => item.key === key)\n if (currentIndex !== -1) {\n removeAt(currentIndex)\n }\n },\n })\n\n // Populate items if empty (first access after creation)\n if (fa.items.value.length === 0 && fa.values.length > 0) {\n fa.items.value = fa.values.map(() => createItem(generateId()))\n }\n\n const append = (value: unknown) => {\n const currentValues = (get(ctx.formData, name) || []) as unknown[]\n const newValues = [...currentValues, value]\n set(ctx.formData, name, newValues)\n\n fa.items.value = [...fa.items.value, createItem(generateId())]\n\n ctx.dirtyFields.value = { ...ctx.dirtyFields.value, [name]: true }\n\n if (ctx.options.mode === 'onChange') {\n validate(name)\n }\n }\n\n const prepend = (value: unknown) => {\n insert(0, value)\n }\n\n const update = (index: number, value: unknown) => {\n const currentValues = (get(ctx.formData, name) || []) as unknown[]\n if (index < 0 || index >= currentValues.length) {\n return // Invalid index, do nothing\n }\n const newValues = [...currentValues]\n newValues[index] = value\n set(ctx.formData, name, newValues)\n\n // Keep the same key - no items array change needed (preserves stable identity)\n ctx.dirtyFields.value = { ...ctx.dirtyFields.value, [name]: true }\n\n if (ctx.options.mode === 'onChange') {\n validate(name)\n }\n }\n\n const removeAt = (index: number) => {\n const currentValues = (get(ctx.formData, name) || []) as unknown[]\n const newValues = currentValues.filter((_: unknown, i: number) => i !== index)\n set(ctx.formData, name, newValues)\n\n // Remove item by current index, keep others (indices auto-update via getter)\n const keyToRemove = fa.items.value[index]?.key\n fa.items.value = fa.items.value.filter((item) => item.key !== keyToRemove)\n\n ctx.dirtyFields.value = { ...ctx.dirtyFields.value, [name]: true }\n\n if (ctx.options.mode === 'onChange') {\n validate(name)\n }\n }\n\n const insert = (index: number, value: unknown) => {\n const currentValues = (get(ctx.formData, name) || []) as unknown[]\n const newValues = [...currentValues.slice(0, index), value, ...currentValues.slice(index)]\n set(ctx.formData, name, newValues)\n\n const newItem = createItem(generateId())\n fa.items.value = [...fa.items.value.slice(0, index), newItem, ...fa.items.value.slice(index)]\n\n ctx.dirtyFields.value = { ...ctx.dirtyFields.value, [name]: true }\n\n if (ctx.options.mode === 'onChange') {\n validate(name)\n }\n }\n\n const swap = (indexA: number, indexB: number) => {\n const currentValues = (get(ctx.formData, name) || []) as unknown[]\n const newValues = [...currentValues]\n ;[newValues[indexA], newValues[indexB]] = [newValues[indexB], newValues[indexA]]\n set(ctx.formData, name, newValues)\n\n // Swap items in array (indices auto-update via getter)\n const newItems = [...fa.items.value]\n const itemA = newItems[indexA]\n const itemB = newItems[indexB]\n if (itemA && itemB) {\n newItems[indexA] = itemB\n newItems[indexB] = itemA\n fa.items.value = newItems\n }\n\n ctx.dirtyFields.value = { ...ctx.dirtyFields.value, [name]: true }\n\n if (ctx.options.mode === 'onChange') {\n validate(name)\n }\n }\n\n const move = (from: number, to: number) => {\n const currentValues = (get(ctx.formData, name) || []) as unknown[]\n const newValues = [...currentValues]\n const [removed] = newValues.splice(from, 1)\n if (removed !== undefined) {\n newValues.splice(to, 0, removed)\n set(ctx.formData, name, newValues)\n }\n\n // Move item in array (indices auto-update via getter)\n const newItems = [...fa.items.value]\n const [removedItem] = newItems.splice(from, 1)\n if (removedItem) {\n newItems.splice(to, 0, removedItem)\n fa.items.value = newItems\n }\n\n ctx.dirtyFields.value = { ...ctx.dirtyFields.value, [name]: true }\n\n if (ctx.options.mode === 'onChange') {\n validate(name)\n }\n }\n\n return {\n value: fa.items.value,\n append,\n prepend,\n remove: removeAt,\n insert,\n swap,\n move,\n update,\n }\n }\n\n return { fields }\n}\n","import { computed } from 'vue'\nimport type { ZodType } from 'zod'\nimport type {\n UseFormOptions,\n UseFormReturn,\n FormState,\n FieldErrors,\n FieldState,\n ErrorOption,\n SetFocusOptions,\n ResetOptions,\n InferSchema,\n Path,\n PathValue,\n} from './types'\nimport { get, set } from './utils/paths'\nimport { createFormContext } from './core/formContext'\nimport { createValidation } from './core/useValidation'\nimport { createFieldRegistration } from './core/useFieldRegistration'\nimport { createFieldArrayManager } from './core/useFieldArray'\n\n/**\n * Main form management composable\n *\n * @example\n * ```ts\n * const schema = z.object({\n * email: z.email(),\n * name: z.string().min(2)\n * })\n *\n * const { register, handleSubmit, formState } = useForm({ schema })\n *\n * const onSubmit = (data) => {\n * console.log(data) // { email: '...', name: '...' }\n * }\n * ```\n */\nexport function useForm<TSchema extends ZodType>(\n options: UseFormOptions<TSchema>,\n): UseFormReturn<TSchema> {\n type FormValues = InferSchema<TSchema>\n\n // Create shared context with all reactive state\n const ctx = createFormContext(options)\n\n // Create validation functions\n const { validate } = createValidation<FormValues>(ctx)\n\n // Create field registration functions\n const { register, unregister } = createFieldRegistration<FormValues>(ctx, validate)\n\n // Create field array manager\n const { fields } = createFieldArrayManager<FormValues>(ctx, validate)\n\n /**\n * Get current form state\n */\n const formState = computed<FormState<FormValues>>(() => ({\n errors: ctx.errors.value,\n isDirty: Object.keys(ctx.dirtyFields.value).some((k) => ctx.dirtyFields.value[k]),\n dirtyFields: ctx.dirtyFields.value,\n isValid:\n (ctx.submitCount.value > 0 || Object.keys(ctx.touchedFields.value).length > 0) &&\n Object.keys(ctx.errors.value).length === 0,\n isSubmitting: ctx.isSubmitting.value,\n isLoading: ctx.isLoading.value,\n touchedFields: ctx.touchedFields.value,\n submitCount: ctx.submitCount.value,\n }))\n\n /**\n * Handle form submission\n */\n function handleSubmit(\n onValid: (data: FormValues) => void | Promise<void>,\n onInvalid?: (errors: FieldErrors<FormValues>) => void,\n ) {\n return async (e: Event) => {\n e.preventDefault()\n\n ctx.isSubmitting.value = true\n ctx.submitCount.value++\n\n try {\n // Collect values from uncontrolled inputs\n for (const [name, fieldRef] of ctx.fieldRefs.entries()) {\n const el = fieldRef.value\n if (el) {\n const opts = ctx.fieldOptions.get(name)\n if (!opts?.controlled) {\n const value = el.type === 'checkbox' ? el.checked : el.value\n set(ctx.formData, name, value)\n }\n }\n }\n\n // Validate entire form\n const isValid = await validate()\n\n if (isValid) {\n // Call success handler with validated data\n await onValid(ctx.formData as FormValues)\n } else {\n // Call error handler if provided\n onInvalid?.(ctx.errors.value)\n }\n } finally {\n ctx.isSubmitting.value = false\n }\n }\n }\n\n /**\n * Set field value programmatically\n */\n function setValue<TPath extends Path<FormValues>>(\n name: TPath,\n value: PathValue<FormValues, TPath>,\n ): void {\n set(ctx.formData, name, value)\n ctx.dirtyFields.value = { ...ctx.dirtyFields.value, [name]: true }\n\n // Update input element if it exists\n const fieldRef = ctx.fieldRefs.get(name)\n if (fieldRef?.value) {\n const el = fieldRef.value\n if (el.type === 'checkbox') {\n el.checked = value as boolean\n } else {\n el.value = value as string\n }\n }\n\n // Validate if needed\n if (options.mode === 'onChange' || ctx.touchedFields.value[name]) {\n validate(name)\n }\n }\n\n /**\n * Get field value\n */\n function getValue<TPath extends Path<FormValues>>(\n name: TPath,\n ): PathValue<FormValues, TPath> | undefined {\n return get(ctx.formData, name) as PathValue<FormValues, TPath> | undefined\n }\n\n /**\n * Reset form to default values\n */\n function reset(values?: Partial<FormValues>, resetOptions?: ResetOptions): void {\n const opts = resetOptions || {}\n\n // Update default values unless keepDefaultValues is true\n if (!opts.keepDefaultValues && values) {\n Object.assign(ctx.defaultValues, values)\n }\n\n // Clear form data\n Object.keys(ctx.formData).forEach((key) => delete ctx.formData[key])\n\n // Apply new values or defaults\n const newValues = values || ctx.defaultValues\n Object.assign(ctx.formData, newValues)\n\n // Reset state based on options\n if (!opts.keepErrors) {\n ctx.errors.value = {} as FieldErrors<FormValues>\n }\n if (!opts.keepTouched) {\n ctx.touchedFields.value = {}\n }\n if (!opts.keepDirty) {\n ctx.dirtyFields.value = {}\n }\n if (!opts.keepSubmitCount) {\n ctx.submitCount.value = 0\n }\n if (!opts.keepIsSubmitting) {\n ctx.isSubmitting.value = false\n }\n\n // Always clear field arrays (they'll be recreated on next access)\n ctx.fieldArrays.clear()\n\n // Update input elements\n for (const [name, fieldRef] of ctx.fieldRefs.entries()) {\n const el = fieldRef.value\n if (el) {\n const value = get(newValues as Record<string, unknown>, name)\n if (value !== undefined) {\n if (el.type === 'checkbox') {\n el.checked = value as boolean\n } else {\n el.value = value as string\n }\n }\n }\n }\n }\n\n /**\n * Watch field value(s) reactively\n */\n function watch<TPath extends Path<FormValues>>(name?: TPath | TPath[]) {\n return computed(() => {\n if (!name) {\n return ctx.formData\n }\n if (Array.isArray(name)) {\n return name.reduce(\n (acc, n) => {\n acc[n] = get(ctx.formData, n)\n return acc\n },\n {} as Record<TPath, unknown>,\n )\n }\n return get(ctx.formData, name)\n })\n }\n\n // ========================================\n // NEW P0/P1 FEATURES\n // ========================================\n\n /**\n * Clear errors for one or more fields, or all errors\n */\n function clearErrors<TPath extends Path<FormValues>>(name?: TPath | TPath[]): void {\n if (name === undefined) {\n // Clear all errors\n ctx.errors.value = {} as FieldErrors<FormValues>\n return\n }\n\n const fieldsToClean = Array.isArray(name) ? name : [name]\n const newErrors = { ...ctx.errors.value }\n\n for (const field of fieldsToClean) {\n // Clear exact path and any nested paths\n for (const key of Object.keys(newErrors)) {\n if (key === field || key.startsWith(`${field}.`)) {\n delete newErrors[key as keyof typeof newErrors]\n }\n }\n }\n\n ctx.errors.value = newErrors as FieldErrors<FormValues>\n }\n\n /**\n * Programmatically set an error for a field\n * Supports both simple string errors (backward compatible) and structured FieldError objects\n */\n function setError<TPath extends Path<FormValues>>(\n name: TPath | 'root' | `root.${string}`,\n error: ErrorOption,\n ): void {\n const newErrors = { ...ctx.errors.value }\n\n // Create structured error if type is provided, otherwise use string for backward compatibility\n const errorValue = error.type\n ? { type: error.type, message: error.message }\n : error.message\n\n set(newErrors, name, errorValue)\n ctx.errors.value = newErrors as FieldErrors<FormValues>\n }\n\n /**\n * Get form values - all values, single field, or multiple fields\n */\n function getValues(): FormValues\n function getValues<TPath extends Path<FormValues>>(name: TPath): PathValue<FormValues, TPath>\n function getValues<TPath extends Path<FormValues>>(names: TPath[]): Partial<FormValues>\n function getValues<TPath extends Path<FormValues>>(\n nameOrNames?: TPath | TPath[],\n ): FormValues | PathValue<FormValues, TPath> | Partial<FormValues> {\n // Sync values from uncontrolled inputs before returning\n for (const [name, fieldRef] of ctx.fieldRefs.entries()) {\n const el = fieldRef.value\n if (el) {\n const opts = ctx.fieldOptions.get(name)\n if (!opts?.controlled) {\n const value = el.type === 'checkbox' ? el.checked : el.value\n set(ctx.formData, name, value)\n }\n }\n }\n\n if (nameOrNames === undefined) {\n // Return all values\n return { ...ctx.formData } as FormValues\n }\n\n if (Array.isArray(nameOrNames)) {\n // Return multiple field values\n const result: Record<string, unknown> = {}\n for (const fieldName of nameOrNames) {\n result[fieldName] = get(ctx.formData, fieldName)\n }\n return result as Partial<FormValues>\n }\n\n // Return single field value\n return get(ctx.formData, nameOrNames) as PathValue<FormValues, TPath>\n }\n\n /**\n * Get the state of an individual field\n */\n function getFieldState<TPath extends Path<FormValues>>(name: TPath): FieldState {\n const error = get(ctx.errors.value, name) as string | { type: string; message: string } | undefined\n return {\n isDirty: ctx.dirtyFields.value[name] === true,\n isTouched: ctx.touchedFields.value[name] === true,\n invalid: error !== undefined && error !== null,\n error,\n }\n }\n\n /**\n * Manually trigger validation for specific fields or entire form\n */\n async function trigger<TPath extends Path<FormValues>>(\n name?: TPath | TPath[],\n ): Promise<boolean> {\n if (name === undefined) {\n // Validate entire form\n return await validate()\n }\n\n if (Array.isArray(name)) {\n // Validate multiple fields\n let allValid = true\n for (const fieldName of name) {\n const isValid = await validate(fieldName)\n if (!isValid) {\n allValid = false\n }\n }\n return allValid\n }\n\n // Validate single field\n return await validate(name)\n }\n\n /**\n * Programmatically focus a field\n */\n function setFocus<TPath extends Path<FormValues>>(\n name: TPath,\n focusOptions?: SetFocusOptions,\n ): void {\n const fieldRef = ctx.fieldRefs.get(name)\n\n if (!fieldRef?.value) {\n return\n }\n\n const el = fieldRef.value\n\n // Check if element is focusable\n if (typeof el.focus === 'function') {\n el.focus()\n\n // Select text if requested and element supports selection\n if (\n focusOptions?.shouldSelect &&\n el instanceof HTMLInputElement &&\n typeof el.select === 'function'\n ) {\n el.select()\n }\n }\n }\n\n return {\n register,\n unregister,\n handleSubmit,\n formState,\n fields,\n setValue,\n getValue,\n reset,\n watch,\n validate,\n clearErrors,\n setError,\n getValues,\n getFieldState,\n trigger,\n setFocus,\n }\n}\n","import { inject, provide, type InjectionKey } from 'vue'\nimport type { UseFormReturn } from './types'\nimport type { ZodType } from 'zod'\n\n/**\n * Injection key for form context\n */\nexport const FormContextKey: InjectionKey<UseFormReturn<ZodType>> = Symbol('FormContext')\n\n/**\n * Provide form methods to child components via Vue's dependency injection.\n *\n * Call this in a parent component's setup function after calling useForm().\n *\n * @example\n * ```ts\n * // Parent component\n * const form = useForm({ schema })\n * provideForm(form)\n * ```\n *\n * @param methods - The return value from useForm()\n */\nexport function provideForm<TSchema extends ZodType>(methods: UseFormReturn<TSchema>): void {\n provide(FormContextKey, methods as unknown as UseFormReturn<ZodType>)\n}\n\n/**\n * Access form methods in a child component via Vue's dependency injection.\n *\n * Must be used within a component tree where provideForm() has been called.\n *\n * @example\n * ```ts\n * // Child component\n * const { register, formState } = useFormContext()\n * ```\n *\n * @returns The form methods from the parent component's useForm() call\n * @throws Error if used outside of a FormProvider context\n */\nexport function useFormContext<TSchema extends ZodType>(): UseFormReturn<TSchema> {\n const context = inject(FormContextKey)\n\n if (!context) {\n throw new Error(\n 'useFormContext must be used within a component tree where provideForm() has been called. ' +\n 'Make sure to call provideForm(useForm({ schema })) in a parent component.',\n )\n }\n\n return context as unknown as UseFormReturn<TSchema>\n}\n","import { computed, type ComputedRef } from 'vue'\nimport type { ZodType } from 'zod'\nimport type { UseFormReturn, Path, InferSchema } from './types'\nimport { useFormContext } from './context'\nimport { get } from './utils/paths'\n\n/**\n * Options for useWatch composable\n */\nexport interface UseWatchOptions<TSchema extends ZodType, TPath extends Path<InferSchema<TSchema>>> {\n /** Form control from useForm (uses context if not provided) */\n control?: UseFormReturn<TSchema>\n /** Field path or array of paths to watch (watches all if not provided) */\n name?: TPath | TPath[]\n /** Default value when field is undefined */\n defaultValue?: unknown\n}\n\n/**\n * Watch form field values reactively without the full form instance\n *\n * This composable allows you to subscribe to form value changes from any component\n * in the tree, as long as the form context is provided via provideForm().\n *\n * @example\n * ```ts\n * // Watch a single field\n * const email = useWatch({ name: 'email' })\n *\n * // Watch multiple fields\n * const fields = useWatch({ name: ['firstName', 'lastName'] })\n *\n * // Watch all form values\n * const allValues = useWatch({})\n *\n * // With explicit control\n * const { control } = useForm({ schema })\n * const email = useWatch({ control, name: 'email' })\n *\n * // With default value\n * const status = useWatch({ name: 'status', defaultValue: 'pending' })\n * ```\n */\nexport function useWatch<\n TSchema extends ZodType,\n TPath extends Path<InferSchema<TSchema>> = Path<InferSchema<TSchema>>,\n>(options: UseWatchOptions<TSchema, TPath> = {}): ComputedRef<unknown> {\n const { control, name, defaultValue } = options\n\n // Get form control from context if not provided\n const form = control ?? useFormContext<TSchema>()\n\n return computed(() => {\n if (name === undefined) {\n // Watch all values\n return form.getValues()\n }\n\n if (Array.isArray(name)) {\n // Watch multiple fields\n const result: Record<string, unknown> = {}\n for (const fieldName of name) {\n const value = get(form.getValues(), fieldName)\n result[fieldName] = value ?? defaultValue\n }\n return result\n }\n\n // Watch single field\n const value = get(form.getValues(), name)\n return value ?? defaultValue\n })\n}\n","import { computed, ref, type ComputedRef, type Ref } from 'vue'\nimport type { ZodType } from 'zod'\nimport type { UseFormReturn, Path, PathValue, InferSchema, FieldState } from './types'\nimport { useFormContext } from './context'\nimport { get } from './utils/paths'\n\n/**\n * Options for useController composable\n */\nexport interface UseControllerOptions<\n TSchema extends ZodType,\n TPath extends Path<InferSchema<TSchema>>,\n> {\n /** Field name/path */\n name: TPath\n /** Form control from useForm (uses context if not provided) */\n control?: UseFormReturn<TSchema>\n /** Default value for the field */\n defaultValue?: PathValue<InferSchema<TSchema>, TPath>\n}\n\n/**\n * Field props returned by useController\n */\nexport interface ControllerFieldProps<TValue> {\n /** Current field value */\n value: Ref<TValue>\n /** Field name */\n name: string\n /** Change handler - call with new value */\n onChange: (value: TValue) => void\n /** Blur handler */\n onBlur: () => void\n /** Ref callback for the input element */\n ref: (el: HTMLElement | null) => void\n}\n\n/**\n * Return value from useController\n */\nexport interface UseControllerReturn<TValue> {\n /** Field props for binding to input components */\n field: ControllerFieldProps<TValue>\n /** Current field state (errors, dirty, touched) */\n fieldState: ComputedRef<FieldState>\n}\n\n/**\n * Hook for controlled components that need fine-grained control over field state\n *\n * This composable is useful for integrating with custom input components or\n * third-party UI libraries that don't work with the standard register() approach.\n *\n * @example\n * ```ts\n * // Basic usage with context\n * const { field, fieldState } = useController({ name: 'email' })\n *\n * // With explicit control\n * const { control } = useForm({ schema })\n * const { field, fieldState } = useController({ control, name: 'email' })\n *\n * // In template:\n * // <CustomInput\n * // :value=\"field.value.value\"\n * // @update:modelValue=\"field.onChange\"\n * // @blur=\"field.onBlur\"\n * // />\n * // <span v-if=\"fieldState.value.error\">{{ fieldState.value.error }}</span>\n * ```\n */\nexport function useController<\n TSchema extends ZodType,\n TPath extends Path<InferSchema<TSchema>>,\n>(\n options: UseControllerOptions<TSchema, TPath>,\n): UseControllerReturn<PathValue<InferSchema<TSchema>, TPath>> {\n type TValue = PathValue<InferSchema<TSchema>, TPath>\n\n const { name, control, defaultValue } = options\n\n // Get form control from context if not provided\n const form = control ?? useFormContext<TSchema>()\n\n // Element ref for focus management\n const elementRef = ref<HTMLElement | null>(null)\n\n // Initialize with default value if provided\n if (defaultValue !== undefined && form.getValue(name) === undefined) {\n form.setValue(name, defaultValue)\n }\n\n // Create reactive value\n const value = computed({\n get: () => {\n const currentValue = form.getValue(name)\n return (currentValue ?? defaultValue) as TValue\n },\n set: (newValue: TValue) => {\n form.setValue(name, newValue)\n },\n })\n\n // Change handler\n const onChange = (newValue: TValue) => {\n form.setValue(name, newValue)\n }\n\n // Blur handler - triggers validation based on mode\n const onBlur = () => {\n form.trigger(name)\n }\n\n // Ref callback\n const refCallback = (el: HTMLElement | null) => {\n elementRef.value = el\n }\n\n // Field state computed\n const fieldState = computed<FieldState>(() => {\n return form.getFieldState(name)\n })\n\n return {\n field: {\n value: value as unknown as Ref<TValue>,\n name,\n onChange,\n onBlur,\n ref: refCallback,\n },\n fieldState,\n }\n}\n","import { computed, type ComputedRef } from 'vue'\nimport type { ZodType } from 'zod'\nimport type { UseFormReturn, FormState, InferSchema } from './types'\nimport { useFormContext } from './context'\n\n/**\n * Keys of FormState that can be subscribed to\n */\nexport type FormStateKey = keyof FormState<unknown>\n\n/**\n * Options for useFormState composable\n */\nexport interface UseFormStateOptions<TSchema extends ZodType> {\n /** Form control from useForm (uses context if not provided) */\n control?: UseFormReturn<TSchema>\n /** Specific state keys to subscribe to (subscribes to all if not provided) */\n name?: FormStateKey | FormStateKey[]\n}\n\n/**\n * Subscribe to specific form state properties\n *\n * This composable allows you to efficiently subscribe to only the form state\n * properties you need, reducing unnecessary re-renders.\n *\n * @example\n * ```ts\n * // Subscribe to all form state\n * const formState = useFormState({})\n *\n * // Subscribe to specific properties\n * const { isSubmitting, errors } = useFormState({ name: ['isSubmitting', 'errors'] })\n *\n * // Subscribe to single property\n * const isDirty = useFormState({ name: 'isDirty' })\n *\n * // With explicit control\n * const { control } = useForm({ schema })\n * const formState = useFormState({ control })\n * ```\n */\nexport function useFormState<TSchema extends ZodType>(\n options: UseFormStateOptions<TSchema> = {},\n): ComputedRef<Partial<FormState<InferSchema<TSchema>>>> {\n const { control, name } = options\n\n // Get form control from context if not provided\n const form = control ?? useFormContext<TSchema>()\n\n return computed(() => {\n const fullState = form.formState.value\n\n if (name === undefined) {\n // Return all state\n return { ...fullState }\n }\n\n if (Array.isArray(name)) {\n // Return specific properties\n const result: Partial<FormState<InferSchema<TSchema>>> = {}\n for (const key of name) {\n ;(result as Record<string, unknown>)[key] = fullState[key]\n }\n return result\n }\n\n // Return single property wrapped in object\n return { [name]: fullState[name] } as Partial<FormState<InferSchema<TSchema>>>\n })\n}\n"],"mappings":"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"}