@teamnovu/kit-vue-forms 0.1.22 → 0.1.23

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.
@@ -10,4 +10,4 @@ export declare class HashStore<T, Item = unknown> {
10
10
  get(item: Item): T | undefined;
11
11
  set(item: Item, value: T): void;
12
12
  }
13
- export declare function useFieldArray<T extends FormDataDefault, K extends Paths<T>>(form: Form<T>, path: PickProps<T, K> extends unknown[] ? K : never, options?: FieldArrayOptions<PickProps<T, K> extends (infer U)[] ? U : never>): FieldArray<PickProps<T, K> extends (infer U)[] ? U : never>;
13
+ export declare function useFieldArray<T extends FormDataDefault, K extends Paths<T>>(form: Form<T>, path: PickProps<T, K> extends unknown[] ? K : never, options?: FieldArrayOptions<PickProps<T, K> extends (infer U)[] ? U : never>): FieldArray<PickProps<T, K> extends (infer U)[] ? U : never, typeof path>;
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  var Q = Object.defineProperty;
2
2
  var X = (r, t, e) => t in r ? Q(r, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : r[t] = e;
3
3
  var R = (r, t, e) => X(r, typeof t != "symbol" ? t + "" : t, e);
4
- import { toValue as Y, toRaw as ee, unref as d, shallowRef as I, watch as D, computed as V, isRef as O, reactive as A, toRefs as K, shallowReactive as te, toRef as U, onScopeDispose as re, triggerRef as ae, ref as J, getCurrentScope as se, onBeforeUnmount as ne, defineComponent as C, renderSlot as k, normalizeProps as T, guardReactiveProps as N, resolveComponent as ie, createBlock as z, openBlock as H, withCtx as B, resolveDynamicComponent as oe, mergeProps as le, createSlots as ce, renderList as ue } from "vue";
4
+ import { toValue as Y, toRaw as ee, unref as f, shallowRef as $, watch as D, computed as m, isRef as x, reactive as k, toRefs as K, shallowReactive as te, toRef as j, onScopeDispose as re, triggerRef as ae, ref as J, getCurrentScope as se, onBeforeUnmount as ne, defineComponent as C, renderSlot as b, normalizeProps as T, guardReactiveProps as N, resolveComponent as ie, createBlock as z, openBlock as H, withCtx as U, resolveDynamicComponent as oe, mergeProps as le, createSlots as ce, renderList as ue } from "vue";
5
5
  import { cloneDeep as de } from "lodash-es";
6
6
  import "zod";
7
7
  function g(r) {
@@ -10,7 +10,7 @@ function g(r) {
10
10
  }
11
11
  function L(r, t) {
12
12
  return (e) => async (a) => {
13
- a.preventDefault(), d(t.validationStrategy) !== "none" && await r.validateForm(), r.isValid.value && await e(r.data.value);
13
+ a.preventDefault(), f(t.validationStrategy) !== "none" && await r.validateForm(), r.isValid.value && await e(r.data.value);
14
14
  };
15
15
  }
16
16
  class fe {
@@ -36,51 +36,50 @@ class fe {
36
36
  this.isReferenceType(a) ? this.weakMap.set(a, e) : this.map.set(a, e);
37
37
  }
38
38
  }
39
- function he(r, t) {
40
- const e = /* @__PURE__ */ new Set();
41
- return t.map((a) => {
42
- const s = [...r.get(a) ?? []], n = s.findIndex((c) => !e.has(c)), p = (n === -1 ? [] : s.slice(n))[0];
43
- if (p)
44
- return e.add(p), {
45
- id: p,
46
- item: a
39
+ function he(r, t, e) {
40
+ const a = /* @__PURE__ */ new Set();
41
+ return t.map((s, n) => {
42
+ const d = [...r.get(s) ?? []], V = d.findIndex((p) => !a.has(p)), c = (V === -1 ? [] : d.slice(V))[0];
43
+ if (c)
44
+ return a.add(c), {
45
+ id: c,
46
+ item: s,
47
+ path: `${e}.${n}`
47
48
  };
48
- const v = crypto.randomUUID();
49
- return r.set(a, s.concat([v])), e.add(v), {
50
- id: v,
51
- item: a
49
+ const o = crypto.randomUUID();
50
+ return r.set(s, d.concat([o])), a.add(o), {
51
+ id: o,
52
+ item: s,
53
+ path: `${e}.${n}`
52
54
  };
53
55
  });
54
56
  }
55
57
  function G(r, t, e) {
56
- const a = new fe(e == null ? void 0 : e.hashFn), s = r.getField(t), n = I([]);
58
+ const a = new fe(e == null ? void 0 : e.hashFn), s = r.getField(t), n = $([]);
57
59
  return D(
58
60
  s.data,
59
- (c) => {
60
- n.value = he(a, c);
61
+ (h) => {
62
+ n.value = he(a, h, t);
61
63
  },
62
64
  {
63
65
  immediate: !0,
64
66
  flush: "sync"
65
67
  }
66
68
  ), {
67
- fields: n,
68
- push: (c) => {
69
- const i = s.data.value ?? [];
70
- s.setData([...i, c]);
69
+ items: n,
70
+ push: (h) => {
71
+ const c = s.data.value ?? [];
72
+ return s.setData([...c, h]), n.value.at(-1);
71
73
  },
72
- remove: (c) => {
73
- const i = s.data.value ?? [];
74
- s.setData(
75
- (i == null ? void 0 : i.filter((h) => h !== d(c))) ?? []
74
+ remove: (h) => {
75
+ const c = s.data.value ?? [], o = n.value.findIndex(
76
+ ({ id: p }) => p === h
77
+ );
78
+ o !== -1 && s.setData(
79
+ c.slice(0, o).concat(c.slice(o + 1))
76
80
  );
77
81
  },
78
- removeByIndex: (c) => {
79
- const i = s.data.value ?? [];
80
- s.setData((i == null ? void 0 : i.filter((h, l) => l !== c)) ?? []);
81
- },
82
- errors: s.errors,
83
- dirty: s.dirty
82
+ field: s
84
83
  };
85
84
  }
86
85
  function W(r) {
@@ -100,26 +99,26 @@ function ve(r, t, e) {
100
99
  const a = Array.isArray(t) ? t : W(t), s = a.at(-1);
101
100
  if (s) {
102
101
  const n = a.slice(0, -1).reduce(
103
- (f, p) => ((f == null ? void 0 : f[p]) === void 0 && (f[p] = {}), f == null ? void 0 : f[p]),
102
+ (d, V) => ((d == null ? void 0 : d[V]) === void 0 && (d[V] = {}), d == null ? void 0 : d[V]),
104
103
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
105
- d(r)
104
+ f(r)
106
105
  );
107
106
  n[s] = e;
108
107
  } else {
109
- if (!O(r))
108
+ if (!x(r))
110
109
  return;
111
110
  r.value = e;
112
111
  }
113
112
  }
114
- const Z = (r, t) => V({
113
+ const Z = (r, t) => m({
115
114
  get() {
116
- return S(d(r), d(t));
115
+ return S(f(r), f(t));
117
116
  },
118
117
  set(e) {
119
- ve(r, d(t), e);
118
+ ve(r, f(t), e);
120
119
  }
121
120
  });
122
- function b(r, t) {
121
+ function I(r, t) {
123
122
  return !r && !t ? "" : !r && t ? t : !t && r ? r : `${r}.${t}`;
124
123
  }
125
124
  function me(r, t) {
@@ -149,13 +148,13 @@ class Ve {
149
148
  this.rc > 0 && (this.rc -= 1, this.rc === 0 && this.drop && this.drop());
150
149
  }
151
150
  }
152
- function ye(r) {
151
+ function Fe(r) {
153
152
  const e = {
154
153
  ...{
155
154
  existsInForm: !0
156
155
  },
157
156
  ...r
158
- }, a = I(Object.freeze(g(e.initialValue))), s = A({
157
+ }, a = $(Object.freeze(g(e.initialValue))), s = k({
159
158
  value: e.value,
160
159
  path: e.path,
161
160
  initialValue: a,
@@ -163,51 +162,51 @@ function ye(r) {
163
162
  touched: !1
164
163
  });
165
164
  D(
166
- I(e.initialValue),
165
+ $(e.initialValue),
167
166
  () => {
168
- a.value = Object.freeze(g(e.initialValue)), s.value !== d(e.initialValue) && (s.value = g(e.initialValue));
167
+ a.value = Object.freeze(g(e.initialValue)), s.value !== f(e.initialValue) && (s.value = g(e.initialValue));
169
168
  },
170
169
  { flush: "sync" }
171
170
  );
172
- const n = V(() => JSON.stringify(s.value) !== JSON.stringify(s.initialValue)), f = (m) => {
173
- s.value = m;
174
- }, p = () => {
175
- var m;
176
- s.touched = !0, s.errors = [], (m = e.onBlur) == null || m.call(e);
177
- }, v = () => {
178
- var m;
179
- (m = e.onFocus) == null || m.call(e);
171
+ const n = m(() => JSON.stringify(s.value) !== JSON.stringify(s.initialValue)), d = (v) => {
172
+ s.value = v;
173
+ }, V = () => {
174
+ var v;
175
+ s.touched = !0, s.errors = [], (v = e.onBlur) == null || v.call(e);
176
+ }, h = () => {
177
+ var v;
178
+ (v = e.onFocus) == null || v.call(e);
180
179
  }, c = () => {
181
- const m = s.path.split(".").at(-1) || "";
182
- d(e.existsInForm) && !/^\d+$/.test(m) && (s.value = g(s.initialValue)), s.touched = !1, s.errors = [];
183
- }, i = (m) => {
184
- n.value || f(g(m)), s.initialValue = m;
185
- }, h = (m) => {
186
- s.errors = m;
180
+ const v = s.path.split(".").at(-1) || "";
181
+ f(e.existsInForm) && !/^\d+$/.test(v) && (s.value = g(s.initialValue)), s.touched = !1, s.errors = [];
182
+ }, o = (v) => {
183
+ n.value || d(g(v)), s.initialValue = v;
184
+ }, p = (v) => {
185
+ s.errors = v;
187
186
  }, l = () => {
188
187
  s.errors = [];
189
- }, o = K(s);
188
+ }, i = K(s);
190
189
  return {
191
- data: o.value,
192
- path: o.path,
193
- initialValue: o.initialValue,
194
- errors: o.errors,
195
- touched: o.touched,
190
+ data: i.value,
191
+ path: i.path,
192
+ initialValue: i.initialValue,
193
+ errors: i.errors,
194
+ touched: i.touched,
196
195
  dirty: n,
197
- setData: f,
198
- setInitialData: i,
199
- onBlur: p,
200
- onFocus: v,
196
+ setData: d,
197
+ setInitialData: o,
198
+ onBlur: V,
199
+ onFocus: h,
201
200
  reset: c,
202
- setErrors: h,
201
+ setErrors: p,
203
202
  clearErrors: l
204
203
  };
205
204
  }
206
- const Fe = {
205
+ const ye = {
207
206
  keepValuesOnUnmount: !0
208
207
  };
209
208
  function ge(r, t) {
210
- const e = () => S(r.initialData, t), a = I(e());
209
+ const e = () => S(r.initialData, t), a = $(e());
211
210
  return D(
212
211
  () => r.initialData,
213
212
  () => {
@@ -218,68 +217,68 @@ function ge(r, t) {
218
217
  }
219
218
  function Ee(r, t, e) {
220
219
  const a = /* @__PURE__ */ new Map(), s = te(/* @__PURE__ */ new Map()), n = {
221
- ...Fe,
220
+ ...ye,
222
221
  ...e
223
- }, f = (l) => {
224
- const o = d(l.path);
225
- s.set(o, l);
226
- }, p = (l) => {
227
- var o;
228
- n != null && n.keepValuesOnUnmount || (o = s.get(l)) == null || o.reset(), s.delete(l);
229
- }, v = (l) => {
230
- var o;
231
- a.has(l) ? (o = a.get(l)) == null || o.inc() : a.set(l, new Ve(() => p(l)));
222
+ }, d = (l) => {
223
+ const i = f(l.path);
224
+ s.set(i, l);
225
+ }, V = (l) => {
226
+ var i;
227
+ n != null && n.keepValuesOnUnmount || (i = s.get(l)) == null || i.reset(), s.delete(l);
228
+ }, h = (l) => {
229
+ var i;
230
+ a.has(l) ? (i = a.get(l)) == null || i.inc() : a.set(l, new Ve(() => V(l)));
232
231
  }, c = (l) => {
233
- var o;
234
- a.has(l) && ((o = a.get(l)) == null || o.dec());
235
- }, i = (l) => {
236
- const { path: o } = l;
237
- if (!s.has(o)) {
238
- const M = ye({
239
- path: o,
240
- value: Z(U(r, "data"), o),
241
- initialValue: ge(r, o),
242
- existsInForm: V(() => pe(r.data, d(o))),
243
- errors: V({
232
+ var i;
233
+ a.has(l) && ((i = a.get(l)) == null || i.dec());
234
+ }, o = (l) => {
235
+ const { path: i } = l;
236
+ if (!s.has(i)) {
237
+ const A = Fe({
238
+ path: i,
239
+ value: Z(j(r, "data"), i),
240
+ initialValue: ge(r, i),
241
+ existsInForm: m(() => pe(r.data, f(i))),
242
+ errors: m({
244
243
  get() {
245
- return t.errors.value.propertyErrors[o] || [];
244
+ return t.errors.value.propertyErrors[i] || [];
246
245
  },
247
246
  set(E) {
248
- t.errors.value.propertyErrors[o] = E;
247
+ t.errors.value.propertyErrors[i] = E;
249
248
  }
250
249
  }),
251
250
  onBlur: async () => {
252
251
  var E, P;
253
252
  await Promise.all([
254
- (E = n == null ? void 0 : n.onBlur) == null ? void 0 : E.call(n, d(o)),
253
+ (E = n == null ? void 0 : n.onBlur) == null ? void 0 : E.call(n, f(i)),
255
254
  (P = l.onBlur) == null ? void 0 : P.call(l)
256
255
  ]);
257
256
  },
258
257
  onFocus: async () => {
259
258
  var E, P;
260
259
  await Promise.all([
261
- (E = n == null ? void 0 : n.onFocus) == null ? void 0 : E.call(n, d(o)),
260
+ (E = n == null ? void 0 : n.onFocus) == null ? void 0 : E.call(n, f(i)),
262
261
  (P = l.onFocus) == null ? void 0 : P.call(l)
263
262
  ]);
264
263
  }
265
264
  });
266
- f(M);
265
+ d(A);
267
266
  }
268
- const m = s.get(o);
269
- return v(o), re(() => {
270
- c(o);
271
- }), m;
272
- }, h = (l) => i(l);
267
+ const v = s.get(i);
268
+ return h(i), re(() => {
269
+ c(i);
270
+ }), v;
271
+ }, p = (l) => o(l);
273
272
  return {
274
- fields: V(() => [...s.values()]),
275
- getField: (l) => i({ path: l }),
276
- registerField: f,
277
- deregisterField: p,
278
- defineField: h
273
+ fields: m(() => [...s.values()]),
274
+ getField: (l) => o({ path: l }),
275
+ registerField: d,
276
+ deregisterField: V,
277
+ defineField: p
279
278
  };
280
279
  }
281
280
  function we(r) {
282
- const t = V(() => r.fields.value.some((a) => d(a.dirty))), e = V(() => r.fields.value.some((a) => d(a.touched)));
281
+ const t = m(() => r.fields.value.some((a) => f(a.dirty))), e = m(() => r.fields.value.some((a) => f(a.touched)));
283
282
  return {
284
283
  isDirty: t,
285
284
  isTouched: e
@@ -312,7 +311,7 @@ function De(...r) {
312
311
  };
313
312
  }, {});
314
313
  }
315
- function j(...r) {
314
+ function B(...r) {
316
315
  if (!r.length)
317
316
  return {
318
317
  general: [],
@@ -345,7 +344,7 @@ function Pe(r) {
345
344
  propertyErrors: e
346
345
  };
347
346
  }
348
- const F = {
347
+ const y = {
349
348
  isValid: !0,
350
349
  errors: {
351
350
  general: [],
@@ -358,10 +357,10 @@ class Se {
358
357
  }
359
358
  async validate(t) {
360
359
  if (!this.schema)
361
- return F;
360
+ return y;
362
361
  const e = await this.schema.safeParseAsync(t);
363
362
  if (e.success)
364
- return F;
363
+ return y;
365
364
  const a = Pe(e.error);
366
365
  return {
367
366
  isValid: !1,
@@ -372,16 +371,16 @@ class Se {
372
371
  };
373
372
  }
374
373
  }
375
- class be {
374
+ class Ie {
376
375
  constructor(t) {
377
376
  this.validateFn = t;
378
377
  }
379
378
  async validate(t) {
380
379
  if (!this.validateFn)
381
- return F;
380
+ return y;
382
381
  try {
383
382
  const e = await this.validateFn(t);
384
- return e.isValid ? F : e;
383
+ return e.isValid ? y : e;
385
384
  } catch (e) {
386
385
  return {
387
386
  isValid: !1,
@@ -393,11 +392,11 @@ class be {
393
392
  }
394
393
  }
395
394
  }
396
- class Ie {
395
+ class $e {
397
396
  constructor(t, e) {
398
397
  R(this, "schemaValidator");
399
398
  R(this, "functionValidator");
400
- this.schema = t, this.validateFn = e, this.schemaValidator = new Se(this.schema), this.functionValidator = new be(this.validateFn);
399
+ this.schema = t, this.validateFn = e, this.schemaValidator = new Se(this.schema), this.functionValidator = new Ie(this.validateFn);
401
400
  }
402
401
  async validate(t) {
403
402
  const [e, a] = await Promise.all([
@@ -406,103 +405,103 @@ class Ie {
406
405
  ]);
407
406
  return {
408
407
  isValid: e.isValid && a.isValid,
409
- errors: j(e.errors, a.errors)
408
+ errors: B(e.errors, a.errors)
410
409
  };
411
410
  }
412
411
  }
413
- function x(r) {
414
- return V(() => new Ie(
415
- d(r.schema),
416
- d(r.validateFn)
412
+ function O(r) {
413
+ return m(() => new $e(
414
+ f(r.schema),
415
+ f(r.validateFn)
417
416
  ));
418
417
  }
419
- function ke(r, t) {
420
- const e = A({
421
- validators: J([x(t)]),
418
+ function be(r, t) {
419
+ const e = k({
420
+ validators: J([O(t)]),
422
421
  isValidated: !1,
423
- errors: d(t.errors) ?? F.errors
424
- }), a = (i = F.errors) => {
425
- e.errors = j(d(t.errors) ?? F.errors, i);
422
+ errors: f(t.errors) ?? y.errors
423
+ }), a = (o = y.errors) => {
424
+ e.errors = B(f(t.errors) ?? y.errors, o);
426
425
  };
427
- D(() => d(t.errors), async () => {
426
+ D(() => f(t.errors), async () => {
428
427
  if (e.isValidated) {
429
- const i = await n();
430
- a(i.errors);
428
+ const o = await n();
429
+ a(o.errors);
431
430
  } else
432
431
  a();
433
432
  }, { immediate: !0 }), D(
434
433
  [() => e.validators],
435
- async (i) => {
434
+ async (o) => {
436
435
  if (e.isValidated)
437
- if (i) {
438
- const h = await n();
439
- e.errors = h.errors;
436
+ if (o) {
437
+ const p = await n();
438
+ e.errors = p.errors;
440
439
  } else
441
- e.errors = F.errors;
440
+ e.errors = y.errors;
442
441
  },
443
442
  { immediate: !0 }
444
- ), D([() => r.data, () => d(t.schema)], () => {
445
- e.isValidated && f();
443
+ ), D([() => r.data, () => f(t.schema)], () => {
444
+ e.isValidated && d();
446
445
  });
447
- const s = (i) => {
448
- const h = O(i) ? i : x(i);
449
- return e.validators.push(h), se() && ne(() => {
446
+ const s = (o) => {
447
+ const p = x(o) ? o : O(o);
448
+ return e.validators.push(p), se() && ne(() => {
450
449
  e.validators = e.validators.filter(
451
- (l) => l !== h
450
+ (l) => l !== p
452
451
  );
453
- }), h;
452
+ }), p;
454
453
  };
455
454
  async function n() {
456
- const i = await Promise.all(
457
- e.validators.filter((o) => d(o) !== void 0).map((o) => d(o).validate(r.data))
458
- ), h = i.every((o) => o.isValid);
459
- let { errors: l } = F;
460
- if (!h) {
461
- const o = i.map((m) => m.errors);
462
- l = j(...o);
455
+ const o = await Promise.all(
456
+ e.validators.filter((i) => f(i) !== void 0).map((i) => f(i).validate(r.data))
457
+ ), p = o.every((i) => i.isValid);
458
+ let { errors: l } = y;
459
+ if (!p) {
460
+ const i = o.map((v) => v.errors);
461
+ l = B(...i);
463
462
  }
464
463
  return {
465
464
  errors: l,
466
- isValid: h
465
+ isValid: p
467
466
  };
468
467
  }
469
- const f = async () => {
470
- const i = await n();
471
- return a(i.errors), e.isValidated = !0, {
472
- isValid: !_(i.errors),
468
+ const d = async () => {
469
+ const o = await n();
470
+ return a(o.errors), e.isValidated = !0, {
471
+ isValid: !_(o.errors),
473
472
  errors: e.errors
474
473
  };
475
- }, p = async (i) => {
476
- const h = await n();
474
+ }, V = async (o) => {
475
+ const p = await n();
477
476
  return a({
478
- general: h.errors.general,
477
+ general: p.errors.general,
479
478
  propertyErrors: {
480
- [i]: h.errors.propertyErrors[i]
479
+ [o]: p.errors.propertyErrors[o]
481
480
  }
482
481
  }), {
483
- isValid: !_(h.errors),
482
+ isValid: !_(p.errors),
484
483
  errors: e.errors
485
484
  };
486
- }, v = V(() => !_(e.errors)), c = () => {
487
- e.isValidated = !1, e.errors = d(t.errors) ?? F.errors;
485
+ }, h = m(() => !_(e.errors)), c = () => {
486
+ e.isValidated = !1, e.errors = f(t.errors) ?? y.errors;
488
487
  };
489
488
  return {
490
489
  ...K(e),
491
- validateForm: f,
492
- validateField: p,
490
+ validateForm: d,
491
+ validateField: V,
493
492
  defineValidator: s,
494
- isValid: v,
493
+ isValid: h,
495
494
  reset: c
496
495
  };
497
496
  }
498
- class Ae {
497
+ class ke {
499
498
  constructor(t, e) {
500
499
  this.path = t, this.validator = e;
501
500
  }
502
501
  async validate(t) {
503
502
  const e = S(t, this.path);
504
503
  if (!this.validator)
505
- return F;
504
+ return y;
506
505
  const a = await this.validator.validate(e);
507
506
  return {
508
507
  isValid: a.isValid,
@@ -510,68 +509,68 @@ class Ae {
510
509
  general: a.errors.general || [],
511
510
  propertyErrors: a.errors.propertyErrors ? Object.fromEntries(
512
511
  Object.entries(a.errors.propertyErrors).map(
513
- ([s, n]) => [b(this.path, s), n]
512
+ ([s, n]) => [I(this.path, s), n]
514
513
  )
515
514
  ) : {}
516
515
  }
517
516
  };
518
517
  }
519
518
  }
520
- function Me(r, t, e, a) {
521
- const s = Z(r.data, t), n = V(() => S(r.initialData.value, t)), f = (u) => ({
519
+ function Ae(r, t, e, a) {
520
+ const s = Z(r.data, t), n = m(() => S(r.initialData.value, t)), d = (u) => ({
522
521
  ...u,
523
- path: V(() => d(u.path).replace(t + ".", "")),
524
- setData: (y) => {
525
- u.setData(y);
522
+ path: m(() => f(u.path).replace(t + ".", "")),
523
+ setData: (F) => {
524
+ u.setData(F);
526
525
  }
527
- }), p = (u) => {
528
- const y = b(t, u), w = r.getField(y);
529
- return w ? f(w) : {};
530
- }, v = (u) => {
531
- const y = b(t, u.path), w = r.defineField({
526
+ }), V = (u) => {
527
+ const F = I(t, u), w = r.getField(F);
528
+ return w ? d(w) : {};
529
+ }, h = (u) => {
530
+ const F = I(t, u.path), w = r.defineField({
532
531
  ...u,
533
- path: y
532
+ path: F
534
533
  });
535
- return f(w);
536
- }, c = V(() => r.fields.value.filter((u) => {
537
- const y = u.path.value;
538
- return y.startsWith(t + ".") || y === t;
539
- }).map((u) => f(u))), i = () => r.fields.value.filter((u) => {
540
- const y = u.path.value;
541
- return y.startsWith(t + ".") || y === t;
542
- }), h = V(() => i().some((u) => u.dirty.value)), l = V(() => i().some((u) => u.touched.value)), o = V(() => r.isValid.value), m = V(() => r.isValidated.value), M = V(() => me(d(r.errors), t)), $ = {
534
+ return d(w);
535
+ }, c = m(() => r.fields.value.filter((u) => {
536
+ const F = u.path.value;
537
+ return F.startsWith(t + ".") || F === t;
538
+ }).map((u) => d(u))), o = () => r.fields.value.filter((u) => {
539
+ const F = u.path.value;
540
+ return F.startsWith(t + ".") || F === t;
541
+ }), p = m(() => o().some((u) => u.dirty.value)), l = m(() => o().some((u) => u.touched.value)), i = m(() => r.isValid.value), v = m(() => r.isValidated.value), A = m(() => me(f(r.errors), t)), M = {
543
542
  data: s,
544
543
  fields: c,
545
544
  initialData: n,
546
- defineField: v,
547
- getField: p,
548
- isDirty: h,
545
+ defineField: h,
546
+ getField: V,
547
+ isDirty: p,
549
548
  isTouched: l,
550
- isValid: o,
551
- isValidated: m,
552
- errors: M,
549
+ isValid: i,
550
+ isValidated: v,
551
+ errors: A,
553
552
  defineValidator: (u) => {
554
- const y = O(u) ? u : x(u), w = V(
555
- () => new Ae(t, d(y))
553
+ const F = x(u) ? u : O(u), w = m(
554
+ () => new ke(t, f(F))
556
555
  );
557
- return r.defineValidator(w), y;
556
+ return r.defineValidator(w), F;
558
557
  },
559
- reset: () => i().forEach((u) => u.reset()),
558
+ reset: () => o().forEach((u) => u.reset()),
560
559
  validateForm: () => r.validateForm(),
561
- getSubForm: (u, y) => {
562
- const w = b(t, u);
560
+ getSubForm: (u, F) => {
561
+ const w = I(t, u);
563
562
  return r.getSubForm(
564
563
  w,
565
- y
564
+ F
566
565
  );
567
566
  },
568
- submitHandler: (u) => L($, e ?? {})(u),
569
- useFieldArray: (u, y) => G($, u, y)
567
+ submitHandler: (u) => L(M, e ?? {})(u),
568
+ useFieldArray: (u, F) => G(M, u, F)
570
569
  };
571
- return $;
570
+ return M;
572
571
  }
573
- function Oe(r) {
574
- const t = V(() => g(r.initialData)), e = J(g(t)), a = A({
572
+ function xe(r) {
573
+ const t = m(() => g(r.initialData)), e = J(g(t)), a = k({
575
574
  initialData: t,
576
575
  data: e
577
576
  });
@@ -582,29 +581,29 @@ function Oe(r) {
582
581
  },
583
582
  { flush: "sync" }
584
583
  );
585
- const s = ke(a, r), n = Ee(a, s, {
584
+ const s = be(a, r), n = Ee(a, s, {
586
585
  keepValuesOnUnmount: r.keepValuesOnUnmount,
587
586
  onBlur: async (c) => {
588
- d(r.validationStrategy) === "onTouch" && s.validateField(c);
587
+ f(r.validationStrategy) === "onTouch" && s.validateField(c);
589
588
  }
590
- }), f = we(n), p = () => {
589
+ }), d = we(n), V = () => {
591
590
  e.value = g(t), s.reset();
592
591
  for (const c of n.fields.value)
593
592
  c.reset();
594
593
  };
595
- d(r.validationStrategy) === "onFormOpen" && s.validateForm();
596
- const v = {
594
+ f(r.validationStrategy) === "onFormOpen" && s.validateForm();
595
+ const h = {
597
596
  ...n,
598
597
  ...s,
599
- ...f,
600
- reset: p,
601
- initialData: U(a, "initialData"),
602
- data: U(a, "data"),
603
- submitHandler: (c) => L(v, r)(c),
604
- getSubForm: (c, i) => Me(v, c, r),
605
- useFieldArray: (c, i) => G(v, c, i)
598
+ ...d,
599
+ reset: V,
600
+ initialData: j(a, "initialData"),
601
+ data: j(a, "data"),
602
+ submitHandler: (c) => L(h, r)(c),
603
+ getSubForm: (c, o) => Ae(h, c, r),
604
+ useFieldArray: (c, o) => G(h, c, o)
606
605
  };
607
- return v;
606
+ return h;
608
607
  }
609
608
  const Ce = /* @__PURE__ */ C({
610
609
  __name: "Field",
@@ -621,8 +620,8 @@ const Ce = /* @__PURE__ */ C({
621
620
  setup(r) {
622
621
  const t = r, e = t.form.defineField({
623
622
  path: t.path
624
- }), a = A(e);
625
- return (s, n) => k(s.$slots, "default", T(N(a)));
623
+ }), a = k(e);
624
+ return (s, n) => b(s.$slots, "default", T(N(a)));
626
625
  }
627
626
  }), Te = /* @__PURE__ */ C({
628
627
  inheritAttrs: !1,
@@ -640,22 +639,22 @@ const Ce = /* @__PURE__ */ C({
640
639
  form: r.form,
641
640
  path: r.path
642
641
  }, {
643
- default: B(({ errors: s, data: n, setData: f }) => [
642
+ default: U(({ errors: s, data: n, setData: d }) => [
644
643
  (H(), z(oe(r.component), le({ ...r.componentProps, ...t.$attrs }, {
645
644
  "model-value": n,
646
645
  errors: s,
647
646
  name: r.path,
648
- "onUpdate:modelValue": f
647
+ "onUpdate:modelValue": d
649
648
  }), ce({
650
- default: B(() => [
651
- k(t.$slots, "default")
649
+ default: U(() => [
650
+ b(t.$slots, "default")
652
651
  ]),
653
652
  _: 2
654
653
  }, [
655
- ue(t.$slots, (p, v) => ({
656
- name: v,
657
- fn: B((c) => [
658
- k(t.$slots, v, T(N(c ?? {})))
654
+ ue(t.$slots, (V, h) => ({
655
+ name: h,
656
+ fn: U((c) => [
657
+ b(t.$slots, h, T(N(c ?? {})))
659
658
  ])
660
659
  }))
661
660
  ]), 1040, ["model-value", "errors", "name", "onUpdate:modelValue"]))
@@ -671,13 +670,13 @@ const Ce = /* @__PURE__ */ C({
671
670
  path: {}
672
671
  },
673
672
  setup(r) {
674
- const t = r, e = V(() => t.form.getSubForm(t.path));
675
- return (a, s) => k(a.$slots, "default", T(N({ subform: e.value })));
673
+ const t = r, e = m(() => t.form.getSubForm(t.path));
674
+ return (a, s) => b(a.$slots, "default", T(N({ subform: e.value })));
676
675
  }
677
676
  });
678
677
  export {
679
678
  Ce as Field,
680
679
  Te as FormFieldWrapper,
681
680
  Ne as FormPart,
682
- Oe as useForm
681
+ xe as useForm
683
682
  };
@@ -1,5 +1,5 @@
1
1
  import { Awaitable } from '@vueuse/core';
2
- import { Ref } from 'vue';
2
+ import { Ref, ShallowRef } from 'vue';
3
3
  import { DefineFieldOptions } from '../composables/useFieldRegistry';
4
4
  import { SubformOptions } from '../composables/useSubform';
5
5
  import { ValidatorOptions } from '../composables/useValidation';
@@ -10,16 +10,16 @@ export type HashFn<H, I> = (item: I) => H;
10
10
  export interface FieldArrayOptions<Item> {
11
11
  hashFn?: HashFn<unknown, Item>;
12
12
  }
13
- export interface FieldArray<Item> {
14
- fields: Ref<{
15
- id: string;
16
- item: Item;
17
- }[]>;
18
- push: (item: Item) => void;
19
- remove: (item: Item) => void;
20
- removeByIndex: (index: number) => void;
21
- errors: Ref<ValidationErrors>;
22
- dirty: Ref<boolean>;
13
+ export interface FieldItem<Item, Path extends string> {
14
+ id: string;
15
+ item: Item;
16
+ path: `${Path}.${number}`;
17
+ }
18
+ export interface FieldArray<Item, Path extends string> {
19
+ items: ShallowRef<FieldItem<Item, Path>[]>;
20
+ push: (item: Item) => FieldItem<Item, Path>;
21
+ remove: (id: string) => void;
22
+ field: FormField<Item[], Path>;
23
23
  }
24
24
  export interface FormField<T, P extends string> {
25
25
  data: Ref<T>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teamnovu/kit-vue-forms",
3
- "version": "0.1.22",
3
+ "version": "0.1.23",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -1,9 +1,11 @@
1
- import { shallowRef, unref, watch } from 'vue'
1
+ import { shallowRef, watch } from 'vue'
2
2
  import type {
3
3
  FieldArray,
4
4
  FieldArrayOptions,
5
+ FieldItem,
5
6
  Form,
6
7
  FormDataDefault,
8
+ FormField,
7
9
  HashFn,
8
10
  } from '../types/form'
9
11
  import type { Paths, PickProps } from '../types/util'
@@ -49,13 +51,15 @@ export class HashStore<T, Item = unknown> {
49
51
  }
50
52
  }
51
53
 
52
- function mapIds<Item>(
53
- hashStore: HashStore<string[], Item>,
54
+ function mapIds<Item, Path extends string>(
55
+ hashStore: HashStore<string[],
56
+ Item>,
54
57
  items: Item[],
55
- ) {
58
+ basePath: Path,
59
+ ): FieldItem<Item, Path>[] {
56
60
  const mappedIds = new Set<string>()
57
61
 
58
- return items.map((item) => {
62
+ return items.map((item, i) => {
59
63
  const storeIds = [...(hashStore.get(item) ?? [])]
60
64
 
61
65
  // Remove all used ids
@@ -70,6 +74,7 @@ function mapIds<Item>(
70
74
  return {
71
75
  id: matchingId,
72
76
  item,
77
+ path: `${basePath}.${i}`,
73
78
  }
74
79
  }
75
80
 
@@ -82,6 +87,7 @@ function mapIds<Item>(
82
87
  return {
83
88
  id: newId,
84
89
  item,
90
+ path: `${basePath}.${i}`,
85
91
  }
86
92
  })
87
93
  }
@@ -90,25 +96,28 @@ export function useFieldArray<T extends FormDataDefault, K extends Paths<T>>(
90
96
  form: Form<T>,
91
97
  path: PickProps<T, K> extends unknown[] ? K : never,
92
98
  options?: FieldArrayOptions<PickProps<T, K> extends (infer U)[] ? U : never>,
93
- ): FieldArray<PickProps<T, K> extends (infer U)[] ? U : never> {
99
+ ): FieldArray<PickProps<T, K> extends (infer U)[] ? U : never, typeof path> {
94
100
  type Items = PickProps<T, K>
95
101
  type Item = Items extends (infer U)[] ? U : never
96
102
  type Id = string
103
+ type Path = typeof path
97
104
  type Field = {
98
105
  id: Id
99
106
  item: Item
107
+ path: `${Path}.${number}`
100
108
  }
101
109
 
102
110
  const hashStore = new HashStore<string[], Item>(options?.hashFn)
103
111
 
104
- const arrayField = form.getField(path)
112
+ // We only cast to unknown because we know that the constriant holds true
113
+ const arrayField = form.getField(path) as unknown as FormField<Item[], Path>
105
114
 
106
- const fields = shallowRef<Field[]>([])
115
+ const items = shallowRef<Field[]>([])
107
116
 
108
117
  watch(
109
118
  arrayField.data,
110
119
  (newItems) => {
111
- fields.value = mapIds(hashStore, newItems) as Field[]
120
+ items.value = mapIds(hashStore, newItems, path) as Field[]
112
121
  },
113
122
  {
114
123
  immediate: true,
@@ -119,26 +128,31 @@ export function useFieldArray<T extends FormDataDefault, K extends Paths<T>>(
119
128
  const push = (item: Item) => {
120
129
  const current = (arrayField.data.value ?? []) as Item[]
121
130
  arrayField.setData([...current, item] as Items)
131
+
132
+ return items.value.at(-1)!
122
133
  }
123
134
 
124
- const remove = (value: Item) => {
125
- const current = (arrayField.data.value ?? []) as Item[]
126
- arrayField.setData(
127
- (current?.filter(item => item !== unref(value)) ?? []) as Items,
135
+ const remove = (id: Id) => {
136
+ const currentData = (arrayField.data.value ?? []) as Item[]
137
+ const currentItem = items.value.findIndex(
138
+ ({ id: itemId }) => itemId === id,
128
139
  )
129
- }
130
140
 
131
- const removeByIndex = (index: number) => {
132
- const current = (arrayField.data.value ?? []) as Item[]
133
- arrayField.setData((current?.filter((_, i) => i !== index) ?? []) as Items)
141
+ if (currentItem === -1) {
142
+ return
143
+ }
144
+
145
+ arrayField.setData(
146
+ currentData
147
+ .slice(0, currentItem)
148
+ .concat(currentData.slice(currentItem + 1)) as Items,
149
+ )
134
150
  }
135
151
 
136
152
  return {
137
- fields,
153
+ items,
138
154
  push,
139
155
  remove,
140
- removeByIndex,
141
- errors: arrayField.errors,
142
- dirty: arrayField.dirty,
156
+ field: arrayField,
143
157
  }
144
158
  }
package/src/types/form.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { Awaitable } from '@vueuse/core'
2
- import type { Ref } from 'vue'
2
+ import type { Ref, ShallowRef } from 'vue'
3
3
  import type { DefineFieldOptions } from '../composables/useFieldRegistry'
4
4
  import type { SubformOptions } from '../composables/useSubform'
5
5
  import type { ValidatorOptions } from '../composables/useValidation'
@@ -20,16 +20,17 @@ export interface FieldArrayOptions<Item> {
20
20
  hashFn?: HashFn<unknown, Item>
21
21
  }
22
22
 
23
- export interface FieldArray<Item> {
24
- fields: Ref<{
25
- id: string
26
- item: Item
27
- }[]>
28
- push: (item: Item) => void
29
- remove: (item: Item) => void
30
- removeByIndex: (index: number) => void
31
- errors: Ref<ValidationErrors>
32
- dirty: Ref<boolean>
23
+ export interface FieldItem<Item, Path extends string> {
24
+ id: string
25
+ item: Item
26
+ path: `${Path}.${number}`
27
+ }
28
+
29
+ export interface FieldArray<Item, Path extends string> {
30
+ items: ShallowRef<FieldItem<Item, Path>[]>
31
+ push: (item: Item) => FieldItem<Item, Path>
32
+ remove: (id: string) => void
33
+ field: FormField<Item[], Path>
33
34
  }
34
35
 
35
36
  export interface FormField<T, P extends string> {
@@ -70,121 +70,6 @@ describe('useFieldArray', () => {
70
70
  })
71
71
  })
72
72
 
73
- describe('Core Functionality', () => {
74
- it('should initialize with array data and generate IDs', () => {
75
- const form = useForm({
76
- initialData: {
77
- items: [
78
- {
79
- id: 1,
80
- name: 'Item 1',
81
- },
82
- {
83
- id: 2,
84
- name: 'Item 2',
85
- },
86
- ],
87
- },
88
- })
89
- const fieldArray = useFieldArray(form, 'items')
90
-
91
- expect(fieldArray.fields.value).toHaveLength(2)
92
- expect(fieldArray.fields.value[0]).toHaveProperty('id')
93
- expect(fieldArray.fields.value[0]).toHaveProperty('item')
94
- expect(fieldArray.fields.value[0].item).toEqual({
95
- id: 1,
96
- name: 'Item 1',
97
- })
98
- expect(typeof fieldArray.fields.value[0].id).toBe('string')
99
- expect(fieldArray.errors.value).toEqual([])
100
- expect(fieldArray.dirty.value).toBe(false)
101
- })
102
-
103
- it('should push new items to the array', async () => {
104
- const form = useForm({
105
- initialData: {
106
- items: [
107
- {
108
- id: 1,
109
- name: 'First',
110
- },
111
- ],
112
- },
113
- })
114
- const fieldArray = useFieldArray(form, 'items')
115
-
116
- expect(fieldArray.fields.value).toHaveLength(1)
117
-
118
- fieldArray.push({
119
- id: 2,
120
- name: 'Second',
121
- })
122
- await nextTick()
123
-
124
- expect(fieldArray.fields.value).toHaveLength(2)
125
- expect(fieldArray.fields.value[1].item).toEqual({
126
- id: 2,
127
- name: 'Second',
128
- })
129
- expect(fieldArray.dirty.value).toBe(true)
130
- })
131
-
132
- it('should remove item by reference', async () => {
133
- const form = useForm({
134
- initialData: {
135
- items: [
136
- {
137
- id: 1,
138
- name: 'Keep',
139
- },
140
- {
141
- id: 2,
142
- name: 'Remove',
143
- },
144
- ],
145
- },
146
- })
147
- const fieldArray = useFieldArray(form, 'items')
148
- const itemToRemove = fieldArray.fields.value[1].item
149
-
150
- fieldArray.remove(itemToRemove)
151
- await nextTick()
152
-
153
- expect(fieldArray.fields.value).toHaveLength(1)
154
- expect(fieldArray.fields.value[0].item.name).toBe('Keep')
155
- expect(fieldArray.dirty.value).toBe(true)
156
- })
157
-
158
- it('should remove item by index', async () => {
159
- const form = useForm({
160
- initialData: {
161
- items: [
162
- {
163
- id: 1,
164
- name: 'First',
165
- },
166
- {
167
- id: 2,
168
- name: 'Second',
169
- },
170
- {
171
- id: 3,
172
- name: 'Third',
173
- },
174
- ],
175
- },
176
- })
177
- const fieldArray = useFieldArray(form, 'items')
178
-
179
- fieldArray.removeByIndex(1)
180
- await nextTick()
181
-
182
- expect(fieldArray.fields.value).toHaveLength(2)
183
- expect(fieldArray.fields.value[0].item.name).toBe('First')
184
- expect(fieldArray.fields.value[1].item.name).toBe('Third')
185
- })
186
- })
187
-
188
73
  describe('ID Persistence', () => {
189
74
  it('should maintain IDs when items are reordered', async () => {
190
75
  const form = useForm({
@@ -210,9 +95,9 @@ describe('useFieldArray', () => {
210
95
  })
211
96
 
212
97
  // Capture initial IDs
213
- const id1 = fieldArray.fields.value[0].id
214
- const id2 = fieldArray.fields.value[1].id
215
- const id3 = fieldArray.fields.value[2].id
98
+ const id1 = fieldArray.items.value[0].id
99
+ const id2 = fieldArray.items.value[1].id
100
+ const id3 = fieldArray.items.value[2].id
216
101
 
217
102
  // Reverse the array
218
103
  const arrayField = form.getField('items')
@@ -220,12 +105,15 @@ describe('useFieldArray', () => {
220
105
  await nextTick()
221
106
 
222
107
  // Verify order changed but IDs followed the items
223
- expect(fieldArray.fields.value[0].item.name).toBe('Third')
224
- expect(fieldArray.fields.value[0].id).toBe(id3)
225
- expect(fieldArray.fields.value[1].item.name).toBe('Second')
226
- expect(fieldArray.fields.value[1].id).toBe(id2)
227
- expect(fieldArray.fields.value[2].item.name).toBe('First')
228
- expect(fieldArray.fields.value[2].id).toBe(id1)
108
+ expect(fieldArray.items.value[0].item.name).toBe('Third')
109
+ expect(fieldArray.items.value[0].id).toBe(id3)
110
+ expect(fieldArray.items.value[0].path).toBe('items.0')
111
+ expect(fieldArray.items.value[1].item.name).toBe('Second')
112
+ expect(fieldArray.items.value[1].id).toBe(id2)
113
+ expect(fieldArray.items.value[1].path).toBe('items.1')
114
+ expect(fieldArray.items.value[2].item.name).toBe('First')
115
+ expect(fieldArray.items.value[2].id).toBe(id1)
116
+ expect(fieldArray.items.value[2].path).toBe('items.2')
229
117
  })
230
118
 
231
119
  it('should maintain IDs based on custom hash function', async () => {
@@ -249,8 +137,8 @@ describe('useFieldArray', () => {
249
137
  hashFn: (item: { sku: string }) => item.sku,
250
138
  })
251
139
 
252
- const idABC = fieldArray.fields.value[0].id
253
- const idDEF = fieldArray.fields.value[1].id
140
+ const idABC = fieldArray.items.value[0].id
141
+ const idDEF = fieldArray.items.value[1].id
254
142
 
255
143
  // Update price and swap order
256
144
  const arrayField = form.getField('products')
@@ -269,8 +157,8 @@ describe('useFieldArray', () => {
269
157
  await nextTick()
270
158
 
271
159
  // IDs should persist because SKUs didn't change
272
- expect(fieldArray.fields.value[0].id).toBe(idDEF)
273
- expect(fieldArray.fields.value[1].id).toBe(idABC)
160
+ expect(fieldArray.items.value[0].id).toBe(idDEF)
161
+ expect(fieldArray.items.value[1].id).toBe(idABC)
274
162
 
275
163
  // Change SKU - should get new ID
276
164
  arrayField.setData([
@@ -287,8 +175,8 @@ describe('useFieldArray', () => {
287
175
  ])
288
176
  await nextTick()
289
177
 
290
- expect(fieldArray.fields.value[0].id).not.toBe(idABC)
291
- expect(fieldArray.fields.value[1].id).toBe(idDEF)
178
+ expect(fieldArray.items.value[0].id).not.toBe(idABC)
179
+ expect(fieldArray.items.value[1].id).toBe(idDEF)
292
180
  })
293
181
 
294
182
  it('should assign IDs in order for items with same hash', async () => {
@@ -319,7 +207,7 @@ describe('useFieldArray', () => {
319
207
  })
320
208
 
321
209
  // All items get unique IDs despite same hash
322
- const [id1, id2, id3] = fieldArray.fields.value.map(f => f.id)
210
+ const [id1, id2, id3] = fieldArray.items.value.map(f => f.id)
323
211
  expect(new Set([id1, id2, id3]).size).toBe(3)
324
212
 
325
213
  // Reorder: move last item to first position
@@ -342,40 +230,14 @@ describe('useFieldArray', () => {
342
230
 
343
231
  // IDs are assigned in order from stored list, NOT following items
344
232
  // This is expected behavior with hash collisions
345
- expect(fieldArray.fields.value[0].id).toBe(id1) // svelte gets id1 (was vue's)
346
- expect(fieldArray.fields.value[1].id).toBe(id2) // vue gets id2 (was react's)
347
- expect(fieldArray.fields.value[2].id).toBe(id3) // react gets id3 (was svelte's)
233
+ expect(fieldArray.items.value[0].id).toBe(id1) // svelte gets id1 (was vue's)
234
+ expect(fieldArray.items.value[1].id).toBe(id2) // vue gets id2 (was react's)
235
+ expect(fieldArray.items.value[2].id).toBe(id3) // react gets id3 (was svelte's)
348
236
 
349
237
  // The values confirm the reorder happened
350
- expect(fieldArray.fields.value[0].item.value).toBe('svelte')
351
- expect(fieldArray.fields.value[1].item.value).toBe('vue')
352
- expect(fieldArray.fields.value[2].item.value).toBe('react')
353
- })
354
- })
355
-
356
- describe('Form Integration', () => {
357
- it('should track dirty state correctly', async () => {
358
- const form = useForm({
359
- initialData: { items: [{ name: 'Item' }] },
360
- })
361
- const fieldArray = useFieldArray(form, 'items')
362
-
363
- expect(form.isDirty.value).toBe(false)
364
- expect(fieldArray.dirty.value).toBe(false)
365
-
366
- // Make a change
367
- fieldArray.push({ name: 'New Item' })
368
- await nextTick()
369
-
370
- expect(form.isDirty.value).toBe(true)
371
- expect(fieldArray.dirty.value).toBe(true)
372
-
373
- // Reset form
374
- form.reset()
375
- await nextTick()
376
-
377
- expect(form.isDirty.value).toBe(false)
378
- expect(fieldArray.dirty.value).toBe(false)
238
+ expect(fieldArray.items.value[0].item.value).toBe('svelte')
239
+ expect(fieldArray.items.value[1].item.value).toBe('vue')
240
+ expect(fieldArray.items.value[2].item.value).toBe('react')
379
241
  })
380
242
  })
381
243
  })