@volverjs/form-vue 0.0.3 → 0.0.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 CHANGED
@@ -54,6 +54,7 @@ const form = createForm({
54
54
  schema
55
55
  // lazyLoad: boolean - default false
56
56
  // updateThrottle: number - default 500
57
+ // continuosValidation: boolean - default false
57
58
  // sideEffects?: (data: any) => void
58
59
  })
59
60
 
@@ -131,6 +132,31 @@ The throttle can be changed with the `updateThrottle` option.
131
132
  </template>
132
133
  ```
133
134
 
135
+ The `continuosValidation` can be passed through options or with VvForm prop.
136
+ With this field the validation doesn't stop and continue also after a validaton success.
137
+
138
+ ```vue
139
+ <script lang="ts" setup>
140
+ import { ref } from 'vue'
141
+
142
+ const { VvForm, VvFormField } = useForm(MyZodSchema, {
143
+ lazyLoad: true
144
+ // continuosValidation: true
145
+ })
146
+
147
+ const formData = ref({
148
+ name: '',
149
+ surname: ''
150
+ })
151
+ </script>
152
+
153
+ <template>
154
+ <VvForm v-model="formData" :continuosValidation="true">
155
+ <!-- form fields -->
156
+ </VvForm>
157
+ </template>
158
+ ```
159
+
134
160
  ### VvFormWrapper
135
161
 
136
162
  `VvFormWrapper` gives you the validation status of a part of your form.
@@ -250,6 +276,86 @@ Or a custom component.
250
276
  </template>
251
277
  ```
252
278
 
279
+ ## Nested VvFormField
280
+
281
+ In some use cases can be usefull nest `VvFormField`.
282
+ For example let's assume:
283
+
284
+ - a shopping list that is a field of our model (ex: ToDo list)
285
+ - the sum of all products of the shopping list cannot be 0
286
+ - we don't know all the products a priori
287
+
288
+ So our ToDo model and shopping list are structured like:
289
+
290
+ ```javascript
291
+ const toDo = {
292
+ shoppingList: {
293
+ bread: 0,
294
+ milk: 0,
295
+ tomato: 0,
296
+ potato: 0,
297
+ ...
298
+ }
299
+ }
300
+ ```
301
+
302
+ Our Zod schema can be:
303
+
304
+ ```typescript
305
+ const toDoSchema = z.object({
306
+ shoppingList: z
307
+ .object({})
308
+ .default({})
309
+ .superRefine((value, ctx) => {
310
+ const shoppingList = value as Record<string, number>
311
+ if (
312
+ Object.keys(value).length &&
313
+ !Object.keys(value).find((key) => shoppingList[key] > 0)
314
+ ) {
315
+ ctx.addIssue({
316
+ code: z.ZodIssueCode.custom,
317
+ message: i18n.global.t('atLeastOneProduct')
318
+ })
319
+ }
320
+ })
321
+ })
322
+ ```
323
+
324
+ And the Vue component:
325
+
326
+ ```vue
327
+ <script setup lang="ts">
328
+ const { VvForm, VvFormField } = useForm(toDoSchema, {
329
+ lazyLoad: true,
330
+ continuosValidation: true
331
+ })
332
+
333
+ // shopping list data, const or async
334
+ const shoppingList = {
335
+ bread: 0,
336
+ milk: 0,
337
+ tomato: 0,
338
+ potato: 0
339
+ }
340
+ </script>
341
+
342
+ <template>
343
+ <VvForm>
344
+ <VvFormField v-slot="{ invalid, invalidLabel }" name="shoppingList">
345
+ <VvFormField
346
+ v-for="key in Object.keys(shoppingList)"
347
+ :key="key"
348
+ :name="`shoppingList.${key}`"
349
+ :label="$t(key)"
350
+ />
351
+ <small v-if="invalid" class="input-counter__hint">{{
352
+ invalidLabel[0]
353
+ }}</small>
354
+ </VvFormField>
355
+ </VvForm>
356
+ </template>
357
+ ```
358
+
253
359
  ## Composable
254
360
 
255
361
  `useForm` can be used to create a form programmatically inside a Vue 3 Component.
@@ -268,6 +374,7 @@ The default settings are inherited from the plugin (if it was defined).
268
374
  const { VvForm, VvFormWrapper, VvFormField } = useForm(schema, {
269
375
  // lazyLoad: boolean - default false
270
376
  // updateThrottle: number - default 500
377
+ // continuosValidation: true - default false
271
378
  // sideEffects?: (formData: any) => void
272
379
  })
273
380
  </script>
