@vuehookform/core 0.2.8 → 0.2.10

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,29 @@
1
+ import { Ref } from 'vue';
2
+ import { RegisterOptions } from '../types';
3
+ /**
4
+ * Sync values from uncontrolled DOM inputs to form data
5
+ *
6
+ * This reads the current DOM state from uncontrolled inputs and updates
7
+ * the formData object. Used before form submission and when getting values.
8
+ *
9
+ * @param fieldRefs - Map of field names to their DOM element refs
10
+ * @param fieldOptions - Map of field names to their registration options
11
+ * @param formData - The reactive form data object to update
12
+ */
13
+ export declare function syncUncontrolledInputs(fieldRefs: Map<string, Ref<HTMLInputElement | null>>, fieldOptions: Map<string, RegisterOptions>, formData: Record<string, unknown>): void;
14
+ /**
15
+ * Update a single DOM element with a new value
16
+ *
17
+ * Handles both checkbox and text inputs appropriately.
18
+ *
19
+ * @param el - The DOM input element to update
20
+ * @param value - The value to set
21
+ */
22
+ export declare function updateDomElement(el: HTMLInputElement, value: unknown): void;
23
+ /**
24
+ * Get value from a DOM element based on its type
25
+ *
26
+ * @param el - The DOM input element
27
+ * @returns The current value (checked state for checkboxes, value for others)
28
+ */
29
+ export declare function getDomElementValue(el: HTMLInputElement): unknown;
@@ -0,0 +1,36 @@
1
+ import { ShallowRef } from 'vue';
2
+ /**
3
+ * Mark a field as dirty (value has changed from default)
4
+ *
5
+ * @param dirtyFields - The reactive dirty fields record
6
+ * @param fieldName - Name of the field to mark as dirty
7
+ */
8
+ export declare function markFieldDirty(dirtyFields: ShallowRef<Record<string, boolean>>, fieldName: string): void;
9
+ /**
10
+ * Mark a field as touched (user has interacted with it)
11
+ *
12
+ * @param touchedFields - The reactive touched fields record
13
+ * @param fieldName - Name of the field to mark as touched
14
+ */
15
+ export declare function markFieldTouched(touchedFields: ShallowRef<Record<string, boolean>>, fieldName: string): void;
16
+ /**
17
+ * Clear dirty state for a field
18
+ *
19
+ * @param dirtyFields - The reactive dirty fields record
20
+ * @param fieldName - Name of the field to clear
21
+ */
22
+ export declare function clearFieldDirty(dirtyFields: ShallowRef<Record<string, boolean>>, fieldName: string): void;
23
+ /**
24
+ * Clear touched state for a field
25
+ *
26
+ * @param touchedFields - The reactive touched fields record
27
+ * @param fieldName - Name of the field to clear
28
+ */
29
+ export declare function clearFieldTouched(touchedFields: ShallowRef<Record<string, boolean>>, fieldName: string): void;
30
+ /**
31
+ * Clear errors for a field and its nested paths
32
+ *
33
+ * @param errors - The reactive errors record
34
+ * @param fieldName - Name of the field (clears exact match and all nested paths)
35
+ */
36
+ export declare function clearFieldErrors<T>(errors: ShallowRef<Record<string, T>>, fieldName: string): void;
package/dist/index.d.ts CHANGED
@@ -17,7 +17,7 @@
17
17
  export { useForm } from './useForm';
18
18
  export { provideForm, useFormContext, FormContextKey } from './context';
19
19
  export { useWatch, type UseWatchOptions } from './useWatch';
20
- export { useController, type UseControllerOptions, type UseControllerReturn, type ControllerFieldProps } from './useController';
20
+ export { useController, type UseControllerOptions, type UseControllerReturn, type ControllerFieldProps, } from './useController';
21
21
  export { useFormState, type UseFormStateOptions, type FormStateKey } from './useFormState';
22
22
  export { isFieldError } from './types';
23
23
  export type { UseFormOptions, UseFormReturn, RegisterOptions, RegisterReturn, FormState, FieldState, FieldErrors, FieldError, FieldErrorValue, ErrorOption, FieldArray, FieldArrayItem, InferSchema, FormValues, FormPath, Path, PathValue, ArrayElement, ArrayPath, ValidationMode, SetFocusOptions, ResetOptions, ResetFieldOptions, AsyncDefaultValues, } from './types';
