@vuehookform/core 0.4.3 → 0.4.5
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.
- package/README.md +8 -4
- package/dist/index.d.ts +2 -2
- package/dist/utils/modeChecks.d.ts +2 -2
- package/dist/utils/paths.d.ts +8 -0
- package/dist/vuehookform.cjs +8 -9
- package/dist/vuehookform.js +9 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -42,12 +42,12 @@ const onSubmit = (data) => {
|
|
|
42
42
|
<template>
|
|
43
43
|
<form @submit="handleSubmit(onSubmit)">
|
|
44
44
|
<input v-bind="register('email')" type="email" />
|
|
45
|
-
<span v-if="formState.errors.email">{{ formState.errors.email }}</span>
|
|
45
|
+
<span v-if="formState.value.errors.email">{{ formState.value.errors.email }}</span>
|
|
46
46
|
|
|
47
47
|
<input v-bind="register('password')" type="password" />
|
|
48
|
-
<span v-if="formState.errors.password">{{ formState.errors.password }}</span>
|
|
48
|
+
<span v-if="formState.value.errors.password">{{ formState.value.errors.password }}</span>
|
|
49
49
|
|
|
50
|
-
<button type="submit" :disabled="formState.isSubmitting">Submit</button>
|
|
50
|
+
<button type="submit" :disabled="formState.value.isSubmitting">Submit</button>
|
|
51
51
|
</form>
|
|
52
52
|
</template>
|
|
53
53
|
```
|
|
@@ -160,11 +160,15 @@ const emailError = computed(() => formState.value.errors.email)
|
|
|
160
160
|
|
|
161
161
|
<!-- ✅ Option 3: Use useController for reusable components -->
|
|
162
162
|
<script setup>
|
|
163
|
+
import { useForm, useController, type Control } from '@vuehookform/core'
|
|
164
|
+
|
|
165
|
+
// control comes from useForm (pass it as a prop to child components)
|
|
166
|
+
const { control } = useForm({ schema })
|
|
163
167
|
const { fieldState } = useController({ name: 'email', control })
|
|
164
168
|
// fieldState is a ComputedRef that updates automatically
|
|
165
169
|
</script>
|
|
166
170
|
<template>
|
|
167
|
-
<span v-if="fieldState.error">{{ fieldState.error }}</span>
|
|
171
|
+
<span v-if="fieldState.value.error">{{ fieldState.value.error }}</span>
|
|
168
172
|
</template>
|
|
169
173
|
```
|
|
170
174
|
|
package/dist/index.d.ts
CHANGED
|
@@ -20,5 +20,5 @@ export { useWatch, type UseWatchOptions } from './useWatch';
|
|
|
20
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
|
-
export type { UseFormOptions, UseFormReturn, 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,
|
|
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';
|
|
@@ -5,11 +5,11 @@ import { ValidationMode } from '../types';
|
|
|
5
5
|
*
|
|
6
6
|
* @param mode - The form's validation mode
|
|
7
7
|
* @param isTouched - Whether the field has been touched
|
|
8
|
+
* @param hasSubmitted - Whether the form has been submitted at least once (for reValidateMode)
|
|
8
9
|
* @param reValidateMode - The form's reValidateMode (used after first submit)
|
|
9
|
-
* @param hasSubmitted - Whether the form has been submitted at least once (optional, for reValidateMode)
|
|
10
10
|
* @returns true if validation should be triggered
|
|
11
11
|
*/
|
|
12
|
-
export declare function shouldValidateOnChange(mode: ValidationMode, isTouched: boolean,
|
|
12
|
+
export declare function shouldValidateOnChange(mode: ValidationMode, isTouched: boolean, hasSubmitted?: boolean, reValidateMode?: ValidationMode): boolean;
|
|
13
13
|
/**
|
|
14
14
|
* Determines if validation should occur on blur event.
|
|
15
15
|
* Used by useController and register for consistent mode handling.
|
package/dist/utils/paths.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get cached path segments or parse and cache them.
|
|
3
|
+
* Uses simple LRU eviction (delete oldest when full).
|
|
4
|
+
*
|
|
5
|
+
* Exported for use by other utilities that need path parsing
|
|
6
|
+
* with caching benefits (devWarnings, schemaExtract).
|
|
7
|
+
*/
|
|
8
|
+
export declare function getPathSegments(path: string): string[];
|
|
1
9
|
/**
|
|
2
10
|
* Clear the path segment cache.
|
|
3
11
|
* Call this between SSR requests to prevent memory accumulation,
|
package/dist/vuehookform.cjs
CHANGED
|
@@ -28,7 +28,7 @@ function get(obj, path) {
|
|
|
28
28
|
return result;
|
|
29
29
|
}
|
|
30
30
|
function set(obj, path, value) {
|
|
31
|
-
if (!path) return;
|
|
31
|
+
if (!path || obj === null || obj === void 0) return;
|
|
32
32
|
const keys = getPathSegments(path).slice();
|
|
33
33
|
const UNSAFE_KEYS = [
|
|
34
34
|
"__proto__",
|
|
@@ -60,7 +60,7 @@ function set(obj, path, value) {
|
|
|
60
60
|
current[lastKey] = value;
|
|
61
61
|
}
|
|
62
62
|
function unset(obj, path) {
|
|
63
|
-
if (!path) return;
|
|
63
|
+
if (!path || obj === null || obj === void 0) return;
|
|
64
64
|
const keys = getPathSegments(path).slice();
|
|
65
65
|
const lastKey = keys.pop();
|
|
66
66
|
let current = obj;
|
|
@@ -118,7 +118,7 @@ function validatePathSyntax(path) {
|
|
|
118
118
|
return null;
|
|
119
119
|
}
|
|
120
120
|
function traverseSchemaPath(schema, path) {
|
|
121
|
-
const segments = path
|
|
121
|
+
const segments = getPathSegments(path);
|
|
122
122
|
let currentSchema = schema;
|
|
123
123
|
for (let i = 0; i < segments.length; i++) {
|
|
124
124
|
const segment = segments[i];
|
|
@@ -449,7 +449,7 @@ function hasRootEffects(schema) {
|
|
|
449
449
|
return hasChecks(schema);
|
|
450
450
|
}
|
|
451
451
|
function extractSubSchema(schema, path) {
|
|
452
|
-
const segments = path
|
|
452
|
+
const segments = getPathSegments(path);
|
|
453
453
|
let currentSchema = schema;
|
|
454
454
|
let hasEffects = false;
|
|
455
455
|
for (const segment of segments) {
|
|
@@ -800,7 +800,7 @@ var VALID_MODES = [
|
|
|
800
800
|
function validateMode(mode, paramName) {
|
|
801
801
|
if (__DEV__ && !VALID_MODES.includes(mode)) warnOnce(`Invalid ${paramName}: "${mode}". Expected one of: ${VALID_MODES.join(", ")}`, `invalid-mode-${mode}`);
|
|
802
802
|
}
|
|
803
|
-
function shouldValidateOnChange(mode, isTouched,
|
|
803
|
+
function shouldValidateOnChange(mode, isTouched, hasSubmitted, reValidateMode) {
|
|
804
804
|
if (__DEV__) {
|
|
805
805
|
validateMode(mode, "validation mode");
|
|
806
806
|
if (reValidateMode) validateMode(reValidateMode, "reValidateMode");
|
|
@@ -863,7 +863,7 @@ function createFieldRegistration(ctx, validate) {
|
|
|
863
863
|
set(ctx.formData, name, value);
|
|
864
864
|
updateFieldDirtyState(ctx.dirtyFields, ctx.defaultValues, ctx.defaultValueHashes, name, value);
|
|
865
865
|
const fieldOpts = ctx.fieldOptions.get(name);
|
|
866
|
-
if (shouldValidateOnChange(ctx.options.mode ?? "onSubmit", ctx.touchedFields.value[name] === true, ctx.
|
|
866
|
+
if (shouldValidateOnChange(ctx.options.mode ?? "onSubmit", ctx.touchedFields.value[name] === true, ctx.submitCount.value > 0, ctx.options.reValidateMode)) {
|
|
867
867
|
const validationDebounceMs = ctx.options.validationDebounce || 0;
|
|
868
868
|
if (validationDebounceMs > 0) {
|
|
869
869
|
const existingTimer = ctx.schemaValidationTimers.get(name);
|
|
@@ -1088,7 +1088,7 @@ function createFieldArrayManager(ctx, validate, setFocus) {
|
|
|
1088
1088
|
const validateIfNeeded = () => {
|
|
1089
1089
|
const isTouched = ctx.touchedFields.value[name] === true;
|
|
1090
1090
|
const hasSubmitted = ctx.submitCount.value > 0;
|
|
1091
|
-
if (shouldValidateOnChange(ctx.options.mode ?? "onSubmit", isTouched, ctx.options.reValidateMode
|
|
1091
|
+
if (shouldValidateOnChange(ctx.options.mode ?? "onSubmit", isTouched, hasSubmitted, ctx.options.reValidateMode)) validate(name);
|
|
1092
1092
|
};
|
|
1093
1093
|
const ensureSync = () => {
|
|
1094
1094
|
const currentValues = get(ctx.formData, name) || [];
|
|
@@ -1790,7 +1790,7 @@ function useController(options) {
|
|
|
1790
1790
|
const hasSubmitted = form.formState.value.submitCount > 0;
|
|
1791
1791
|
const mode = form.options.mode ?? "onSubmit";
|
|
1792
1792
|
const reValidateMode = form.options.reValidateMode;
|
|
1793
|
-
const shouldValidate = shouldValidateOnChange(mode, isTouched,
|
|
1793
|
+
const shouldValidate = shouldValidateOnChange(mode, isTouched, hasSubmitted, reValidateMode);
|
|
1794
1794
|
form.setValue(name, newValue, { shouldValidate });
|
|
1795
1795
|
};
|
|
1796
1796
|
const onBlur = () => {
|
|
@@ -1844,7 +1844,6 @@ function isFieldError(error) {
|
|
|
1844
1844
|
}
|
|
1845
1845
|
exports.FormContextKey = FormContextKey;
|
|
1846
1846
|
exports.clearPathCache = clearPathCache;
|
|
1847
|
-
exports.generateId = generateId;
|
|
1848
1847
|
exports.get = get;
|
|
1849
1848
|
exports.isFieldError = isFieldError;
|
|
1850
1849
|
exports.provideForm = provideForm;
|
package/dist/vuehookform.js
CHANGED
|
@@ -27,7 +27,7 @@ function get(obj, path) {
|
|
|
27
27
|
return result;
|
|
28
28
|
}
|
|
29
29
|
function set(obj, path, value) {
|
|
30
|
-
if (!path) return;
|
|
30
|
+
if (!path || obj === null || obj === void 0) return;
|
|
31
31
|
const keys = getPathSegments(path).slice();
|
|
32
32
|
const UNSAFE_KEYS = [
|
|
33
33
|
"__proto__",
|
|
@@ -59,7 +59,7 @@ function set(obj, path, value) {
|
|
|
59
59
|
current[lastKey] = value;
|
|
60
60
|
}
|
|
61
61
|
function unset(obj, path) {
|
|
62
|
-
if (!path) return;
|
|
62
|
+
if (!path || obj === null || obj === void 0) return;
|
|
63
63
|
const keys = getPathSegments(path).slice();
|
|
64
64
|
const lastKey = keys.pop();
|
|
65
65
|
let current = obj;
|
|
@@ -116,7 +116,7 @@ function validatePathSyntax(path) {
|
|
|
116
116
|
return null;
|
|
117
117
|
}
|
|
118
118
|
function traverseSchemaPath(schema, path) {
|
|
119
|
-
const segments = path
|
|
119
|
+
const segments = getPathSegments(path);
|
|
120
120
|
let currentSchema = schema;
|
|
121
121
|
for (let i = 0; i < segments.length; i++) {
|
|
122
122
|
const segment = segments[i];
|
|
@@ -447,7 +447,7 @@ function hasRootEffects(schema) {
|
|
|
447
447
|
return hasChecks(schema);
|
|
448
448
|
}
|
|
449
449
|
function extractSubSchema(schema, path) {
|
|
450
|
-
const segments = path
|
|
450
|
+
const segments = getPathSegments(path);
|
|
451
451
|
let currentSchema = schema;
|
|
452
452
|
let hasEffects = false;
|
|
453
453
|
for (const segment of segments) {
|
|
@@ -798,7 +798,7 @@ var VALID_MODES = [
|
|
|
798
798
|
function validateMode(mode, paramName) {
|
|
799
799
|
if (__DEV__ && !VALID_MODES.includes(mode)) warnOnce(`Invalid ${paramName}: "${mode}". Expected one of: ${VALID_MODES.join(", ")}`, `invalid-mode-${mode}`);
|
|
800
800
|
}
|
|
801
|
-
function shouldValidateOnChange(mode, isTouched,
|
|
801
|
+
function shouldValidateOnChange(mode, isTouched, hasSubmitted, reValidateMode) {
|
|
802
802
|
if (__DEV__) {
|
|
803
803
|
validateMode(mode, "validation mode");
|
|
804
804
|
if (reValidateMode) validateMode(reValidateMode, "reValidateMode");
|
|
@@ -861,7 +861,7 @@ function createFieldRegistration(ctx, validate) {
|
|
|
861
861
|
set(ctx.formData, name, value);
|
|
862
862
|
updateFieldDirtyState(ctx.dirtyFields, ctx.defaultValues, ctx.defaultValueHashes, name, value);
|
|
863
863
|
const fieldOpts = ctx.fieldOptions.get(name);
|
|
864
|
-
if (shouldValidateOnChange(ctx.options.mode ?? "onSubmit", ctx.touchedFields.value[name] === true, ctx.
|
|
864
|
+
if (shouldValidateOnChange(ctx.options.mode ?? "onSubmit", ctx.touchedFields.value[name] === true, ctx.submitCount.value > 0, ctx.options.reValidateMode)) {
|
|
865
865
|
const validationDebounceMs = ctx.options.validationDebounce || 0;
|
|
866
866
|
if (validationDebounceMs > 0) {
|
|
867
867
|
const existingTimer = ctx.schemaValidationTimers.get(name);
|
|
@@ -1086,7 +1086,7 @@ function createFieldArrayManager(ctx, validate, setFocus) {
|
|
|
1086
1086
|
const validateIfNeeded = () => {
|
|
1087
1087
|
const isTouched = ctx.touchedFields.value[name] === true;
|
|
1088
1088
|
const hasSubmitted = ctx.submitCount.value > 0;
|
|
1089
|
-
if (shouldValidateOnChange(ctx.options.mode ?? "onSubmit", isTouched, ctx.options.reValidateMode
|
|
1089
|
+
if (shouldValidateOnChange(ctx.options.mode ?? "onSubmit", isTouched, hasSubmitted, ctx.options.reValidateMode)) validate(name);
|
|
1090
1090
|
};
|
|
1091
1091
|
const ensureSync = () => {
|
|
1092
1092
|
const currentValues = get(ctx.formData, name) || [];
|
|
@@ -1788,7 +1788,7 @@ function useController(options) {
|
|
|
1788
1788
|
const hasSubmitted = form.formState.value.submitCount > 0;
|
|
1789
1789
|
const mode = form.options.mode ?? "onSubmit";
|
|
1790
1790
|
const reValidateMode = form.options.reValidateMode;
|
|
1791
|
-
const shouldValidate = shouldValidateOnChange(mode, isTouched,
|
|
1791
|
+
const shouldValidate = shouldValidateOnChange(mode, isTouched, hasSubmitted, reValidateMode);
|
|
1792
1792
|
form.setValue(name, newValue, { shouldValidate });
|
|
1793
1793
|
};
|
|
1794
1794
|
const onBlur = () => {
|
|
@@ -1840,4 +1840,4 @@ function useFormState(options = {}) {
|
|
|
1840
1840
|
function isFieldError(error) {
|
|
1841
1841
|
return typeof error === "object" && error !== null && "type" in error && "message" in error && typeof error.type === "string" && typeof error.message === "string";
|
|
1842
1842
|
}
|
|
1843
|
-
export { FormContextKey, clearPathCache,
|
|
1843
|
+
export { FormContextKey, clearPathCache, get, isFieldError, provideForm, set, unset, useController, useForm, useFormContext, useFormState, useWatch };
|
package/package.json
CHANGED