@@ -297,12 +404,80 @@ const schema = z.object({
297
404
  const { VvForm, VvFormWrapper, VvFormField } = formFactory(schema, {
298
405
  // lazyLoad: boolean - default false
299
406
  // updateThrottle: number - default 500
407
+ // continuosValidation: true - default false
300
408
  // sideEffects?: (data: any) => void
301
409
  })
302
410
 
303
411
  export default { VvForm, VvFormWrapper, VvFormField }
304
412
  ```
305
413
 
414
+ ## Default Object by Zod Object Schema
415
+
416
+ `defaultObjectBySchema` creates an object by a Zod Object Schema.
417
+ It can be useful to create a default object for a form. The default object is created by the default values of the schema and can be merged with an other object passed as parameter.
418
+
419
+ ```ts
420
+ import { z } from 'zod'
421
+ import { defaultObjectBySchema } from '@volverjs/form-vue'
422
+
423
+ const schema = z.object({
424
+ name: z.string().default('John'),
425
+ surname: z.string().default('Doe')
426
+ })
427
+
428
+ const defaultObject = defaultObjectBySchema(schema)
429
+ // defaultObject = { name: 'John', surname: 'Doe' }
430
+
431
+ const defaultObject = defaultObjectBySchema(schema, { name: 'Jane' })
432
+ // defaultObject = { name: 'Jane', surname: 'Doe' }
433
+ ```
434
+
435
+ `defaultObjectBySchema` can be used with nested objects.
436
+
437
+ ```ts
438
+ import { z } from 'zod'
439
+ import { defaultObjectBySchema } from '@volverjs/form-vue'
440
+
441
+ const schema = z.object({
442
+ name: z.string().default('John'),
443
+ surname: z.string().default('Doe'),
444
+ address: z.object({
445
+ street: z.string().default('Main Street'),
446
+ number: z.number().default(1)
447
+ })
448
+ })
449
+
450
+ const defaultObject = defaultObjectBySchema(schema)
451
+ // defaultObject = { name: 'John', surname: 'Doe', address: { street: 'Main Street', number: 1 } }
452
+ ```
453
+
454
+ Other Zod methods are also supported: [`z.nullable()`](https://github.com/colinhacks/zod#nullable), [`z.coerce`](https://github.com/colinhacks/zod#coercion-for-primitives) and [`z.passthrough()`](https://github.com/colinhacks/zod#passthrough).
455
+
456
+ ```ts
457
+ import { z } from 'zod'
458
+ import { defaultObjectBySchema } from '@volverjs/form-vue'
459
+
460
+ const schema = z
461
+ .object({
462
+ name: z.string().default('John'),
463
+ surname: z.string().default('Doe'),
464
+ address: z.object({
465
+ street: z.string().default('Main Street'),
466
+ number: z.number().default(1)
467
+ }),
468
+ age: z.number().nullable().default(null),
469
+ height: z.number().coerce().default(1.8),
470
+ weight: z.number().default(80)
471
+ })
472
+ .passthrough()
473
+
474
+ const defaultObject = defaultObjectBySchema(schema, {
475
+ height: '1.9',
476
+ email: 'john.doe@test.com'
477
+ })
478
+ // defaultObject = { name: 'John', surname: 'Doe', address: { street: 'Main Street', number: 1 }, age: null, height: 1.9, weight: 80, email: 'john.doe@test.com' }
479
+ ```
480
+
306
481
  ## License
307
482
 
308
483
  [MIT](http://opensource.org/licenses/MIT)
package/dist/VvForm.d.ts CHANGED
@@ -13,6 +13,10 @@ export declare const defineForm: (schema: AnyZodObject | ZodEffects<AnyZodObject
13
13
  type: ObjectConstructor;
14
14
  default: () => {};
15
15
  };
16
+ continuosValidation: {
17
+ type: BooleanConstructor;
18
+ default: boolean;
19
+ };
16
20
  }, {
17
21
  submit: () => boolean;
18
22
  }, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("valid" | "invalid" | "submit" | "update:modelValue")[], "valid" | "invalid" | "submit" | "update:modelValue", import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
@@ -20,6 +24,10 @@ export declare const defineForm: (schema: AnyZodObject | ZodEffects<AnyZodObject
20
24
  type: ObjectConstructor;
21
25
  default: () => {};
22
26
  };
27
+ continuosValidation: {
28
+ type: BooleanConstructor;
29
+ default: boolean;
30
+ };
23
31
  }>> & {
24
32
  onValid?: ((...args: any[]) => any) | undefined;
25
33
  onInvalid?: ((...args: any[]) => any) | undefined;
@@ -27,4 +35,5 @@ export declare const defineForm: (schema: AnyZodObject | ZodEffects<AnyZodObject
27
35
  "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
28
36
  }, {
29
37
  modelValue: Record<string, any>;
38
+ continuosValidation: boolean;
30
39
  }>;
@@ -10,7 +10,7 @@ export declare const defineFormWrapper: (formProvideKey: InjectionKey<InjectedFo
10
10
  default: undefined;
11
11
  };
12
12
  }, {
13
- formProvided: InjectedFormData<Recrod<string | number, unknown>> | undefined;
13
+ formProvided: InjectedFormData | undefined;
14
14
  invalid: import("vue").ComputedRef<boolean>;
15
15
  fields: Ref<Set<string>>;
16
16
  errors: Ref<Map<string, Record<string, {
package/dist/index.d.ts CHANGED
@@ -10,6 +10,10 @@ export declare const formFactory: (schema: AnyZodObject | ZodEffects<AnyZodObjec
10
10
  type: ObjectConstructor;
11
11
  default: () => {};
12
12
  };
13
+ continuosValidation: {
14
+ type: BooleanConstructor;
15
+ default: boolean;
16
+ };
13
17
  }, {
14
18
  submit: () => boolean;
15
19
  }, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("valid" | "invalid" | "submit" | "update:modelValue")[], "valid" | "invalid" | "submit" | "update:modelValue", import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
@@ -17,6 +21,10 @@ export declare const formFactory: (schema: AnyZodObject | ZodEffects<AnyZodObjec
17
21
  type: ObjectConstructor;
18
22
  default: () => {};
19
23
  };
24
+ continuosValidation: {
25
+ type: BooleanConstructor;
26
+ default: boolean;
27
+ };
20
28
  }>> & {
21
29
  onValid?: ((...args: any[]) => any) | undefined;
22
30
  onInvalid?: ((...args: any[]) => any) | undefined;
@@ -24,6 +32,7 @@ export declare const formFactory: (schema: AnyZodObject | ZodEffects<AnyZodObjec
24
32
  "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
25
33
  }, {
26
34
  modelValue: Record<string, any>;
35
+ continuosValidation: boolean;
27
36
  }>;
28
37
  VvFormWrapper: import("vue").DefineComponent<{
29
38
  name: {
@@ -35,7 +44,7 @@ export declare const formFactory: (schema: AnyZodObject | ZodEffects<AnyZodObjec
35
44
  default: undefined;
36
45
  };
37
46
  }, {
38
- formProvided: InjectedFormData<Recrod<string | number, unknown>> | undefined;
47
+ formProvided: InjectedFormData | undefined;
39
48
  invalid: import("vue").ComputedRef<boolean>;
40
49
  fields: import("vue").Ref<Set<string>>;
41
50
  errors: import("vue").Ref<Map<string, Record<string, {
@@ -56,8 +65,8 @@ export declare const formFactory: (schema: AnyZodObject | ZodEffects<AnyZodObjec
56
65
  }, {
57
66
  tag: string;
58
67
  }>;
59
- VvFormField: import("vue").Component<any, any, any, import("vue").ComputedOptions, import("vue").MethodOptions>;
60
- formInjectionKey: InjectionKey<InjectedFormData<Recrod<string | number, unknown>>>;
68
+ VvFormField: import("vue").Component;
69
+ formInjectionKey: InjectionKey<InjectedFormData>;
61
70
  formWrapperInjectionKey: InjectionKey<InjectedFormWrapperData>;
62
71
  formFieldInjectionKey: InjectionKey<InjectedFormFieldData>;
63
72
  };
@@ -69,6 +78,10 @@ export declare const useForm: (schema: AnyZodObject | ZodEffects<AnyZodObject>,
69
78
  type: ObjectConstructor;
70
79
  default: () => {};
71
80
  };
81
+ continuosValidation: {
82
+ type: BooleanConstructor;
83
+ default: boolean;
84
+ };
72
85
  }, {
73
86
  submit: () => boolean;
74
87
  }, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("valid" | "invalid" | "submit" | "update:modelValue")[], "valid" | "invalid" | "submit" | "update:modelValue", import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
@@ -76,6 +89,10 @@ export declare const useForm: (schema: AnyZodObject | ZodEffects<AnyZodObject>,
76
89
  type: ObjectConstructor;
77
90
  default: () => {};
78
91
  };
92
+ continuosValidation: {
93
+ type: BooleanConstructor;
94
+ default: boolean;
95
+ };
79
96
  }>> & {
80
97
  onValid?: ((...args: any[]) => any) | undefined;
81
98
  onInvalid?: ((...args: any[]) => any) | undefined;
@@ -83,6 +100,7 @@ export declare const useForm: (schema: AnyZodObject | ZodEffects<AnyZodObject>,
83
100
  "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
84
101
  }, {
85
102
  modelValue: Record<string, any>;
103
+ continuosValidation: boolean;
86
104
  }>;
87
105
  VvFormWrapper: import("vue").DefineComponent<{
88
106
  name: {
@@ -94,7 +112,7 @@ export declare const useForm: (schema: AnyZodObject | ZodEffects<AnyZodObject>,
94
112
  default: undefined;
95
113
  };
96
114
  }, {
97
- formProvided: InjectedFormData<Recrod<string | number, unknown>> | undefined;
115
+ formProvided: InjectedFormData | undefined;
98
116
  invalid: import("vue").ComputedRef<boolean>;
99
117
  fields: import("vue").Ref<Set<string>>;
100
118
  errors: import("vue").Ref<Map<string, Record<string, {
@@ -115,8 +133,8 @@ export declare const useForm: (schema: AnyZodObject | ZodEffects<AnyZodObject>,
115
133
  }, {
116
134
  tag: string;
117
135
  }>;
118
- VvFormField: import("vue").Component<any, any, any, import("vue").ComputedOptions, import("vue").MethodOptions>;
119
- formInjectionKey: InjectionKey<InjectedFormData<Recrod<string | number, unknown>>>;
136
+ VvFormField: import("vue").Component;
137
+ formInjectionKey: InjectionKey<InjectedFormData>;
120
138
  formWrapperInjectionKey: InjectionKey<InjectedFormWrapperData>;
121
139
  formFieldInjectionKey: InjectionKey<InjectedFormFieldData>;
122
140
  };
package/dist/index.es.js CHANGED
@@ -1,77 +1,77 @@
1
- import { defineComponent as w, computed as h, onMounted as Z, inject as S, toRefs as G, watch as V, provide as $, readonly as M, resolveComponent as b, defineAsyncComponent as q, h as O, ref as x, isProxy as Y, toRaw as H, withModifiers as Q } from "vue";
2
- import { watchThrottled as X } from "@vueuse/core";
3
- import { ZodEffects as P, ZodDefault as T, ZodObject as F } from "zod";
4
- function A(e) {
1
+ import { defineComponent as $, computed as V, onMounted as J, inject as k, toRefs as D, watch as y, provide as E, readonly as S, resolveComponent as h, defineAsyncComponent as z, h as x, ref as g, isProxy as U, toRaw as q, withModifiers as H } from "vue";
2
+ import { watchThrottled as Q } from "@vueuse/core";
3
+ import { ZodEffects as R, ZodObject as L, ZodDefault as X, ZodNullable as Y, ZodSchema as P } from "zod";
4
+ function w(e) {
5
5
  return Array.isArray(e);
6
6
  }
7
- function ee(e) {
7
+ function F(e) {
8
8
  return typeof e < "u";
9
9
  }
10
10
  function N(e) {
11
11
  return e === null;
12
12
  }
13
- function L(e) {
13
+ function _(e) {
14
14
  return typeof e == "object";
15
15
  }
16
- function D(e) {
16
+ function W(e) {
17
17
  return typeof e == "string";
18
18
  }
19
- function E(e) {
19
+ function O(e) {
20
20
  return typeof e > "u";
21
21
  }
22
- const re = /^[0-9]+$/, te = ["__proto__", "prototype", "constructor"];
23
- function _(e, r, t) {
24
- const a = ee(t) ? t : void 0;
25
- if (!L(e) || !D(r))
26
- return a;
27
- const n = W(r);
28
- if (n.length !== 0) {
29
- for (const u of n) {
30
- if (u === "*")
22
+ const T = /^[0-9]+$/, ee = ["__proto__", "prototype", "constructor"];
23
+ function A(e, n, o) {
24
+ const s = F(o) ? o : void 0;
25
+ if (!_(e) || !W(n))
26
+ return s;
27
+ const t = K(n);
28
+ if (t.length !== 0) {
29
+ for (const r of t) {
30
+ if (r === "*")
31
31
  continue;
32
- const i = function(s) {
33
- return s.map((f) => E(f) || N(f) ? f : A(f) ? i(f) : f[u]);
32
+ const i = function(l) {
33
+ return l.map((c) => O(c) || N(c) ? c : w(c) ? i(c) : c[r]);
34
34
  };
35
- if (A(e) && !re.test(u) ? e = i(e) : e = e[u], E(e) || N(e))
35
+ if (w(e) && !T.test(r) ? e = i(e) : e = e[r], O(e) || N(e))
36
36
  break;
37
37
  }
38
- return E(e) ? a : e;
38
+ return O(e) ? s : e;
39
39
  }
40
40
  }
41
- function U(e, r, t) {
42
- if (!L(e) || !D(r))
41
+ function B(e, n, o) {
42
+ if (!_(e) || !W(n))
43
43
  return;
44
- const a = W(r);
45
- if (a.length === 0)
44
+ const s = K(n);
45
+ if (s.length === 0)
46
46
  return;
47
- const n = a.length;
48
- for (let u = 0; u < n; u++) {
49
- const i = a[u];
50
- if (u === n - 1) {
51
- e[i] = t;
47
+ const t = s.length;
48
+ for (let r = 0; r < t; r++) {
49
+ const i = s[r];
50
+ if (r === t - 1) {
51
+ e[i] = o;
52
52
  return;
53
53
  }
54
- if (i === "*" && A(e)) {
55
- const s = a.slice(u + 1).join(".");
56
- for (const f of e)
57
- U(f, s, t);
54
+ if (i === "*" && w(e)) {
55
+ const l = s.slice(r + 1).join(".");
56
+ for (const c of e)
57
+ B(c, l, o);
58
58
  return;
59
59
  }
60
- E(e[i]) && (e[i] = {}), e = e[i];
60
+ O(e[i]) && (e[i] = {}), e = e[i];
61
61
  }
62
62
  }
63
- function W(e) {
64
- const r = e.split(/[.]|(?:\[(\d|\*)\])/).filter((t) => !!t);
65
- return r.some((t) => te.indexOf(t) !== -1) ? [] : r;
63
+ function K(e) {
64
+ const n = e.split(/[.]|(?:\[(\d|\*)\])/).filter((o) => !!o);
65
+ return n.some((o) => ee.indexOf(o) !== -1) ? [] : n;
66
66
  }
67
- var l = /* @__PURE__ */ ((e) => (e.text = "text", e.number = "number", e.email = "email", e.password = "password", e.tel = "tel", e.url = "url", e.search = "search", e.date = "date", e.time = "time", e.datetimeLocal = "datetimeLocal", e.month = "month", e.week = "week", e.color = "color", e.select = "select", e.checkbox = "checkbox", e.radio = "radio", e.textarea = "textarea", e.radioGroup = "radioGroup", e.checkboxGroup = "checkboxGroup", e.combobox = "combobox", e.custom = "custom", e))(l || {});
68
- const ne = (e, r, t, a = {}) => w({
67
+ var u = /* @__PURE__ */ ((e) => (e.text = "text", e.number = "number", e.email = "email", e.password = "password", e.tel = "tel", e.url = "url", e.search = "search", e.date = "date", e.time = "time", e.datetimeLocal = "datetimeLocal", e.month = "month", e.week = "week", e.color = "color", e.select = "select", e.checkbox = "checkbox", e.radio = "radio", e.textarea = "textarea", e.radioGroup = "radioGroup", e.checkboxGroup = "checkboxGroup", e.combobox = "combobox", e.custom = "custom", e))(u || {});
68
+ const te = (e, n, o, s = {}) => $({
69
69
  name: "FieldComponent",
70
70
  props: {
71
71
  type: {
72
72
  type: String,
73
- validator: (n) => Object.values(l).includes(n),
74
- default: l.custom
73
+ validator: (t) => Object.values(u).includes(t),
74
+ default: u.custom
75
75
  },
76
76
  is: {
77
77
  type: [Object, String],
@@ -96,284 +96,234 @@ const ne = (e, r, t, a = {}) => w({
96
96
  },
97
97
  emits: ["invalid", "valid", "update:formData", "update:modelValue"],
98
98
  expose: ["invalid", "invalidLabel", "errors"],
99
- setup(n, { slots: u, emit: i }) {
100
- const s = h({
99
+ setup(t, { slots: r, emit: i }) {
100
+ const l = V({
101
101
  get() {
102
- if (o != null && o.modelValue)
103
- return _(
104
- Object(o.modelValue.value),
105
- String(n.name)
102
+ if (a != null && a.modelValue)
103
+ return A(
104
+ Object(a.modelValue.value),
105
+ String(t.name)
106
106
  );
107
107
  },
108
- set(c) {
109
- o != null && o.modelValue && (U(
110
- Object(o.modelValue.value),
111
- String(n.name),
112
- c
108
+ set(f) {
109
+ a != null && a.modelValue && (B(
110
+ Object(a.modelValue.value),
111
+ String(t.name),
112
+ f
113
113
  ), i("update:modelValue", {
114
- newValue: s.value,
115
- formData: o == null ? void 0 : o.modelValue
114
+ newValue: l.value,
115
+ formData: a == null ? void 0 : a.modelValue
116
116
  }));
117
117
  }
118
118
  });
119
- Z(() => {
120
- s.value === void 0 && n.defaultValue !== void 0 && (s.value = n.defaultValue);
119
+ J(() => {
120
+ l.value === void 0 && t.defaultValue !== void 0 && (l.value = t.defaultValue);
121
121
  });
122
- const f = S(r, void 0);
123
- f && f.fields.value.add(n.name);
124
- const o = S(e), { props: d, name: m } = G(n), v = h(() => {
125
- if (o != null && o.errors.value)
126
- return _(o.errors.value, String(n.name));
127
- }), y = h(() => {
128
- var c;
129
- return (c = v.value) == null ? void 0 : c._errors;
130
- }), p = h(() => v.value !== void 0);
131
- V(p, () => {
132
- p.value ? (i("invalid", y.value), f && f.errors.value.set(n.name, {
133
- _errors: y.value
134
- })) : (i("valid", s.value), f && f.errors.value.delete(
135
- n.name
122
+ const c = k(n, void 0);
123
+ c && c.fields.value.add(t.name);
124
+ const a = k(e), { props: m, name: v } = D(t), d = V(() => {
125
+ if (a != null && a.errors.value)
126
+ return A(a.errors.value, String(t.name));
127
+ }), p = V(() => {
128
+ var f;
129
+ return (f = d.value) == null ? void 0 : f._errors;
130
+ }), b = V(() => d.value !== void 0);
131
+ y(b, () => {
132
+ b.value ? (i("invalid", p.value), c && c.errors.value.set(t.name, {
133
+ _errors: p.value
134
+ })) : (i("valid", l.value), c && c.errors.value.delete(
135
+ t.name
136
136
  ));
137
- }), V(
138
- () => o == null ? void 0 : o.modelValue,
137
+ }), y(
138
+ () => a == null ? void 0 : a.modelValue,
139
139
  () => {
140
- i("update:formData", o == null ? void 0 : o.modelValue);
140
+ i("update:formData", a == null ? void 0 : a.modelValue);
141
141
  },
142
142
  { deep: !0 }
143
143
  );
144
- const k = (c) => {
145
- s.value = c;
146
- }, I = h(() => typeof d.value == "function" ? d.value(o == null ? void 0 : o.modelValue) : d.value), R = h(() => ({
147
- ...I.value,
148
- name: I.value.name ?? n.name,
149
- invalid: p.value,
150
- valid: n.showValid ? Boolean(!p.value && s.value) : void 0,
151
- type: ((c) => {
144
+ const G = (f) => {
145
+ l.value = f;
146
+ }, C = V(() => typeof m.value == "function" ? m.value(a == null ? void 0 : a.modelValue) : m.value), j = V(() => ({
147
+ ...C.value,
148
+ name: C.value.name ?? t.name,
149
+ invalid: b.value,
150
+ valid: t.showValid ? !!(!b.value && l.value) : void 0,
151
+ type: ((f) => {
152
152
  if ([
153
- l.text,
154
- l.number,
155
- l.email,
156
- l.password,
157
- l.tel,
158
- l.url,
159
- l.search,
160
- l.date,
161
- l.time,
162
- l.datetimeLocal,
163
- l.month,
164
- l.week,
165
- l.color
166
- ].includes(c))
167
- return c;
168
- })(n.type),
169
- invalidLabel: y.value,
170
- modelValue: s.value,
171
- errors: n.is ? v.value : void 0,
172
- "onUpdate:modelValue": k
153
+ u.text,
154
+ u.number,
155
+ u.email,
156
+ u.password,
157
+ u.tel,
158
+ u.url,
159
+ u.search,
160
+ u.date,
161
+ u.time,
162
+ u.datetimeLocal,
163
+ u.month,
164
+ u.week,
165
+ u.color
166
+ ].includes(f))
167
+ return f;
168
+ })(t.type),
169
+ invalidLabel: p.value,
170
+ modelValue: l.value,
171
+ errors: t.is ? d.value : void 0,
172
+ "onUpdate:modelValue": G
173
173
  }));
174
- return $(t, {
175
- name: M(m),
176
- errors: M(v)
177
- }), { component: h(() => {
178
- if (n.type === l.custom)
174
+ return E(o, {
175
+ name: S(v),
176
+ errors: S(d)
177
+ }), { component: V(() => {
178
+ if (t.type === u.custom)
179
179
  return {
180
180
  render() {
181
- var c;
182
- return ((c = u.default) == null ? void 0 : c.call(u, {
183
- modelValue: s.value,
184
- onUpdate: k,
185
- invalid: p.value,
186
- invalidLabel: y.value,
187
- formData: o == null ? void 0 : o.modelValue.value,
188
- formErrors: o == null ? void 0 : o.errors.value,
189
- errors: v.value
190
- })) ?? u.defalut;
181
+ var f;
182
+ return ((f = r.default) == null ? void 0 : f.call(r, {
183
+ modelValue: l.value,
184
+ onUpdate: G,
185
+ invalid: b.value,
186
+ invalidLabel: p.value,
187
+ formData: a == null ? void 0 : a.modelValue.value,
188
+ formErrors: a == null ? void 0 : a.errors.value,
189
+ errors: d.value
190
+ })) ?? r.defalut;
191
191
  }
192
192
  };
193
- if (!a.lazyLoad) {
194
- let c;
195
- switch (n.type) {
196
- case l.select:
197
- c = b("VvSelect");
193
+ if (!s.lazyLoad) {
194
+ let f;
195
+ switch (t.type) {
196
+ case u.select:
197
+ f = h("VvSelect");
198
198
  break;
199
- case l.checkbox:
200
- c = b("VvCheckbox");
199
+ case u.checkbox:
200
+ f = h("VvCheckbox");
201
201
  break;
202
- case l.radio:
203
- c = b("VvRadio");
202
+ case u.radio:
203
+ f = h("VvRadio");
204
204
  break;
205
- case l.textarea:
206
- c = b("VvTextarea");
205
+ case u.textarea:
206
+ f = h("VvTextarea");
207
207
  break;
208
- case l.radioGroup:
209
- c = b("VvRadioGroup");
208
+ case u.radioGroup:
209
+ f = h("VvRadioGroup");
210
210
  break;
211
- case l.checkboxGroup:
212
- c = b("VvCheckboxGroup");
211
+ case u.checkboxGroup:
212
+ f = h("VvCheckboxGroup");
213
213
  break;
214
- case l.combobox:
215
- c = b("VvCombobox");
214
+ case u.combobox:
215
+ f = h("VvCombobox");
216
216
  break;
217
217
  default:
218
- c = b("VvInputText");
218
+ f = h("VvInputText");
219
219
  }
220
- if (typeof c != "string")
221
- return c;
220
+ if (typeof f != "string")
221
+ return f;
222
222
  console.warn(
223
- `[form-vue warn]: ${c} not found, the component will be loaded asynchronously. To avoid this warning, please set "lazyLoad" option.`
223
+ `[form-vue warn]: ${f} not found, the component will be loaded asynchronously. To avoid this warning, please set "lazyLoad" option.`
224
224
  );
225
225
  }
226
- return q(async () => {
227
- switch (a.sideEffects && await Promise.resolve(a.sideEffects(n.type)), n.type) {
228
- case l.textarea:
226
+ return z(async () => {
227
+ switch (s.sideEffects && await Promise.resolve(s.sideEffects(t.type)), t.type) {
228
+ case u.textarea:
229
229
  return import("@volverjs/ui-vue/vv-textarea");
230
- case l.radio:
230
+ case u.radio:
231
231
  return import("@volverjs/ui-vue/vv-radio");
232
- case l.radioGroup:
232
+ case u.radioGroup:
233
233
  return import("@volverjs/ui-vue/vv-radio-group");
234
- case l.checkbox:
234
+ case u.checkbox:
235
235
  return import("@volverjs/ui-vue/vv-checkbox");
236
- case l.checkboxGroup:
236
+ case u.checkboxGroup:
237
237
  return import("@volverjs/ui-vue/vv-checkbox-group");
238
- case l.combobox:
238
+ case u.combobox:
239
239
  return import("@volverjs/ui-vue/vv-combobox");
240
240
  }
241
241
  return import("@volverjs/ui-vue/vv-input-text");
242
242
  });
243
- }), hasProps: R, invalid: p };
243
+ }), hasProps: j, invalid: b };
244
244
  },
245
245
  render() {
246
- return this.is ? O(this.is, this.hasProps, this.$slots) : this.type === l.custom ? O(this.component, null, this.$slots) : O(this.component, this.hasProps, this.$slots);
247
- }
248
- });
249
- var ae = function(r) {
250
- return ue(r) && !oe(r);
251
- };
252
- function ue(e) {
253
- return !!e && typeof e == "object";
254
- }
255
- function oe(e) {
256
- var r = Object.prototype.toString.call(e);
257
- return r === "[object RegExp]" || r === "[object Date]" || se(e);
258
- }
259
- var le = typeof Symbol == "function" && Symbol.for, ie = le ? Symbol.for("react.element") : 60103;
260
- function se(e) {
261
- return e.$$typeof === ie;
262
- }
263
- function ce(e) {
264
- return Array.isArray(e) ? [] : {};
265
- }
266
- function j(e, r) {
267
- return r.clone !== !1 && r.isMergeableObject(e) ? g(ce(e), e, r) : e;
268
- }
269
- function fe(e, r, t) {
270
- return e.concat(r).map(function(a) {
271
- return j(a, t);
272
- });
273
- }
274
- function de(e, r) {
275
- if (!r.customMerge)
276
- return g;
277
- var t = r.customMerge(e);
278
- return typeof t == "function" ? t : g;
279
- }
280
- function me(e) {
281
- return Object.getOwnPropertySymbols ? Object.getOwnPropertySymbols(e).filter(function(r) {
282
- return Object.propertyIsEnumerable.call(e, r);
283
- }) : [];
284
- }
285
- function C(e) {
286
- return Object.keys(e).concat(me(e));
287
- }
288
- function B(e, r) {
289
- try {
290
- return r in e;
291
- } catch {
292
- return !1;
246
+ return this.is ? x(this.is, this.hasProps, this.$slots) : this.type === u.custom ? x(this.component, null, this.$slots) : x(this.component, this.hasProps, this.$slots);
293
247
  }
294
- }
295
- function ve(e, r) {
296
- return B(e, r) && !(Object.hasOwnProperty.call(e, r) && Object.propertyIsEnumerable.call(e, r));
297
- }
298
- function be(e, r, t) {
299
- var a = {};
300
- return t.isMergeableObject(e) && C(e).forEach(function(n) {
301
- a[n] = j(e[n], t);
302
- }), C(r).forEach(function(n) {
303
- ve(e, n) || (B(e, n) && t.isMergeableObject(r[n]) ? a[n] = de(n, t)(e[n], r[n], t) : a[n] = j(r[n], t));
304
- }), a;
305
- }
306
- function g(e, r, t) {
307
- t = t || {}, t.arrayMerge = t.arrayMerge || fe, t.isMergeableObject = t.isMergeableObject || ae, t.cloneUnlessOtherwiseSpecified = j;
308
- var a = Array.isArray(r), n = Array.isArray(e), u = a === n;
309
- return u ? a ? t.arrayMerge(e, r, t) : be(e, r, t) : j(r, t);
310
- }
311
- g.all = function(r, t) {
312
- if (!Array.isArray(r))
313
- throw new Error("first argument should be an array");
314
- return r.reduce(function(a, n) {
315
- return g(a, n, t);
316
- }, {});
317
- };
318
- var he = g, ye = he;
319
- const J = (e, r = {}) => {
320
- const t = e instanceof P ? e.innerType().shape : e.shape;
321
- return ye(
322
- Object.fromEntries(
323
- Object.entries(t).map(([a, n]) => n instanceof T ? [a, n._def.defaultValue()] : n instanceof F ? [a, J(n)] : [a, void 0])
324
- ),
325
- r
326
- );
327
- }, pe = (e, r, t) => w({
248
+ }), M = (e, n = {}) => {
249
+ const o = e instanceof R ? e.innerType().shape : e.shape;
250
+ return {
251
+ ...(e instanceof L ? e._def.unknownKeys === "passthrough" : !1) ? n : {},
252
+ ...Object.fromEntries(
253
+ Object.entries(o).map(([t, r]) => {
254
+ const i = n[t];
255
+ let l;
256
+ if (r instanceof X && (l = r._def.defaultValue()), i === null && r instanceof Y)
257
+ return [t, i];
258
+ if (r instanceof P) {
259
+ const c = r.safeParse(n[t]);
260
+ if (c.success)
261
+ return [t, c.data ?? l];
262
+ }
263
+ return r instanceof L ? [
264
+ t,
265
+ M(
266
+ r,
267
+ i && typeof i == "object" ? i : {}
268
+ )
269
+ ] : [t, l];
270
+ })
271
+ )
272
+ };
273
+ }, re = (e, n, o) => $({
328
274
  name: "FormComponent",
329
275
  props: {
330
276
  modelValue: {
331
277
  type: Object,
332
278
  default: () => ({})
279
+ },
280
+ continuosValidation: {
281
+ type: Boolean,
282
+ default: !1
333
283
  }
334
284
  },
335
285
  emits: ["invalid", "valid", "submit", "update:modelValue"],
336
286
  expose: ["submit", "errors", "status"],
337
- setup(a, { emit: n }) {
338
- const u = x(
339
- J(e, a.modelValue)
340
- );
341
- V(
342
- () => a.modelValue,
343
- (d) => {
344
- if (d) {
345
- const m = Y(d) ? H(d) : d;
346
- u.value = typeof (m == null ? void 0 : m.clone) == "function" ? m.clone() : JSON.parse(JSON.stringify(m));
287
+ setup(s, { emit: t }) {
288
+ const r = g(
289
+ M(e, s.modelValue)
290
+ ), i = (o == null ? void 0 : o.continuosValidation) || s.continuosValidation;
291
+ y(
292
+ () => s.modelValue,
293
+ (v) => {
294
+ if (v) {
295
+ const d = U(v) ? q(v) : v;
296
+ r.value = typeof (d == null ? void 0 : d.clone) == "function" ? d.clone() : JSON.parse(JSON.stringify(d));
347
297
  }
348
298
  },
349
299
  { deep: !0 }
350
- ), X(
351
- u,
352
- (d) => {
353
- (i.value || t != null && t.continuosValidation) && f(), (!d || !a.modelValue || JSON.stringify(d) !== JSON.stringify(a.modelValue)) && n("update:modelValue", d);
300
+ ), Q(
301
+ r,
302
+ (v) => {
303
+ (l.value || i) && a(), (!v || !s.modelValue || JSON.stringify(v) !== JSON.stringify(s.modelValue)) && t("update:modelValue", v);
354
304
  },
355
- { deep: !0, throttle: (t == null ? void 0 : t.updateThrottle) ?? 500 }
305
+ { deep: !0, throttle: (o == null ? void 0 : o.updateThrottle) ?? 500 }
356
306
  );
357
- const i = x(), s = x(), f = (d = u.value) => {
358
- const m = e.safeParse(d);
359
- return m.success ? (i.value = void 0, s.value = "valid", u.value = m.data, n("valid", m.data), !0) : (i.value = m.error.format(), s.value = "invalid", n("invalid", i.value), !1);
360
- }, o = () => f() ? (n("submit", u.value), !0) : !1;
361
- return $(r, {
362
- modelValue: u,
363
- submit: o,
364
- errors: M(i)
365
- }), { submit: o };
307
+ const l = g(), c = g(), a = (v = r.value) => {
308
+ const d = e.safeParse(v);
309
+ return d.success ? (l.value = void 0, c.value = "valid", r.value = d.data, t("valid", d.data), !0) : (l.value = d.error.format(), c.value = "invalid", t("invalid", l.value), !1);
310
+ }, m = () => a() ? (t("submit", r.value), !0) : !1;
311
+ return E(n, {
312
+ modelValue: r,
313
+ submit: m,
314
+ errors: S(l)
315
+ }), { submit: m };
366
316
  },
367
317
  render() {
368
- return O(
318
+ return x(
369
319
  "form",
370
320
  {
371
- onSubmit: Q(this.submit, ["prevent"])
321
+ onSubmit: H(this.submit, ["prevent"])
372
322
  },
373
323
  this.$slots
374
324
  );
375
325
  }
376
- }), Ve = (e, r) => w({
326
+ }), ae = (e, n) => $({
377
327
  name: "WrapperComponent",
378
328
  props: {
379
329
  name: {
@@ -387,90 +337,90 @@ const J = (e, r = {}) => {
387
337
  },
388
338
  emits: ["invalid", "valid"],
389
339
  expose: ["fields", "invalid"],
390
- setup(t, { emit: a }) {
391
- const n = S(e), u = S(r, void 0), i = x(/* @__PURE__ */ new Set()), s = x(/* @__PURE__ */ new Map()), { name: f } = G(t);
392
- $(r, {
393
- name: M(f),
394
- errors: s,
340
+ setup(o, { emit: s }) {
341
+ const t = k(e), r = k(n, void 0), i = g(/* @__PURE__ */ new Set()), l = g(/* @__PURE__ */ new Map()), { name: c } = D(o);
342
+ E(n, {
343
+ name: S(c),
344
+ errors: l,
395
345
  fields: i
396
- }), V(
346
+ }), y(
397
347
  i,
398
- (d) => {
399
- u != null && u.fields && d.forEach((m) => {
400
- u == null || u.fields.value.add(m);
348
+ (m) => {
349
+ r != null && r.fields && m.forEach((v) => {
350
+ r == null || r.fields.value.add(v);
401
351
  });
402
352
  },
403
353
  { deep: !0 }
404
- ), V(
405
- () => new Map(s.value),
406
- (d, m) => {
407
- u != null && u.errors && (Array.from(m.keys()).forEach((v) => {
408
- u.errors.value.delete(v);
409
- }), Array.from(d.keys()).forEach((v) => {
410
- const y = d.get(v);
411
- y && u.errors.value.set(v, y);
354
+ ), y(
355
+ () => new Map(l.value),
356
+ (m, v) => {
357
+ r != null && r.errors && (Array.from(v.keys()).forEach((d) => {
358
+ r.errors.value.delete(d);
359
+ }), Array.from(m.keys()).forEach((d) => {
360
+ const p = m.get(d);
361
+ p && r.errors.value.set(d, p);
412
362
  }));
413
363
  },
414
364
  { deep: !0 }
415
365
  );
416
- const o = h(() => n != null && n.errors.value ? s.value.size > 0 : !1);
417
- return V(o, () => {
418
- o.value ? a("invalid") : a("valid");
419
- }), { formProvided: n, invalid: o, fields: i, errors: s };
366
+ const a = V(() => t != null && t.errors.value ? l.value.size > 0 : !1);
367
+ return y(a, () => {
368
+ a.value ? s("invalid") : s("valid");
369
+ }), { formProvided: t, invalid: a, fields: i, errors: l };
420
370
  },
421
371
  render() {
422
- var t, a, n, u, i, s, f, o;
423
- return this.tag ? O(
372
+ var o, s, t, r, i, l, c, a;
373
+ return this.tag ? x(
424
374
  this.tag,
425
375
  null,
426
- ((u = (n = this.$slots).default) == null ? void 0 : u.call(n, {
376
+ ((r = (t = this.$slots).default) == null ? void 0 : r.call(t, {
427
377
  invalid: this.invalid,
428
- formData: (t = this.formProvided) == null ? void 0 : t.modelValue,
429
- errors: (a = this.formProvided) == null ? void 0 : a.errors,
378
+ formData: (o = this.formProvided) == null ? void 0 : o.modelValue,
379
+ errors: (s = this.formProvided) == null ? void 0 : s.errors,
430
380
  fieldsErrors: this.errors
431
381
  })) ?? this.$slots.defalut
432
- ) : ((o = (f = this.$slots).default) == null ? void 0 : o.call(f, {
382
+ ) : ((a = (c = this.$slots).default) == null ? void 0 : a.call(c, {
433
383
  invalid: this.invalid,
434
384
  formData: (i = this.formProvided) == null ? void 0 : i.modelValue,
435
- errors: (s = this.formProvided) == null ? void 0 : s.errors,
385
+ errors: (l = this.formProvided) == null ? void 0 : l.errors,
436
386
  fieldsErrors: this.errors
437
387
  })) ?? this.$slots.defalut;
438
388
  }
439
- }), K = (e, r = {}) => {
440
- const t = Symbol(), a = Symbol(), n = Symbol(), u = pe(e, t, r), i = Ve(
441
- t,
442
- a
443
- ), s = ne(
389
+ }), I = (e, n = {}) => {
390
+ const o = Symbol(), s = Symbol(), t = Symbol(), r = re(e, o, n), i = ae(
391
+ o,
392
+ s
393
+ ), l = te(
394
+ o,
395
+ s,
444
396
  t,
445
- a,
446
- n,
447
- r
397
+ n
448
398
  );
449
399
  return {
450
- VvForm: u,
400
+ VvForm: r,
451
401
  VvFormWrapper: i,
452
- VvFormField: s,
453
- formInjectionKey: t,
454
- formWrapperInjectionKey: a,
455
- formFieldInjectionKey: n
402
+ VvFormField: l,
403
+ formInjectionKey: o,
404
+ formWrapperInjectionKey: s,
405
+ formFieldInjectionKey: t
456
406
  };
457
- }, z = Symbol(), je = (e) => {
458
- let r = {};
459
- return e.schema && (r = K(e.schema, e)), {
460
- ...r,
461
- install(t, { global: a = !1 } = {}) {
462
- t.provide(z, e), a && (t.config.globalProperties.$vvForm = e, r != null && r.VvForm && t.component("VvForm", r.VvForm), r != null && r.VvFormWrapper && t.component("VvFormWrapper", r.VvFormWrapper), r != null && r.VvFormField && t.component("VvFormField", r.VvFormField));
407
+ }, Z = Symbol(), se = (e) => {
408
+ let n = {};
409
+ return e.schema && (n = I(e.schema, e)), {
410
+ ...n,
411
+ install(o, { global: s = !1 } = {}) {
412
+ o.provide(Z, e), s && (o.config.globalProperties.$vvForm = e, n != null && n.VvForm && o.component("VvForm", n.VvForm), n != null && n.VvFormWrapper && o.component("VvFormWrapper", n.VvFormWrapper), n != null && n.VvFormField && o.component("VvFormField", n.VvFormField));
463
413
  }
464
414
  };
465
- }, Ee = (e, r = {}) => {
466
- const t = { ...S(z, {}), ...r };
467
- return K(e, t);
415
+ }, ie = (e, n = {}) => {
416
+ const o = { ...k(Z, {}), ...n };
417
+ return I(e, o);
468
418
  };
469
419
  export {
470
- l as FormFieldType,
471
- je as createForm,
472
- J as defaultObjectBySchema,
473
- K as formFactory,
474
- z as pluginInjectionKey,
475
- Ee as useForm
420
+ u as FormFieldType,
421
+ se as createForm,
422
+ M as defaultObjectBySchema,
423
+ I as formFactory,
424
+ Z as pluginInjectionKey,
425
+ ie as useForm
476
426
  };
package/dist/index.umd.js CHANGED
@@ -1 +1 @@
1
- (function(b,a){typeof exports=="object"&&typeof module<"u"?a(exports,require("vue"),require("@vueuse/core"),require("zod")):typeof define=="function"&&define.amd?define(["exports","vue","@vueuse/core","zod"],a):(b=typeof globalThis<"u"?globalThis:b||self,a(b["@volverjs/form-vue"]={},b.Vue,b.VueUseCore,b.zod))})(this,function(b,a,D,S){"use strict";function j(e){return Array.isArray(e)}function U(e){return typeof e<"u"}function E(e){return e===null}function A(e){return typeof e=="object"}function C(e){return typeof e=="string"}function O(e){return typeof e>"u"}const W=/^[0-9]+$/,B=["__proto__","prototype","constructor"];function $(e,r,t){const o=U(t)?t:void 0;if(!A(e)||!C(r))return o;const n=I(r);if(n.length!==0){for(const l of n){if(l==="*")continue;const c=function(u){return u.map(d=>O(d)||E(d)?d:j(d)?c(d):d[l])};if(j(e)&&!W.test(l)?e=c(e):e=e[l],O(e)||E(e))break}return O(e)?o:e}}function k(e,r,t){if(!A(e)||!C(r))return;const o=I(r);if(o.length===0)return;const n=o.length;for(let l=0;l<n;l++){const c=o[l];if(l===n-1){e[c]=t;return}if(c==="*"&&j(e)){const u=o.slice(l+1).join(".");for(const d of e)k(d,u,t);return}O(e[c])&&(e[c]={}),e=e[c]}}function I(e){const r=e.split(/[.]|(?:\[(\d|\*)\])/).filter(t=>!!t);return r.some(t=>B.indexOf(t)!==-1)?[]:r}var s=(e=>(e.text="text",e.number="number",e.email="email",e.password="password",e.tel="tel",e.url="url",e.search="search",e.date="date",e.time="time",e.datetimeLocal="datetimeLocal",e.month="month",e.week="week",e.color="color",e.select="select",e.checkbox="checkbox",e.radio="radio",e.textarea="textarea",e.radioGroup="radioGroup",e.checkboxGroup="checkboxGroup",e.combobox="combobox",e.custom="custom",e))(s||{});const q=(e,r,t,o={})=>a.defineComponent({name:"FieldComponent",props:{type:{type:String,validator:n=>Object.values(s).includes(n),default:s.custom},is:{type:[Object,String],default:void 0},name:{type:[String,Number,Boolean,Symbol],required:!0},props:{type:[Object,Function],default:()=>({})},showValid:{type:Boolean,default:!1},defaultValue:{type:[String,Number,Boolean,Array,Object],default:void 0}},emits:["invalid","valid","update:formData","update:modelValue"],expose:["invalid","invalidLabel","errors"],setup(n,{slots:l,emit:c}){const u=a.computed({get(){if(i!=null&&i.modelValue)return $(Object(i.modelValue.value),String(n.name))},set(f){i!=null&&i.modelValue&&(k(Object(i.modelValue.value),String(n.name),f),c("update:modelValue",{newValue:u.value,formData:i==null?void 0:i.modelValue}))}});a.onMounted(()=>{u.value===void 0&&n.defaultValue!==void 0&&(u.value=n.defaultValue)});const d=a.inject(r,void 0);d&&d.fields.value.add(n.name);const i=a.inject(e),{props:m,name:h}=a.toRefs(n),p=a.computed(()=>{if(i!=null&&i.errors.value)return $(i.errors.value,String(n.name))}),y=a.computed(()=>{var f;return(f=p.value)==null?void 0:f._errors}),V=a.computed(()=>p.value!==void 0);a.watch(V,()=>{V.value?(c("invalid",y.value),d&&d.errors.value.set(n.name,{_errors:y.value})):(c("valid",u.value),d&&d.errors.value.delete(n.name))}),a.watch(()=>i==null?void 0:i.modelValue,()=>{c("update:formData",i==null?void 0:i.modelValue)},{deep:!0});const G=f=>{u.value=f},L=a.computed(()=>typeof m.value=="function"?m.value(i==null?void 0:i.modelValue):m.value),le=a.computed(()=>({...L.value,name:L.value.name??n.name,invalid:V.value,valid:n.showValid?Boolean(!V.value&&u.value):void 0,type:(f=>{if([s.text,s.number,s.email,s.password,s.tel,s.url,s.search,s.date,s.time,s.datetimeLocal,s.month,s.week,s.color].includes(f))return f})(n.type),invalidLabel:y.value,modelValue:u.value,errors:n.is?p.value:void 0,"onUpdate:modelValue":G}));return a.provide(t,{name:a.readonly(h),errors:a.readonly(p)}),{component:a.computed(()=>{if(n.type===s.custom)return{render(){var f;return((f=l.default)==null?void 0:f.call(l,{modelValue:u.value,onUpdate:G,invalid:V.value,invalidLabel:y.value,formData:i==null?void 0:i.modelValue.value,formErrors:i==null?void 0:i.errors.value,errors:p.value}))??l.defalut}};if(!o.lazyLoad){let f;switch(n.type){case s.select:f=a.resolveComponent("VvSelect");break;case s.checkbox:f=a.resolveComponent("VvCheckbox");break;case s.radio:f=a.resolveComponent("VvRadio");break;case s.textarea:f=a.resolveComponent("VvTextarea");break;case s.radioGroup:f=a.resolveComponent("VvRadioGroup");break;case s.checkboxGroup:f=a.resolveComponent("VvCheckboxGroup");break;case s.combobox:f=a.resolveComponent("VvCombobox");break;default:f=a.resolveComponent("VvInputText")}if(typeof f!="string")return f;console.warn(`[form-vue warn]: ${f} not found, the component will be loaded asynchronously. To avoid this warning, please set "lazyLoad" option.`)}return a.defineAsyncComponent(async()=>{switch(o.sideEffects&&await Promise.resolve(o.sideEffects(n.type)),n.type){case s.textarea:return import("@volverjs/ui-vue/vv-textarea");case s.radio:return import("@volverjs/ui-vue/vv-radio");case s.radioGroup:return import("@volverjs/ui-vue/vv-radio-group");case s.checkbox:return import("@volverjs/ui-vue/vv-checkbox");case s.checkboxGroup:return import("@volverjs/ui-vue/vv-checkbox-group");case s.combobox:return import("@volverjs/ui-vue/vv-combobox")}return import("@volverjs/ui-vue/vv-input-text")})}),hasProps:le,invalid:V}},render(){return this.is?a.h(this.is,this.hasProps,this.$slots):this.type===s.custom?a.h(this.component,null,this.$slots):a.h(this.component,this.hasProps,this.$slots)}});var K=function(r){return z(r)&&!J(r)};function z(e){return!!e&&typeof e=="object"}function J(e){var r=Object.prototype.toString.call(e);return r==="[object RegExp]"||r==="[object Date]"||Y(e)}var R=typeof Symbol=="function"&&Symbol.for,Z=R?Symbol.for("react.element"):60103;function Y(e){return e.$$typeof===Z}function H(e){return Array.isArray(e)?[]:{}}function g(e,r){return r.clone!==!1&&r.isMergeableObject(e)?v(H(e),e,r):e}function Q(e,r,t){return e.concat(r).map(function(o){return g(o,t)})}function X(e,r){if(!r.customMerge)return v;var t=r.customMerge(e);return typeof t=="function"?t:v}function P(e){return Object.getOwnPropertySymbols?Object.getOwnPropertySymbols(e).filter(function(r){return Object.propertyIsEnumerable.call(e,r)}):[]}function N(e){return Object.keys(e).concat(P(e))}function _(e,r){try{return r in e}catch{return!1}}function T(e,r){return _(e,r)&&!(Object.hasOwnProperty.call(e,r)&&Object.propertyIsEnumerable.call(e,r))}function F(e,r,t){var o={};return t.isMergeableObject(e)&&N(e).forEach(function(n){o[n]=g(e[n],t)}),N(r).forEach(function(n){T(e,n)||(_(e,n)&&t.isMergeableObject(r[n])?o[n]=X(n,t)(e[n],r[n],t):o[n]=g(r[n],t))}),o}function v(e,r,t){t=t||{},t.arrayMerge=t.arrayMerge||Q,t.isMergeableObject=t.isMergeableObject||K,t.cloneUnlessOtherwiseSpecified=g;var o=Array.isArray(r),n=Array.isArray(e),l=o===n;return l?o?t.arrayMerge(e,r,t):F(e,r,t):g(r,t)}v.all=function(r,t){if(!Array.isArray(r))throw new Error("first argument should be an array");return r.reduce(function(o,n){return v(o,n,t)},{})};var ee=v,re=ee;const x=(e,r={})=>{const t=e instanceof S.ZodEffects?e.innerType().shape:e.shape;return re(Object.fromEntries(Object.entries(t).map(([o,n])=>n instanceof S.ZodDefault?[o,n._def.defaultValue()]:n instanceof S.ZodObject?[o,x(n)]:[o,void 0])),r)},te=(e,r,t)=>a.defineComponent({name:"FormComponent",props:{modelValue:{type:Object,default:()=>({})}},emits:["invalid","valid","submit","update:modelValue"],expose:["submit","errors","status"],setup(o,{emit:n}){const l=a.ref(x(e,o.modelValue));a.watch(()=>o.modelValue,m=>{if(m){const h=a.isProxy(m)?a.toRaw(m):m;l.value=typeof(h==null?void 0:h.clone)=="function"?h.clone():JSON.parse(JSON.stringify(h))}},{deep:!0}),D.watchThrottled(l,m=>{(c.value||t!=null&&t.continuosValidation)&&d(),(!m||!o.modelValue||JSON.stringify(m)!==JSON.stringify(o.modelValue))&&n("update:modelValue",m)},{deep:!0,throttle:(t==null?void 0:t.updateThrottle)??500});const c=a.ref(),u=a.ref(),d=(m=l.value)=>{const h=e.safeParse(m);return h.success?(c.value=void 0,u.value="valid",l.value=h.data,n("valid",h.data),!0):(c.value=h.error.format(),u.value="invalid",n("invalid",c.value),!1)},i=()=>d()?(n("submit",l.value),!0):!1;return a.provide(r,{modelValue:l,submit:i,errors:a.readonly(c)}),{submit:i}},render(){return a.h("form",{onSubmit:a.withModifiers(this.submit,["prevent"])},this.$slots)}}),ne=(e,r)=>a.defineComponent({name:"WrapperComponent",props:{name:{type:String,required:!0},tag:{type:String,default:void 0}},emits:["invalid","valid"],expose:["fields","invalid"],setup(t,{emit:o}){const n=a.inject(e),l=a.inject(r,void 0),c=a.ref(new Set),u=a.ref(new Map),{name:d}=a.toRefs(t);a.provide(r,{name:a.readonly(d),errors:u,fields:c}),a.watch(c,m=>{l!=null&&l.fields&&m.forEach(h=>{l==null||l.fields.value.add(h)})},{deep:!0}),a.watch(()=>new Map(u.value),(m,h)=>{l!=null&&l.errors&&(Array.from(h.keys()).forEach(p=>{l.errors.value.delete(p)}),Array.from(m.keys()).forEach(p=>{const y=m.get(p);y&&l.errors.value.set(p,y)}))},{deep:!0});const i=a.computed(()=>n!=null&&n.errors.value?u.value.size>0:!1);return a.watch(i,()=>{i.value?o("invalid"):o("valid")}),{formProvided:n,invalid:i,fields:c,errors:u}},render(){var t,o,n,l,c,u,d,i;return this.tag?a.h(this.tag,null,((l=(n=this.$slots).default)==null?void 0:l.call(n,{invalid:this.invalid,formData:(t=this.formProvided)==null?void 0:t.modelValue,errors:(o=this.formProvided)==null?void 0:o.errors,fieldsErrors:this.errors}))??this.$slots.defalut):((i=(d=this.$slots).default)==null?void 0:i.call(d,{invalid:this.invalid,formData:(c=this.formProvided)==null?void 0:c.modelValue,errors:(u=this.formProvided)==null?void 0:u.errors,fieldsErrors:this.errors}))??this.$slots.defalut}}),w=(e,r={})=>{const t=Symbol(),o=Symbol(),n=Symbol(),l=te(e,t,r),c=ne(t,o),u=q(t,o,n,r);return{VvForm:l,VvFormWrapper:c,VvFormField:u,formInjectionKey:t,formWrapperInjectionKey:o,formFieldInjectionKey:n}},M=Symbol(),ae=e=>{let r={};return e.schema&&(r=w(e.schema,e)),{...r,install(t,{global:o=!1}={}){t.provide(M,e),o&&(t.config.globalProperties.$vvForm=e,r!=null&&r.VvForm&&t.component("VvForm",r.VvForm),r!=null&&r.VvFormWrapper&&t.component("VvFormWrapper",r.VvFormWrapper),r!=null&&r.VvFormField&&t.component("VvFormField",r.VvFormField))}}},oe=(e,r={})=>{const t={...a.inject(M,{}),...r};return w(e,t)};b.FormFieldType=s,b.createForm=ae,b.defaultObjectBySchema=x,b.formFactory=w,b.pluginInjectionKey=M,b.useForm=oe,Object.defineProperty(b,Symbol.toStringTag,{value:"Module"})});
1
+ (function(v,t){typeof exports=="object"&&typeof module<"u"?t(exports,require("vue"),require("@vueuse/core"),require("zod")):typeof define=="function"&&define.amd?define(["exports","vue","@vueuse/core","zod"],t):(v=typeof globalThis<"u"?globalThis:v||self,t(v["@volverjs/form-vue"]={},v.Vue,v.VueUseCore,v.zod))})(this,function(v,t,A,y){"use strict";function x(e){return Array.isArray(e)}function D(e){return typeof e<"u"}function S(e){return e===null}function C(e){return typeof e=="object"}function j(e){return typeof e=="string"}function g(e){return typeof e>"u"}const _=/^[0-9]+$/,B=["__proto__","prototype","constructor"];function $(e,o,l){const u=D(l)?l:void 0;if(!C(e)||!j(o))return u;const r=G(o);if(r.length!==0){for(const n of r){if(n==="*")continue;const c=function(i){return i.map(f=>g(f)||S(f)?f:x(f)?c(f):f[n])};if(x(e)&&!_.test(n)?e=c(e):e=e[n],g(e)||S(e))break}return g(e)?u:e}}function E(e,o,l){if(!C(e)||!j(o))return;const u=G(o);if(u.length===0)return;const r=u.length;for(let n=0;n<r;n++){const c=u[n];if(n===r-1){e[c]=l;return}if(c==="*"&&x(e)){const i=u.slice(n+1).join(".");for(const f of e)E(f,i,l);return}g(e[c])&&(e[c]={}),e=e[c]}}function G(e){const o=e.split(/[.]|(?:\[(\d|\*)\])/).filter(l=>!!l);return o.some(l=>B.indexOf(l)!==-1)?[]:o}var s=(e=>(e.text="text",e.number="number",e.email="email",e.password="password",e.tel="tel",e.url="url",e.search="search",e.date="date",e.time="time",e.datetimeLocal="datetimeLocal",e.month="month",e.week="week",e.color="color",e.select="select",e.checkbox="checkbox",e.radio="radio",e.textarea="textarea",e.radioGroup="radioGroup",e.checkboxGroup="checkboxGroup",e.combobox="combobox",e.custom="custom",e))(s||{});const K=(e,o,l,u={})=>t.defineComponent({name:"FieldComponent",props:{type:{type:String,validator:r=>Object.values(s).includes(r),default:s.custom},is:{type:[Object,String],default:void 0},name:{type:[String,Number,Boolean,Symbol],required:!0},props:{type:[Object,Function],default:()=>({})},showValid:{type:Boolean,default:!1},defaultValue:{type:[String,Number,Boolean,Array,Object],default:void 0}},emits:["invalid","valid","update:formData","update:modelValue"],expose:["invalid","invalidLabel","errors"],setup(r,{slots:n,emit:c}){const i=t.computed({get(){if(a!=null&&a.modelValue)return $(Object(a.modelValue.value),String(r.name))},set(d){a!=null&&a.modelValue&&(E(Object(a.modelValue.value),String(r.name),d),c("update:modelValue",{newValue:i.value,formData:a==null?void 0:a.modelValue}))}});t.onMounted(()=>{i.value===void 0&&r.defaultValue!==void 0&&(i.value=r.defaultValue)});const f=t.inject(o,void 0);f&&f.fields.value.add(r.name);const a=t.inject(e),{props:p,name:h}=t.toRefs(r),m=t.computed(()=>{if(a!=null&&a.errors.value)return $(a.errors.value,String(r.name))}),V=t.computed(()=>{var d;return(d=m.value)==null?void 0:d._errors}),b=t.computed(()=>m.value!==void 0);t.watch(b,()=>{b.value?(c("invalid",V.value),f&&f.errors.value.set(r.name,{_errors:V.value})):(c("valid",i.value),f&&f.errors.value.delete(r.name))}),t.watch(()=>a==null?void 0:a.modelValue,()=>{c("update:formData",a==null?void 0:a.modelValue)},{deep:!0});const L=d=>{i.value=d},N=t.computed(()=>typeof p.value=="function"?p.value(a==null?void 0:a.modelValue):p.value),q=t.computed(()=>({...N.value,name:N.value.name??r.name,invalid:b.value,valid:r.showValid?!!(!b.value&&i.value):void 0,type:(d=>{if([s.text,s.number,s.email,s.password,s.tel,s.url,s.search,s.date,s.time,s.datetimeLocal,s.month,s.week,s.color].includes(d))return d})(r.type),invalidLabel:V.value,modelValue:i.value,errors:r.is?m.value:void 0,"onUpdate:modelValue":L}));return t.provide(l,{name:t.readonly(h),errors:t.readonly(m)}),{component:t.computed(()=>{if(r.type===s.custom)return{render(){var d;return((d=n.default)==null?void 0:d.call(n,{modelValue:i.value,onUpdate:L,invalid:b.value,invalidLabel:V.value,formData:a==null?void 0:a.modelValue.value,formErrors:a==null?void 0:a.errors.value,errors:m.value}))??n.defalut}};if(!u.lazyLoad){let d;switch(r.type){case s.select:d=t.resolveComponent("VvSelect");break;case s.checkbox:d=t.resolveComponent("VvCheckbox");break;case s.radio:d=t.resolveComponent("VvRadio");break;case s.textarea:d=t.resolveComponent("VvTextarea");break;case s.radioGroup:d=t.resolveComponent("VvRadioGroup");break;case s.checkboxGroup:d=t.resolveComponent("VvCheckboxGroup");break;case s.combobox:d=t.resolveComponent("VvCombobox");break;default:d=t.resolveComponent("VvInputText")}if(typeof d!="string")return d;console.warn(`[form-vue warn]: ${d} not found, the component will be loaded asynchronously. To avoid this warning, please set "lazyLoad" option.`)}return t.defineAsyncComponent(async()=>{switch(u.sideEffects&&await Promise.resolve(u.sideEffects(r.type)),r.type){case s.textarea:return import("@volverjs/ui-vue/vv-textarea");case s.radio:return import("@volverjs/ui-vue/vv-radio");case s.radioGroup:return import("@volverjs/ui-vue/vv-radio-group");case s.checkbox:return import("@volverjs/ui-vue/vv-checkbox");case s.checkboxGroup:return import("@volverjs/ui-vue/vv-checkbox-group");case s.combobox:return import("@volverjs/ui-vue/vv-combobox")}return import("@volverjs/ui-vue/vv-input-text")})}),hasProps:q,invalid:b}},render(){return this.is?t.h(this.is,this.hasProps,this.$slots):this.type===s.custom?t.h(this.component,null,this.$slots):t.h(this.component,this.hasProps,this.$slots)}}),k=(e,o={})=>{const l=e instanceof y.ZodEffects?e.innerType().shape:e.shape;return{...(e instanceof y.ZodObject?e._def.unknownKeys==="passthrough":!1)?o:{},...Object.fromEntries(Object.entries(l).map(([r,n])=>{const c=o[r];let i;if(n instanceof y.ZodDefault&&(i=n._def.defaultValue()),c===null&&n instanceof y.ZodNullable)return[r,c];if(n instanceof y.ZodSchema){const f=n.safeParse(o[r]);if(f.success)return[r,f.data??i]}return n instanceof y.ZodObject?[r,k(n,c&&typeof c=="object"?c:{})]:[r,i]}))}},M=(e,o,l)=>t.defineComponent({name:"FormComponent",props:{modelValue:{type:Object,default:()=>({})},continuosValidation:{type:Boolean,default:!1}},emits:["invalid","valid","submit","update:modelValue"],expose:["submit","errors","status"],setup(u,{emit:r}){const n=t.ref(k(e,u.modelValue)),c=(l==null?void 0:l.continuosValidation)||u.continuosValidation;t.watch(()=>u.modelValue,h=>{if(h){const m=t.isProxy(h)?t.toRaw(h):h;n.value=typeof(m==null?void 0:m.clone)=="function"?m.clone():JSON.parse(JSON.stringify(m))}},{deep:!0}),A.watchThrottled(n,h=>{(i.value||c)&&a(),(!h||!u.modelValue||JSON.stringify(h)!==JSON.stringify(u.modelValue))&&r("update:modelValue",h)},{deep:!0,throttle:(l==null?void 0:l.updateThrottle)??500});const i=t.ref(),f=t.ref(),a=(h=n.value)=>{const m=e.safeParse(h);return m.success?(i.value=void 0,f.value="valid",n.value=m.data,r("valid",m.data),!0):(i.value=m.error.format(),f.value="invalid",r("invalid",i.value),!1)},p=()=>a()?(r("submit",n.value),!0):!1;return t.provide(o,{modelValue:n,submit:p,errors:t.readonly(i)}),{submit:p}},render(){return t.h("form",{onSubmit:t.withModifiers(this.submit,["prevent"])},this.$slots)}}),W=(e,o)=>t.defineComponent({name:"WrapperComponent",props:{name:{type:String,required:!0},tag:{type:String,default:void 0}},emits:["invalid","valid"],expose:["fields","invalid"],setup(l,{emit:u}){const r=t.inject(e),n=t.inject(o,void 0),c=t.ref(new Set),i=t.ref(new Map),{name:f}=t.toRefs(l);t.provide(o,{name:t.readonly(f),errors:i,fields:c}),t.watch(c,p=>{n!=null&&n.fields&&p.forEach(h=>{n==null||n.fields.value.add(h)})},{deep:!0}),t.watch(()=>new Map(i.value),(p,h)=>{n!=null&&n.errors&&(Array.from(h.keys()).forEach(m=>{n.errors.value.delete(m)}),Array.from(p.keys()).forEach(m=>{const V=p.get(m);V&&n.errors.value.set(m,V)}))},{deep:!0});const a=t.computed(()=>r!=null&&r.errors.value?i.value.size>0:!1);return t.watch(a,()=>{a.value?u("invalid"):u("valid")}),{formProvided:r,invalid:a,fields:c,errors:i}},render(){var l,u,r,n,c,i,f,a;return this.tag?t.h(this.tag,null,((n=(r=this.$slots).default)==null?void 0:n.call(r,{invalid:this.invalid,formData:(l=this.formProvided)==null?void 0:l.modelValue,errors:(u=this.formProvided)==null?void 0:u.errors,fieldsErrors:this.errors}))??this.$slots.defalut):((a=(f=this.$slots).default)==null?void 0:a.call(f,{invalid:this.invalid,formData:(c=this.formProvided)==null?void 0:c.modelValue,errors:(i=this.formProvided)==null?void 0:i.errors,fieldsErrors:this.errors}))??this.$slots.defalut}}),w=(e,o={})=>{const l=Symbol(),u=Symbol(),r=Symbol(),n=M(e,l,o),c=W(l,u),i=K(l,u,r,o);return{VvForm:n,VvFormWrapper:c,VvFormField:i,formInjectionKey:l,formWrapperInjectionKey:u,formFieldInjectionKey:r}},O=Symbol(),I=e=>{let o={};return e.schema&&(o=w(e.schema,e)),{...o,install(l,{global:u=!1}={}){l.provide(O,e),u&&(l.config.globalProperties.$vvForm=e,o!=null&&o.VvForm&&l.component("VvForm",o.VvForm),o!=null&&o.VvFormWrapper&&l.component("VvFormWrapper",o.VvFormWrapper),o!=null&&o.VvFormField&&l.component("VvFormField",o.VvFormField))}}},Z=(e,o={})=>{const l={...t.inject(O,{}),...o};return w(e,l)};v.FormFieldType=s,v.createForm=I,v.defaultObjectBySchema=k,v.formFactory=w,v.pluginInjectionKey=O,v.useForm=Z,Object.defineProperty(v,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -19,7 +19,7 @@
19
19
  "bugs": {
20
20
  "url": "https://github.com/volverjs/form-vue/issues"
21
21
  },
22
- "version": "0.0.3",
22
+ "version": "0.0.5",
23
23
  "engines": {
24
24
  "node": ">= 16.x"
25
25
  },
@@ -36,31 +36,29 @@
36
36
  "dependencies": {
37
37
  "@volverjs/ui-vue": "0.0.5-beta.1",
38
38
  "@vueuse/core": "^9.13.0",
39
- "deepmerge": "^4.3.0",
40
39
  "ts-dot-prop": "^2.1.2",
41
40
  "vue": "^3.2.47",
42
41
  "zod": "^3.21.4"
43
42
  },
44
43
  "devDependencies": {
45
- "@testing-library/vue": "^6.6.1",
46
- "@typescript-eslint/eslint-plugin": "^5.54.1",
47
- "@typescript-eslint/parser": "^5.54.1",
48
- "@vitejs/plugin-vue": "^4.0.0",
44
+ "@testing-library/vue": "^7.0.0",
45
+ "@typescript-eslint/eslint-plugin": "^5.55.0",
46
+ "@typescript-eslint/parser": "^5.55.0",
47
+ "@vitejs/plugin-vue": "^4.1.0",
49
48
  "@vue/compiler-sfc": "^3.2.47",
50
49
  "@vue/runtime-core": "^3.2.47",
51
50
  "@vue/test-utils": "^2.3.1",
52
51
  "copy": "^0.3.2",
53
- "eslint": "^8.35.0",
52
+ "eslint": "^8.36.0",
54
53
  "eslint-config-prettier": "^8.7.0",
55
54
  "eslint-plugin-prettier": "^4.2.1",
56
55
  "happy-dom": "^8.9.0",
57
56
  "prettier": "^2.8.4",
58
- "sass": "^1.58.3",
59
- "typescript": "^4.9.5",
60
- "vite": "^4.1.4",
57
+ "typescript": "^5.0.2",
58
+ "vite": "^4.2.0",
61
59
  "vite-plugin-eslint": "^1.8.1",
62
60
  "vite-plugin-externalize-deps": "^0.5.0",
63
- "vitest": "^0.29.2",
61
+ "vitest": "^0.29.3",
64
62
  "vue-tsc": "^1.2.0"
65
63
  },
66
64
  "typesVersions": {
package/src/VvForm.ts CHANGED
@@ -36,6 +36,10 @@ export const defineForm = (
36
36
  type: Object,
37
37
  default: () => ({}),
38
38
  },
39
+ continuosValidation: {
40
+ type: Boolean,
41
+ default: false,
42
+ },
39
43
  },
40
44
  emits: ['invalid', 'valid', 'submit', 'update:modelValue'],
41
45
  expose: ['submit', 'errors', 'status'],
@@ -43,6 +47,10 @@ export const defineForm = (
43
47
  const localModelValue = ref(
44
48
  defaultObjectBySchema(schema, props.modelValue),
45
49
  )
50
+
51
+ const keepValidation =
52
+ options?.continuosValidation || props.continuosValidation
53
+
46
54
  watch(
47
55
  () => props.modelValue,
48
56
  (newValue) => {
@@ -62,7 +70,7 @@ export const defineForm = (
62
70
  watchThrottled(
63
71
  localModelValue,
64
72
  (newValue) => {
65
- if (errors.value || options?.continuosValidation) {
73
+ if (errors.value || keepValidation) {
66
74
  parseModelValue()
67
75
  }
68
76
  if (
package/src/utils.ts CHANGED
@@ -1,10 +1,11 @@
1
- import merge from 'deepmerge'
2
1
  import {
3
2
  type z,
4
3
  type AnyZodObject,
5
4
  ZodDefault,
6
5
  ZodObject,
7
6
  ZodEffects,
7
+ ZodSchema,
8
+ ZodNullable,
8
9
  } from 'zod'
9
10
 
10
11
  export const defaultObjectBySchema = <
@@ -15,18 +16,45 @@ export const defaultObjectBySchema = <
15
16
  ): Partial<z.infer<Schema>> => {
16
17
  const shape =
17
18
  schema instanceof ZodEffects ? schema.innerType().shape : schema.shape
18
- return merge(
19
- Object.fromEntries(
20
- Object.entries(shape).map(([key, value]) => {
21
- if (value instanceof ZodDefault) {
22
- return [key, value._def.defaultValue()]
19
+
20
+ const unknownKeys =
21
+ schema instanceof ZodObject
22
+ ? schema._def.unknownKeys === 'passthrough'
23
+ : false
24
+ return {
25
+ ...(unknownKeys ? original : {}),
26
+ ...Object.fromEntries(
27
+ Object.entries(shape).map(([key, subSchema]) => {
28
+ const originalValue = original[key]
29
+ let defaultValue = undefined
30
+ if (subSchema instanceof ZodDefault) {
31
+ defaultValue = subSchema._def.defaultValue()
32
+ }
33
+ if (
34
+ originalValue === null &&
35
+ subSchema instanceof ZodNullable
36
+ ) {
37
+ return [key, originalValue]
38
+ }
39
+ if (subSchema instanceof ZodSchema) {
40
+ const parse = subSchema.safeParse(original[key])
41
+ if (parse.success) {
42
+ return [key, parse.data ?? defaultValue]
43
+ }
23
44
  }
24
- if (value instanceof ZodObject) {
25
- return [key, defaultObjectBySchema(value)]
45
+ if (subSchema instanceof ZodObject) {
46
+ return [
47
+ key,
48
+ defaultObjectBySchema(
49
+ subSchema,
50
+ originalValue && typeof originalValue === 'object'
51
+ ? originalValue
52
+ : {},
53
+ ),
54
+ ]
26
55
  }
27
- return [key, undefined]
56
+ return [key, defaultValue]
28
57
  }),
29
58
  ),
30
- original,
31
- ) as Partial<z.infer<Schema>>
59
+ } as Partial<z.infer<Schema>>
32
60
  }