package/dist/types.d.ts CHANGED
@@ -74,7 +74,7 @@ export type ArrayPath<T> = {
74
74
  * type ItemType = PathValue<Form, 'items.0'> // { id: number }
75
75
  * type ItemId = PathValue<Form, 'items.0.id'> // number
76
76
  */
77
- export type PathValue<T, P extends string> = P extends `${infer K}.${infer Rest}` ? K extends keyof T ? PathValue<T[K], Rest> : T extends Array<infer U> ? K extends `${number}` ? PathValue<U, Rest> : never : never : P extends keyof T ? T[P] : T extends Array<infer U> ? P extends `${number}` ? U : never : never;
77
+ export type PathValue<T, P extends string> = T extends unknown ? P extends `${infer K}.${infer Rest}` ? K extends keyof T ? PathValue<T[K], Rest> : T extends Array<infer U> ? K extends `${number}` ? PathValue<U, Rest> : never : never : P extends keyof T ? T[P] : T extends Array<infer U> ? P extends `${number}` ? U : never : never : never;
78
78
  /**
79
79
  * Single field error with type and message
80
80
  */
@@ -490,9 +490,15 @@ export interface UseFormReturn<TSchema extends ZodType> {
490
490
  resetField: <TPath extends Path<InferSchema<TSchema>>>(name: TPath, options?: ResetFieldOptions<PathValue<InferSchema<TSchema>, TPath>>) => void;
491
491
  /**
492
492
  * Watch field value(s) reactively
493
- * @param name - Field path or array of paths (optional - watches all if not provided)
493
+ * @overload Watch all form values
494
+ * @overload Watch single field value by path
495
+ * @overload Watch multiple field values by paths array
494
496
  */
495
- watch: <TPath extends Path<InferSchema<TSchema>>>(name?: TPath | TPath[]) => ComputedRef<unknown>;
497
+ watch: {
498
+ (): ComputedRef<InferSchema<TSchema>>;
499
+ <TPath extends Path<InferSchema<TSchema>>>(name: TPath): ComputedRef<PathValue<InferSchema<TSchema>, TPath>>;
500
+ <TPath extends Path<InferSchema<TSchema>>>(names: TPath[]): ComputedRef<Partial<InferSchema<TSchema>>>;
501
+ };
496
502
  /**
497
503
  * Manually trigger validation
498
504
  * @param name - Optional field path (validates all if not provided)
@@ -502,7 +508,7 @@ export interface UseFormReturn<TSchema extends ZodType> {
502
508
  * Clear errors for specified fields or all errors
503
509
  * @param name - Optional field path or array of paths
504
510
  */
505
- clearErrors: <TPath extends Path<InferSchema<TSchema>>>(name?: TPath | TPath[]) => void;
511
+ clearErrors: <TPath extends Path<InferSchema<TSchema>>>(name?: TPath | TPath[] | 'root' | `root.${string}`) => void;
506
512
  /**
507
513
  * Set an error for a specific field
508
514
  * @param name - Field path or root error
@@ -1,6 +1,6 @@
1
1
  import { ComputedRef } from 'vue';
2
2
  import { ZodType } from 'zod';
3
- import { UseFormReturn, Path, InferSchema } from './types';
3
+ import { UseFormReturn, Path, PathValue, InferSchema } from './types';
4
4
  /**
5
5
  * Options for useWatch composable
6
6
  */
@@ -37,4 +37,10 @@ export interface UseWatchOptions<TSchema extends ZodType, TPath extends Path<Inf
37
37
  * const status = useWatch({ name: 'status', defaultValue: 'pending' })
38
38
  * ```
39
39
  */
40
- export declare function useWatch<TSchema extends ZodType, TPath extends Path<InferSchema<TSchema>> = Path<InferSchema<TSchema>>>(options?: UseWatchOptions<TSchema, TPath>): ComputedRef<unknown>;
40
+ export declare function useWatch<TSchema extends ZodType>(options?: Omit<UseWatchOptions<TSchema, Path<InferSchema<TSchema>>>, 'name'>): ComputedRef<InferSchema<TSchema>>;
41
+ export declare function useWatch<TSchema extends ZodType, TPath extends Path<InferSchema<TSchema>>>(options: UseWatchOptions<TSchema, TPath> & {
42
+ name: TPath;
43
+ }): ComputedRef<PathValue<InferSchema<TSchema>, TPath>>;
44
+ export declare function useWatch<TSchema extends ZodType, TPath extends Path<InferSchema<TSchema>>>(options: UseWatchOptions<TSchema, TPath> & {
45
+ name: TPath[];
46
+ }): ComputedRef<Partial<InferSchema<TSchema>>>;
@@ -144,7 +144,7 @@ function createFormContext(options) {
144
144
  options
145
145
  };
146
146
  }
147
- function clearFieldErrors(errors, fieldPath) {
147
+ function clearFieldErrors$1(errors, fieldPath) {
148
148
  const newErrors = { ...errors };
149
149
  for (const key of Object.keys(newErrors)) if (key === fieldPath || key.startsWith(`${fieldPath}.`)) delete newErrors[key];
150
150
  return newErrors;
@@ -221,7 +221,7 @@ function createValidation(ctx) {
221
221
  ctx.errorDelayTimers.delete(fieldPath);
222
222
  }
223
223
  ctx.pendingErrors.delete(fieldPath);
224
- return clearFieldErrors(ctx.errors.value, fieldPath);
224
+ return clearFieldErrors$1(ctx.errors.value, fieldPath);
225
225
  }
226
226
  function clearAllPendingErrors() {
227
227
  for (const timer of ctx.errorDelayTimers.values()) clearTimeout(timer);
@@ -648,6 +648,45 @@ function createFieldArrayManager(ctx, validate, setFocus) {
648
648
  }
649
649
  return { fields };
650
650
  }
651
+ function syncUncontrolledInputs(fieldRefs, fieldOptions, formData) {
652
+ for (const [name, fieldRef] of Array.from(fieldRefs.entries())) {
653
+ const el = fieldRef.value;
654
+ if (el) {
655
+ if (!fieldOptions.get(name)?.controlled) set(formData, name, el.type === "checkbox" ? el.checked : el.value);
656
+ }
657
+ }
658
+ }
659
+ function updateDomElement(el, value) {
660
+ if (el.type === "checkbox") el.checked = value;
661
+ else el.value = value;
662
+ }
663
+ function markFieldDirty(dirtyFields, fieldName) {
664
+ dirtyFields.value = {
665
+ ...dirtyFields.value,
666
+ [fieldName]: true
667
+ };
668
+ }
669
+ function markFieldTouched(touchedFields, fieldName) {
670
+ touchedFields.value = {
671
+ ...touchedFields.value,
672
+ [fieldName]: true
673
+ };
674
+ }
675
+ function clearFieldDirty(dirtyFields, fieldName) {
676
+ const newDirty = { ...dirtyFields.value };
677
+ delete newDirty[fieldName];
678
+ dirtyFields.value = newDirty;
679
+ }
680
+ function clearFieldTouched(touchedFields, fieldName) {
681
+ const newTouched = { ...touchedFields.value };
682
+ delete newTouched[fieldName];
683
+ touchedFields.value = newTouched;
684
+ }
685
+ function clearFieldErrors(errors, fieldName) {
686
+ const newErrors = { ...errors.value };
687
+ for (const key of Object.keys(newErrors)) if (key === fieldName || key.startsWith(`${fieldName}.`)) delete newErrors[key];
688
+ errors.value = newErrors;
689
+ }
651
690
  function useForm(options) {
652
691
  const ctx = createFormContext(options);
653
692
  const { validate, clearAllPendingErrors } = createValidation(ctx);
@@ -693,15 +732,7 @@ function useForm(options) {
693
732
  ctx.submitCount.value++;
694
733
  ctx.isSubmitSuccessful.value = false;
695
734
  try {
696
- for (const [name, fieldRef] of ctx.fieldRefs.entries()) {
697
- const el = fieldRef.value;
698
- if (el) {
699
- if (!ctx.fieldOptions.get(name)?.controlled) {
700
- const value = el.type === "checkbox" ? el.checked : el.value;
701
- set(ctx.formData, name, value);
702
- }
703
- }
704
- }
735
+ syncUncontrolledInputs(ctx.fieldRefs, ctx.fieldOptions, ctx.formData);
705
736
  if (await validate()) {
706
737
  await onValid(ctx.formData);
707
738
  ctx.isSubmitSuccessful.value = true;
@@ -719,21 +750,11 @@ function useForm(options) {
719
750
  }
720
751
  function setValue(name, value, setValueOptions) {
721
752
  set(ctx.formData, name, value);
722
- if (setValueOptions?.shouldDirty !== false) ctx.dirtyFields.value = {
723
- ...ctx.dirtyFields.value,
724
- [name]: true
725
- };
726
- if (setValueOptions?.shouldTouch) ctx.touchedFields.value = {
727
- ...ctx.touchedFields.value,
728
- [name]: true
729
- };
753
+ if (setValueOptions?.shouldDirty !== false) markFieldDirty(ctx.dirtyFields, name);
754
+ if (setValueOptions?.shouldTouch) markFieldTouched(ctx.touchedFields, name);
730
755
  if (!ctx.fieldOptions.get(name)?.controlled) {
731
756
  const fieldRef = ctx.fieldRefs.get(name);
732
- if (fieldRef?.value) {
733
- const el = fieldRef.value;
734
- if (el.type === "checkbox") el.checked = value;
735
- else el.value = value;
736
- }
757
+ if (fieldRef?.value) updateDomElement(fieldRef.value, value);
737
758
  }
738
759
  if (setValueOptions?.shouldValidate) validate(name);
739
760
  }
@@ -757,7 +778,7 @@ function useForm(options) {
757
778
  if (!opts.keepIsSubmitting) ctx.isSubmitting.value = false;
758
779
  if (!opts.keepIsSubmitSuccessful) ctx.isSubmitSuccessful.value = false;
759
780
  ctx.fieldArrays.clear();
760
- for (const [name, fieldRef] of ctx.fieldRefs.entries()) {
781
+ for (const [name, fieldRef] of Array.from(ctx.fieldRefs.entries())) {
761
782
  const el = fieldRef.value;
762
783
  if (el) {
763
784
  const value = get(newValues, name);
@@ -780,30 +801,12 @@ function useForm(options) {
780
801
  else set(ctx.defaultValues, name, defaultValue);
781
802
  const clonedValue = defaultValue !== void 0 ? JSON.parse(JSON.stringify(defaultValue)) : void 0;
782
803
  set(ctx.formData, name, clonedValue);
783
- if (!opts.keepError) {
784
- const newErrors = { ...ctx.errors.value };
785
- for (const key of Object.keys(newErrors)) if (key === name || key.startsWith(`${name}.`)) delete newErrors[key];
786
- ctx.errors.value = newErrors;
787
- }
788
- if (!opts.keepDirty) {
789
- const newDirty = { ...ctx.dirtyFields.value };
790
- delete newDirty[name];
791
- ctx.dirtyFields.value = newDirty;
792
- }
793
- if (!opts.keepTouched) {
794
- const newTouched = { ...ctx.touchedFields.value };
795
- delete newTouched[name];
796
- ctx.touchedFields.value = newTouched;
797
- }
804
+ if (!opts.keepError) clearFieldErrors(ctx.errors, name);
805
+ if (!opts.keepDirty) clearFieldDirty(ctx.dirtyFields, name);
806
+ if (!opts.keepTouched) clearFieldTouched(ctx.touchedFields, name);
798
807
  if (!ctx.fieldOptions.get(name)?.controlled) {
799
808
  const fieldRef = ctx.fieldRefs.get(name);
800
- if (fieldRef?.value) {
801
- const el = fieldRef.value;
802
- if (clonedValue !== void 0) if (el.type === "checkbox") el.checked = clonedValue;
803
- else el.value = clonedValue;
804
- else if (el.type === "checkbox") el.checked = false;
805
- else el.value = "";
806
- }
809
+ if (fieldRef?.value) updateDomElement(fieldRef.value, clonedValue ?? (fieldRef.value.type === "checkbox" ? false : ""));
807
810
  }
808
811
  }
809
812
  function watch$1(name) {
@@ -823,9 +826,7 @@ function useForm(options) {
823
826
  return;
824
827
  }
825
828
  const fieldsToClean = Array.isArray(name) ? name : [name];
826
- const newErrors = { ...ctx.errors.value };
827
- for (const field of fieldsToClean) for (const key of Object.keys(newErrors)) if (key === field || key.startsWith(`${field}.`)) delete newErrors[key];
828
- ctx.errors.value = newErrors;
829
+ for (const field of fieldsToClean) clearFieldErrors(ctx.errors, field);
829
830
  }
830
831
  function setError(name, error) {
831
832
  const newErrors = { ...ctx.errors.value };
@@ -836,15 +837,7 @@ function useForm(options) {
836
837
  ctx.errors.value = newErrors;
837
838
  }
838
839
  function getValues(nameOrNames) {
839
- for (const [name, fieldRef] of ctx.fieldRefs.entries()) {
840
- const el = fieldRef.value;
841
- if (el) {
842
- if (!ctx.fieldOptions.get(name)?.controlled) {
843
- const value = el.type === "checkbox" ? el.checked : el.value;
844
- set(ctx.formData, name, value);
845
- }
846
- }
847
- }
840
+ syncUncontrolledInputs(ctx.fieldRefs, ctx.fieldOptions, ctx.formData);
848
841
  if (nameOrNames === void 0) return { ...ctx.formData };
849
842
  if (Array.isArray(nameOrNames)) {
850
843
  const result = {};
@@ -143,7 +143,7 @@ function createFormContext(options) {
143
143
  options
144
144
  };
145
145
  }
146
- function clearFieldErrors(errors, fieldPath) {
146
+ function clearFieldErrors$1(errors, fieldPath) {
147
147
  const newErrors = { ...errors };
148
148
  for (const key of Object.keys(newErrors)) if (key === fieldPath || key.startsWith(`${fieldPath}.`)) delete newErrors[key];
149
149
  return newErrors;
@@ -220,7 +220,7 @@ function createValidation(ctx) {
220
220
  ctx.errorDelayTimers.delete(fieldPath);
221
221
  }
222
222
  ctx.pendingErrors.delete(fieldPath);
223
- return clearFieldErrors(ctx.errors.value, fieldPath);
223
+ return clearFieldErrors$1(ctx.errors.value, fieldPath);
224
224
  }
225
225
  function clearAllPendingErrors() {
226
226
  for (const timer of ctx.errorDelayTimers.values()) clearTimeout(timer);
@@ -647,6 +647,45 @@ function createFieldArrayManager(ctx, validate, setFocus) {
647
647
  }
648
648
  return { fields };
649
649
  }
650
+ function syncUncontrolledInputs(fieldRefs, fieldOptions, formData) {
651
+ for (const [name, fieldRef] of Array.from(fieldRefs.entries())) {
652
+ const el = fieldRef.value;
653
+ if (el) {
654
+ if (!fieldOptions.get(name)?.controlled) set(formData, name, el.type === "checkbox" ? el.checked : el.value);
655
+ }
656
+ }
657
+ }
658
+ function updateDomElement(el, value) {
659
+ if (el.type === "checkbox") el.checked = value;
660
+ else el.value = value;
661
+ }
662
+ function markFieldDirty(dirtyFields, fieldName) {
663
+ dirtyFields.value = {
664
+ ...dirtyFields.value,
665
+ [fieldName]: true
666
+ };
667
+ }
668
+ function markFieldTouched(touchedFields, fieldName) {
669
+ touchedFields.value = {
670
+ ...touchedFields.value,
671
+ [fieldName]: true
672
+ };
673
+ }
674
+ function clearFieldDirty(dirtyFields, fieldName) {
675
+ const newDirty = { ...dirtyFields.value };
676
+ delete newDirty[fieldName];
677
+ dirtyFields.value = newDirty;
678
+ }
679
+ function clearFieldTouched(touchedFields, fieldName) {
680
+ const newTouched = { ...touchedFields.value };
681
+ delete newTouched[fieldName];
682
+ touchedFields.value = newTouched;
683
+ }
684
+ function clearFieldErrors(errors, fieldName) {
685
+ const newErrors = { ...errors.value };
686
+ for (const key of Object.keys(newErrors)) if (key === fieldName || key.startsWith(`${fieldName}.`)) delete newErrors[key];
687
+ errors.value = newErrors;
688
+ }
650
689
  function useForm(options) {
651
690
  const ctx = createFormContext(options);
652
691
  const { validate, clearAllPendingErrors } = createValidation(ctx);
@@ -692,15 +731,7 @@ function useForm(options) {
692
731
  ctx.submitCount.value++;
693
732
  ctx.isSubmitSuccessful.value = false;
694
733
  try {
695
- for (const [name, fieldRef] of ctx.fieldRefs.entries()) {
696
- const el = fieldRef.value;
697
- if (el) {
698
- if (!ctx.fieldOptions.get(name)?.controlled) {
699
- const value = el.type === "checkbox" ? el.checked : el.value;
700
- set(ctx.formData, name, value);
701
- }
702
- }
703
- }
734
+ syncUncontrolledInputs(ctx.fieldRefs, ctx.fieldOptions, ctx.formData);
704
735
  if (await validate()) {
705
736
  await onValid(ctx.formData);
706
737
  ctx.isSubmitSuccessful.value = true;
@@ -718,21 +749,11 @@ function useForm(options) {
718
749
  }
719
750
  function setValue(name, value, setValueOptions) {
720
751
  set(ctx.formData, name, value);
721
- if (setValueOptions?.shouldDirty !== false) ctx.dirtyFields.value = {
722
- ...ctx.dirtyFields.value,
723
- [name]: true
724
- };
725
- if (setValueOptions?.shouldTouch) ctx.touchedFields.value = {
726
- ...ctx.touchedFields.value,
727
- [name]: true
728
- };
752
+ if (setValueOptions?.shouldDirty !== false) markFieldDirty(ctx.dirtyFields, name);
753
+ if (setValueOptions?.shouldTouch) markFieldTouched(ctx.touchedFields, name);
729
754
  if (!ctx.fieldOptions.get(name)?.controlled) {
730
755
  const fieldRef = ctx.fieldRefs.get(name);
731
- if (fieldRef?.value) {
732
- const el = fieldRef.value;
733
- if (el.type === "checkbox") el.checked = value;
734
- else el.value = value;
735
- }
756
+ if (fieldRef?.value) updateDomElement(fieldRef.value, value);
736
757
  }
737
758
  if (setValueOptions?.shouldValidate) validate(name);
738
759
  }
@@ -756,7 +777,7 @@ function useForm(options) {
756
777
  if (!opts.keepIsSubmitting) ctx.isSubmitting.value = false;
757
778
  if (!opts.keepIsSubmitSuccessful) ctx.isSubmitSuccessful.value = false;
758
779
  ctx.fieldArrays.clear();
759
- for (const [name, fieldRef] of ctx.fieldRefs.entries()) {
780
+ for (const [name, fieldRef] of Array.from(ctx.fieldRefs.entries())) {
760
781
  const el = fieldRef.value;
761
782
  if (el) {
762
783
  const value = get(newValues, name);
@@ -779,30 +800,12 @@ function useForm(options) {
779
800
  else set(ctx.defaultValues, name, defaultValue);
780
801
  const clonedValue = defaultValue !== void 0 ? JSON.parse(JSON.stringify(defaultValue)) : void 0;
781
802
  set(ctx.formData, name, clonedValue);
782
- if (!opts.keepError) {
783
- const newErrors = { ...ctx.errors.value };
784
- for (const key of Object.keys(newErrors)) if (key === name || key.startsWith(`${name}.`)) delete newErrors[key];
785
- ctx.errors.value = newErrors;
786
- }
787
- if (!opts.keepDirty) {
788
- const newDirty = { ...ctx.dirtyFields.value };
789
- delete newDirty[name];
790
- ctx.dirtyFields.value = newDirty;
791
- }
792
- if (!opts.keepTouched) {
793
- const newTouched = { ...ctx.touchedFields.value };
794
- delete newTouched[name];
795
- ctx.touchedFields.value = newTouched;
796
- }
803
+ if (!opts.keepError) clearFieldErrors(ctx.errors, name);
804
+ if (!opts.keepDirty) clearFieldDirty(ctx.dirtyFields, name);
805
+ if (!opts.keepTouched) clearFieldTouched(ctx.touchedFields, name);
797
806
  if (!ctx.fieldOptions.get(name)?.controlled) {
798
807
  const fieldRef = ctx.fieldRefs.get(name);
799
- if (fieldRef?.value) {
800
- const el = fieldRef.value;
801
- if (clonedValue !== void 0) if (el.type === "checkbox") el.checked = clonedValue;
802
- else el.value = clonedValue;
803
- else if (el.type === "checkbox") el.checked = false;
804
- else el.value = "";
805
- }
808
+ if (fieldRef?.value) updateDomElement(fieldRef.value, clonedValue ?? (fieldRef.value.type === "checkbox" ? false : ""));
806
809
  }
807
810
  }
808
811
  function watch$1(name) {
@@ -822,9 +825,7 @@ function useForm(options) {
822
825
  return;
823
826
  }
824
827
  const fieldsToClean = Array.isArray(name) ? name : [name];
825
- const newErrors = { ...ctx.errors.value };
826
- for (const field of fieldsToClean) for (const key of Object.keys(newErrors)) if (key === field || key.startsWith(`${field}.`)) delete newErrors[key];
827
- ctx.errors.value = newErrors;
828
+ for (const field of fieldsToClean) clearFieldErrors(ctx.errors, field);
828
829
  }
829
830
  function setError(name, error) {
830
831
  const newErrors = { ...ctx.errors.value };
@@ -835,15 +836,7 @@ function useForm(options) {
835
836
  ctx.errors.value = newErrors;
836
837
  }
837
838
  function getValues(nameOrNames) {
838
- for (const [name, fieldRef] of ctx.fieldRefs.entries()) {
839
- const el = fieldRef.value;
840
- if (el) {
841
- if (!ctx.fieldOptions.get(name)?.controlled) {
842
- const value = el.type === "checkbox" ? el.checked : el.value;
843
- set(ctx.formData, name, value);
844
- }
845
- }
846
- }
839
+ syncUncontrolledInputs(ctx.fieldRefs, ctx.fieldOptions, ctx.formData);
847
840
  if (nameOrNames === void 0) return { ...ctx.formData };
848
841
  if (Array.isArray(nameOrNames)) {
849
842
  const result = {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vuehookform/core",
3
- "version": "0.2.8",
3
+ "version": "0.2.10",
4
4
  "description": "TypeScript-first form library for Vue 3, inspired by React Hook Form. Form-level state management with Zod validation.",
5
5
  "type": "module",
6
6
  "main": "./dist/vuehookform.cjs",
@@ -23,14 +23,15 @@
23
23
  "scripts": {
24
24
  "dev": "vite",
25
25
  "build": "run-p type-check \"build-only {@}\" --",
26
- "build:lib": "vite build --config vite.config.lib.ts",
26
+ "build:lib": "run-p type-check build-lib-only",
27
+ "build-lib-only": "vite build --config vite.config.lib.ts",
27
28
  "preview": "vite preview",
28
29
  "build-only": "vite build",
29
30
  "type-check": "vue-tsc --build",
30
31
  "lint:oxlint": "oxlint . --fix -D correctness --ignore-path .gitignore",
31
32
  "lint:eslint": "eslint . --fix --cache",
32
33
  "lint": "run-s lint:*",
33
- "format": "prettier --write --experimental-cli src/",
34
+ "format": "prettier --write --experimental-cli src/ tests/",
34
35
  "test": "vitest",
35
36
  "test:run": "vitest run",
36
37
  "test:coverage": "vitest run --coverage",
@@ -67,6 +68,7 @@
67
68
  "zod": "^3.0.0 || ^4.0.0"
68
69
  },
69
70
  "devDependencies": {
71
+ "@tailwindcss/vite": "^4.1.18",
70
72
  "@prettier/plugin-oxc": "^0.0.5",
71
73
  "@tsconfig/node24": "^24.0.3",
72
74
  "@types/node": "^24.10.1",
@@ -75,7 +77,6 @@
75
77
  "@vue/eslint-config-prettier": "^10.2.0",
76
78
  "@vue/eslint-config-typescript": "^14.6.0",
77
79
  "@vue/test-utils": "^2.4.6",
78
- "@vue/tsconfig": "^0.8.1",
79
80
  "eslint": "^9.39.1",
80
81
  "eslint-plugin-oxlint": "~1.29.0",
81
82
  "eslint-plugin-vue": "~10.5.1",
@@ -93,10 +94,7 @@
93
94
  "vue": "^3.5.25",
94
95
  "vue-router": "^4.6.3",
95
96
  "vue-tsc": "^3.1.5",
96
- "zod": "^4.2.1"
97
- },
98
- "dependencies": {
99
- "@tailwindcss/vite": "^4.1.18",
97
+ "zod": "^4.2.1",
100
98
  "material-icons": "^1.13.14",
101
99
  "material-symbols": "^0.40.2",
102
100
  "tailwindcss": "^4.1.18"