@teamnovu/kit-vue-forms 0.0.11 → 0.0.13

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.
@@ -13,7 +13,7 @@ export declare function useFieldRegistry<T extends FormDataDefault>(formState: F
13
13
  getField: <K extends Paths<T>>(path: K) => ResolvedFormField<T, K>;
14
14
  getFields: <TData extends T>() => FieldsTuple<TData>;
15
15
  registerField: <K extends Paths<T>>(field: ResolvedFormField<T, K>) => void;
16
- defineField: <K extends Paths<T>>(options: DefineFieldOptions<PickProps<T, K>, K>) => FormField<K extends `${infer TRoot}.${infer TRest}` ? TRoot extends string | number | symbol ? TRest extends string ? TRest extends infer T_1 ? T_1 extends TRest ? T_1 extends `${infer TRoot}.${infer TRest}` ? TRoot extends string | number | symbol ? TRest extends string ? TRest extends infer T_2 ? T_2 extends TRest ? T_2 extends `${infer TRoot}.${infer TRest}` ? TRoot extends string | number | symbol ? TRest extends string ? TRest extends infer T_3 ? T_3 extends TRest ? T_3 extends `${infer TRoot}.${infer TRest}` ? TRoot extends string | number | symbol ? TRest extends string ? TRest extends infer T_4 ? T_4 extends TRest ? T_4 extends `${infer TRoot}.${infer TRest}` ? TRoot extends string | number | symbol ? TRest extends string ? TRest extends infer T_5 ? T_5 extends TRest ? T_5 extends `${infer TRoot}.${infer TRest}` ? TRoot extends string | number | symbol ? TRest extends string ? TRest extends infer T_6 ? T_6 extends TRest ? T_6 extends `${infer TRoot}.${infer TRest}` ? TRoot extends string | number | symbol ? TRest extends string ? TRest extends infer T_7 ? T_7 extends TRest ? T_7 extends `${infer TRoot}.${infer TRest}` ? TRoot extends string | number | symbol ? TRest extends string ? TRest extends infer T_8 ? T_8 extends TRest ? T_8 extends `${infer TRoot}.${infer TRest}` ? TRoot extends string | number | symbol ? TRest extends string ? TRest extends infer T_9 ? T_9 extends TRest ? T_9 extends `${infer TRoot}.${infer TRest}` ? TRoot extends string | number | symbol ? TRest extends string ? TRest extends infer T_10 ? T_10 extends TRest ? T_10 extends `${infer TRoot}.${infer TRest}` ? TRoot extends string | number | symbol ? TRest extends string ? /*elided*/ any : never : TRoot extends `${number}` ? never : never : T_10 extends string | number | symbol ? Required<any>[T_10] : T_10 extends `${number}` ? never : never : never : never : never : TRoot extends `${number}` ? never : never : T_9 extends string | number | symbol ? Required<any>[T_9] : T_9 extends `${number}` ? never : never : never : never : never : TRoot extends `${number}` ? never : never : T_8 extends string | number | symbol ? Required<any>[T_8] : T_8 extends `${number}` ? never : never : never : never : never : TRoot extends `${number}` ? never : never : T_7 extends string | number | symbol ? Required<any>[T_7] : T_7 extends `${number}` ? never : never : never : never : never : TRoot extends `${number}` ? never : never : T_6 extends string | number | symbol ? Required<any>[T_6] : T_6 extends `${number}` ? never : never : never : never : never : TRoot extends `${number}` ? never : never : T_5 extends string | number | symbol ? Required<any>[T_5] : T_5 extends `${number}` ? never : never : never : never : never : TRoot extends `${number}` ? never : never : T_4 extends string | number | symbol ? Required<any>[T_4] : T_4 extends `${number}` ? never : never : never : never : never : TRoot extends `${number}` ? never : never : T_3 extends string | number | symbol ? Required<any>[T_3] : T_3 extends `${number}` ? never : never : never : never : never : TRoot extends `${number}` ? never : never : T_2 extends string | number | symbol ? Required<any>[T_2] : T_2 extends `${number}` ? never : never : never : never : never : TRoot extends `${number}` ? never : never : T_1 extends string | number | symbol ? Required<any>[T_1] : T_1 extends `${number}` ? never : never : never : never : never : TRoot extends `${number}` ? never : never : K extends string | number | symbol ? any : K extends `${number}` ? never : never, K>;
16
+ defineField: <K extends Paths<T>>(options: DefineFieldOptions<PickProps<T, K>, K>) => ResolvedFormField<T, K>;
17
17
  };
18
18
  export type FieldRegistry<T extends FormDataDefault> = ReturnType<typeof useFieldRegistry<T>>;
19
19
  export {};
package/dist/index.mjs CHANGED
@@ -1,102 +1,81 @@
1
1
  var x = Object.defineProperty;
2
2
  var K = (e, r, t) => r in e ? x(e, r, { enumerable: !0, configurable: !0, writable: !0, value: t }) : e[r] = t;
3
3
  var S = (e, r, t) => K(e, typeof r != "symbol" ? r + "" : r, t);
4
- import { toValue as W, toRaw as B, computed as d, unref as u, reactive as w, watch as E, toRefs as A, ref as y, toRef as P, isRef as _, getCurrentScope as I, onBeforeUnmount as J, defineComponent as T, renderSlot as G, normalizeProps as L, guardReactiveProps as U } from "vue";
4
+ import { toValue as W, toRaw as I, computed as f, unref as u, reactive as m, watch as F, toRefs as O, toRef as D, ref as A, isRef as _, getCurrentScope as J, onBeforeUnmount as T, defineComponent as B, renderSlot as G, normalizeProps as L, guardReactiveProps as U } from "vue";
5
5
  import "zod";
6
- function F(e) {
7
- const r = W(e), t = B(r);
6
+ import "@vueuse/core";
7
+ function y(e) {
8
+ const r = W(e), t = I(r);
8
9
  return structuredClone(t);
9
10
  }
10
11
  function N(e) {
11
12
  return e === "" ? [] : e.split(/\s*\.\s*/).filter(Boolean);
12
13
  }
13
- function R(e, r) {
14
+ function w(e, r) {
14
15
  return (Array.isArray(r) ? r : N(r)).reduce(
15
- (a, s) => a == null ? void 0 : a[s],
16
+ (s, a) => s == null ? void 0 : s[a],
16
17
  e
17
18
  );
18
19
  }
19
20
  function Z(e, r, t) {
20
- const a = Array.isArray(r) ? r : N(r);
21
- if (a.length === 0)
21
+ const s = Array.isArray(r) ? r : N(r);
22
+ if (s.length === 0)
22
23
  throw new Error("Path cannot be empty");
23
- const s = a.at(-1), n = a.slice(0, -1).reduce(
24
+ const a = s.at(-1), n = s.slice(0, -1).reduce(
24
25
  (o, v) => o[v],
25
26
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
27
  e
27
28
  );
28
- n[s] = t;
29
+ n[a] = t;
29
30
  }
30
- const $ = (e, r) => d({
31
+ const z = (e, r) => f({
31
32
  get() {
32
- return R(u(e), u(r));
33
+ return w(u(e), u(r));
33
34
  },
34
35
  set(t) {
35
36
  Z(u(e), u(r), t);
36
37
  }
37
38
  });
38
- function m(e, r) {
39
+ function E(e, r) {
39
40
  return !e && !r ? "" : !e && r ? r : !r && e ? e : `${e}.${r}`;
40
41
  }
41
42
  function k(e, r) {
42
43
  if (!r)
43
44
  return e;
44
- const t = `${r}.`, a = Object.fromEntries(
45
- Object.entries(e.propertyErrors).filter(([s]) => s.startsWith(t)).map(
46
- ([s, n]) => [s.slice(t.length), n]
45
+ const t = `${r}.`, s = Object.fromEntries(
46
+ Object.entries(e.propertyErrors).filter(([a]) => a.startsWith(t)).map(
47
+ ([a, n]) => [a.slice(t.length), n]
47
48
  )
48
49
  );
49
50
  return {
50
51
  general: e.general,
51
52
  // Keep general errors
52
- propertyErrors: a
53
+ propertyErrors: s
53
54
  };
54
55
  }
55
- function q() {
56
- return {
57
- setData: () => {
58
- },
59
- onBlur: () => {
60
- },
61
- onFocus: () => {
62
- },
63
- reset: () => {
64
- },
65
- setErrors: () => {
66
- },
67
- clearErrors: () => {
68
- },
69
- data: y(void 0),
70
- initialValue: y(void 0),
71
- path: y(""),
72
- errors: y([]),
73
- touched: y(!1),
74
- dirty: d(() => !1)
75
- };
76
- }
77
- function H(e) {
78
- const r = w({
56
+ function q(e) {
57
+ const r = m({
79
58
  value: e.value,
80
59
  path: e.path,
81
- initialValue: d(() => Object.freeze(F(e.initialValue))),
60
+ initialValue: f(() => Object.freeze(y(e.initialValue))),
82
61
  errors: u(e.errors) || [],
83
62
  touched: !1
84
63
  });
85
- E(() => u(e.errors), (f) => {
86
- r.errors = f || [];
64
+ F(() => u(e.errors), (d) => {
65
+ r.errors = d || [];
87
66
  });
88
- const t = d(() => JSON.stringify(r.value) !== JSON.stringify(r.initialValue)), a = (f) => {
89
- r.value = f;
90
- }, s = () => {
67
+ const t = f(() => JSON.stringify(r.value) !== JSON.stringify(r.initialValue)), s = (d) => {
68
+ r.value = d;
69
+ }, a = () => {
91
70
  r.touched = !0;
92
71
  }, n = () => {
93
72
  }, o = () => {
94
- r.value = F(r.initialValue), r.touched = !1, r.errors = [];
95
- }, v = (f) => {
96
- r.errors = f;
73
+ r.value = y(r.initialValue), r.touched = !1, r.errors = [];
74
+ }, v = (d) => {
75
+ r.errors = d;
97
76
  }, l = () => {
98
77
  r.errors = [];
99
- }, c = A(r);
78
+ }, c = O(r);
100
79
  return {
101
80
  data: c.value,
102
81
  path: c.path,
@@ -104,69 +83,72 @@ function H(e) {
104
83
  errors: c.errors,
105
84
  touched: c.touched,
106
85
  dirty: t,
107
- setData: a,
108
- onBlur: s,
86
+ setData: s,
87
+ onBlur: a,
109
88
  onFocus: n,
110
89
  reset: o,
111
90
  setErrors: v,
112
91
  clearErrors: l
113
92
  };
114
93
  }
115
- function Q(e) {
94
+ function H(e) {
116
95
  const r = {}, t = (o) => {
117
96
  const v = u(o.path);
118
97
  r[v] = o;
98
+ }, s = (o) => {
99
+ if (!r[o]) {
100
+ const v = q({
101
+ path: o,
102
+ value: z(D(e, "data"), o),
103
+ initialValue: f(() => w(e.initialData, o))
104
+ });
105
+ return t(v), v;
106
+ }
107
+ return r[o];
119
108
  };
120
109
  return {
121
110
  fields: r,
122
- getField: (o) => o in r ? r[o] : (console.warn(`Field with path "${o}" is not registered.`), q()),
111
+ getField: s,
123
112
  getFields: () => Object.values(r),
124
113
  registerField: t,
125
- defineField: (o) => {
126
- const v = H({
127
- ...o,
128
- value: $(P(e, "data"), o.path),
129
- initialValue: d(() => R(e.initialData, u(o.path)))
130
- });
131
- return t(v), v;
132
- }
114
+ defineField: (o) => s(o.path)
133
115
  };
134
116
  }
135
- function X(e) {
136
- const r = d(() => e.getFields().some((a) => u(a.dirty))), t = d(() => e.getFields().some((a) => u(a.touched)));
117
+ function Q(e) {
118
+ const r = f(() => e.getFields().some((s) => u(s.dirty))), t = f(() => e.getFields().some((s) => u(s.touched)));
137
119
  return {
138
120
  isDirty: r,
139
121
  isTouched: t
140
122
  };
141
123
  }
142
- function Y(e) {
124
+ function X(e) {
143
125
  return e.filter(
144
- (r, t, a) => a.indexOf(r) === t
126
+ (r, t, s) => s.indexOf(r) === t
145
127
  );
146
128
  }
147
- function z(...e) {
129
+ function C(...e) {
148
130
  return e.slice(1).reduce((r, t) => {
149
131
  if (!r && !t)
150
132
  return;
151
- const a = ((t == null ? void 0 : t.length) ?? 0) > 0;
133
+ const s = ((t == null ? void 0 : t.length) ?? 0) > 0;
152
134
  if (!r && ((t == null ? void 0 : t.length) ?? 0) > 0)
153
135
  return t;
154
- if (!a)
136
+ if (!s)
155
137
  return r;
156
- const s = (r ?? []).concat(t);
157
- return Y(s);
138
+ const a = (r ?? []).concat(t);
139
+ return X(a);
158
140
  }, e[0]);
159
141
  }
160
- function rr(...e) {
161
- return e.map((t) => Object.keys(t)).flat().reduce((t, a) => {
162
- const s = e.map((n) => n[a]).filter(Boolean);
142
+ function Y(...e) {
143
+ return e.map((t) => Object.keys(t)).flat().reduce((t, s) => {
144
+ const a = e.map((n) => n[s]).filter(Boolean);
163
145
  return {
164
146
  ...t,
165
- [a]: z(...s)
147
+ [s]: C(...a)
166
148
  };
167
149
  }, {});
168
150
  }
169
- function b(...e) {
151
+ function P(...e) {
170
152
  if (!e.length)
171
153
  return {
172
154
  general: [],
@@ -174,24 +156,24 @@ function b(...e) {
174
156
  };
175
157
  const r = e[0];
176
158
  return e.length === 1 ? r : e.slice(1).reduce(
177
- (t, a) => ({
178
- general: z(t.general, a.general),
179
- propertyErrors: rr(t.propertyErrors ?? {}, a.propertyErrors ?? {})
159
+ (t, s) => ({
160
+ general: C(t.general, s.general),
161
+ propertyErrors: Y(t.propertyErrors ?? {}, s.propertyErrors ?? {})
180
162
  }),
181
163
  r
182
164
  );
183
165
  }
184
- function O(e) {
185
- var a;
186
- const r = (((a = e.general) == null ? void 0 : a.length) ?? 0) > 0, t = Object.entries(e.propertyErrors).filter(([, s]) => s == null ? void 0 : s.length).length > 0;
166
+ function j(e) {
167
+ var s;
168
+ const r = (((s = e.general) == null ? void 0 : s.length) ?? 0) > 0, t = Object.entries(e.propertyErrors).filter(([, a]) => a == null ? void 0 : a.length).length > 0;
187
169
  return r || t;
188
170
  }
189
- function er(e) {
190
- const r = e.issues.filter((a) => a.path.length === 0).map((a) => a.message), t = e.issues.filter((a) => a.path.length > 0).reduce((a, s) => {
191
- const n = s.path.join(".");
171
+ function rr(e) {
172
+ const r = e.issues.filter((s) => s.path.length === 0).map((s) => s.message), t = e.issues.filter((s) => s.path.length > 0).reduce((s, a) => {
173
+ const n = a.path.join(".");
192
174
  return {
193
- ...a,
194
- [n]: [...a[n] ?? [], s.message]
175
+ ...s,
176
+ [n]: [...s[n] ?? [], a.message]
195
177
  };
196
178
  }, {});
197
179
  return {
@@ -199,43 +181,43 @@ function er(e) {
199
181
  propertyErrors: t
200
182
  };
201
183
  }
202
- const V = {
184
+ const p = {
203
185
  isValid: !0,
204
186
  errors: {
205
187
  general: [],
206
188
  propertyErrors: {}
207
189
  }
208
190
  };
209
- class tr {
191
+ class er {
210
192
  constructor(r) {
211
193
  this.schema = r;
212
194
  }
213
195
  async validate(r) {
214
196
  if (!this.schema)
215
- return V;
197
+ return p;
216
198
  const t = await this.schema.safeParseAsync(r);
217
199
  if (t.success)
218
- return V;
219
- const a = er(t.error);
200
+ return p;
201
+ const s = rr(t.error);
220
202
  return {
221
203
  isValid: !1,
222
204
  errors: {
223
- general: a.general ?? [],
224
- propertyErrors: a.propertyErrors ?? {}
205
+ general: s.general ?? [],
206
+ propertyErrors: s.propertyErrors ?? {}
225
207
  }
226
208
  };
227
209
  }
228
210
  }
229
- class ar {
211
+ class tr {
230
212
  constructor(r) {
231
213
  this.validateFn = r;
232
214
  }
233
215
  async validate(r) {
234
216
  if (!this.validateFn)
235
- return V;
217
+ return p;
236
218
  try {
237
219
  const t = await this.validateFn(r);
238
- return t.isValid ? V : t;
220
+ return t.isValid ? p : t;
239
221
  } catch (t) {
240
222
  return {
241
223
  isValid: !1,
@@ -251,102 +233,102 @@ class sr {
251
233
  constructor(r, t) {
252
234
  S(this, "schemaValidator");
253
235
  S(this, "functionValidator");
254
- this.schema = r, this.validateFn = t, this.schemaValidator = new tr(this.schema), this.functionValidator = new ar(this.validateFn);
236
+ this.schema = r, this.validateFn = t, this.schemaValidator = new er(this.schema), this.functionValidator = new tr(this.validateFn);
255
237
  }
256
238
  async validate(r) {
257
- const [t, a] = await Promise.all([
239
+ const [t, s] = await Promise.all([
258
240
  this.schemaValidator.validate(r),
259
241
  this.functionValidator.validate(r)
260
242
  ]);
261
243
  return {
262
- isValid: t.isValid && a.isValid,
263
- errors: b(t.errors, a.errors)
244
+ isValid: t.isValid && s.isValid,
245
+ errors: P(t.errors, s.errors)
264
246
  };
265
247
  }
266
248
  }
267
- function j(e) {
268
- return d(() => new sr(
249
+ function b(e) {
250
+ return f(() => new sr(
269
251
  u(e.schema),
270
252
  u(e.validateFn)
271
253
  ));
272
254
  }
273
- function ir(e, r) {
274
- const t = w({
275
- validators: y([j(r)]),
255
+ function ar(e, r) {
256
+ const t = m({
257
+ validators: A([b(r)]),
276
258
  isValidated: !1,
277
- errors: u(r.errors) ?? V.errors
259
+ errors: u(r.errors) ?? p.errors
278
260
  });
279
- E(() => u(r.errors), async () => {
280
- const l = await s();
261
+ F(() => u(r.errors), async () => {
262
+ const l = await a();
281
263
  n(l.errors);
282
- }, { immediate: !0 }), E(
264
+ }, { immediate: !0 }), F(
283
265
  [() => t.validators],
284
266
  async (l) => {
285
267
  if (t.isValidated)
286
268
  if (l) {
287
- const c = await s();
269
+ const c = await a();
288
270
  t.errors = c.errors;
289
271
  } else
290
- t.errors = V.errors;
272
+ t.errors = p.errors;
291
273
  },
292
274
  { immediate: !0 }
293
- ), E(() => e.data, () => {
275
+ ), F(() => e.data, () => {
294
276
  t.isValidated && o();
295
277
  });
296
- const a = (l) => {
297
- const c = _(l) ? l : j(l);
298
- return t.validators.push(c), I() && J(() => {
278
+ const s = (l) => {
279
+ const c = _(l) ? l : b(l);
280
+ return t.validators.push(c), J() && T(() => {
299
281
  t.validators = t.validators.filter(
300
- (f) => f !== c
282
+ (d) => d !== c
301
283
  );
302
284
  }), c;
303
285
  };
304
- async function s() {
286
+ async function a() {
305
287
  const l = await Promise.all(
306
- t.validators.filter((p) => u(p) !== void 0).map((p) => u(p).validate(e.data))
307
- ), c = l.every((p) => p.isValid);
308
- let { errors: f } = V;
288
+ t.validators.filter((V) => u(V) !== void 0).map((V) => u(V).validate(e.data))
289
+ ), c = l.every((V) => V.isValid);
290
+ let { errors: d } = p;
309
291
  if (!c) {
310
- const p = l.map((D) => D.errors);
311
- f = b(...p);
292
+ const V = l.map((R) => R.errors);
293
+ d = P(...V);
312
294
  }
313
295
  return {
314
- errors: f,
296
+ errors: d,
315
297
  isValid: c
316
298
  };
317
299
  }
318
300
  const n = (l) => {
319
- t.errors = b(u(r.errors) ?? V.errors, l);
301
+ t.errors = P(u(r.errors) ?? p.errors, l);
320
302
  }, o = async () => {
321
- const l = await s();
303
+ const l = await a();
322
304
  return n(l.errors), t.isValidated = !0, {
323
- isValid: !O(l.errors),
305
+ isValid: !j(l.errors),
324
306
  errors: t.errors
325
307
  };
326
- }, v = d(() => !O(t.errors));
308
+ }, v = f(() => !j(t.errors));
327
309
  return {
328
- ...A(t),
310
+ ...O(t),
329
311
  validateForm: o,
330
- defineValidator: a,
312
+ defineValidator: s,
331
313
  isValid: v
332
314
  };
333
315
  }
334
- class nr {
316
+ class ir {
335
317
  constructor(r, t) {
336
318
  this.path = r, this.validator = t;
337
319
  }
338
320
  async validate(r) {
339
- const t = R(r, this.path);
321
+ const t = w(r, this.path);
340
322
  if (!this.validator)
341
- return V;
342
- const a = await this.validator.validate(t);
323
+ return p;
324
+ const s = await this.validator.validate(t);
343
325
  return {
344
- isValid: a.isValid,
326
+ isValid: s.isValid,
345
327
  errors: {
346
- general: a.errors.general || [],
347
- propertyErrors: a.errors.propertyErrors ? Object.fromEntries(
348
- Object.entries(a.errors.propertyErrors).map(([s, n]) => [
349
- m(this.path, s),
328
+ general: s.errors.general || [],
329
+ propertyErrors: s.errors.propertyErrors ? Object.fromEntries(
330
+ Object.entries(s.errors.propertyErrors).map(([a, n]) => [
331
+ E(this.path, a),
350
332
  n
351
333
  ])
352
334
  ) : {}
@@ -354,18 +336,18 @@ class nr {
354
336
  };
355
337
  }
356
338
  }
357
- function or(e, r, t) {
358
- const a = $(e.data, r), s = d(() => R(e.initialData.value, r)), n = (i) => ({
339
+ function nr(e, r, t) {
340
+ const s = z(e.data, r), a = f(() => w(e.initialData.value, r)), n = (i) => ({
359
341
  ...i,
360
- path: d(() => u(i.path).replace(r + ".", "")),
342
+ path: f(() => u(i.path).replace(r + ".", "")),
361
343
  setData: (h) => {
362
344
  i.setData(h);
363
345
  }
364
346
  }), o = (i) => {
365
- const h = m(r, i), g = e.getField(h);
347
+ const h = E(r, i), g = e.getField(h);
366
348
  return g ? n(g) : {};
367
349
  }, v = (i) => {
368
- const h = m(r, i.path), g = e.defineField({
350
+ const h = E(r, i.path), g = e.defineField({
369
351
  ...i,
370
352
  path: h
371
353
  });
@@ -376,28 +358,28 @@ function or(e, r, t) {
376
358
  }).map((i) => n(i)), c = () => e.getFields().filter((i) => {
377
359
  const h = i.path.value;
378
360
  return h.startsWith(r + ".") || h === r;
379
- }), f = d(() => c().some((i) => i.dirty.value)), p = d(() => c().some((i) => i.touched.value)), D = d(() => e.isValid.value), C = d(() => e.isValidated.value), M = d(() => k(u(e.errors), r));
361
+ }), d = f(() => c().some((i) => i.dirty.value)), V = f(() => c().some((i) => i.touched.value)), R = f(() => e.isValid.value), M = f(() => e.isValidated.value), $ = f(() => k(u(e.errors), r));
380
362
  return {
381
- data: a,
382
- initialData: s,
363
+ data: s,
364
+ initialData: a,
383
365
  defineField: v,
384
366
  getField: o,
385
367
  getFields: l,
386
- isDirty: f,
387
- isTouched: p,
388
- isValid: D,
389
- isValidated: C,
390
- errors: M,
368
+ isDirty: d,
369
+ isTouched: V,
370
+ isValid: R,
371
+ isValidated: M,
372
+ errors: $,
391
373
  defineValidator: (i) => {
392
- const h = _(i) ? i : j(i), g = d(
393
- () => new nr(r, u(h))
374
+ const h = _(i) ? i : b(i), g = f(
375
+ () => new ir(r, u(h))
394
376
  );
395
377
  return e.defineValidator(g), h;
396
378
  },
397
379
  reset: () => c().forEach((i) => i.reset()),
398
380
  validateForm: () => e.validateForm(),
399
381
  getSubForm: (i, h) => {
400
- const g = m(r, i);
382
+ const g = E(r, i);
401
383
  return e.getSubForm(
402
384
  g,
403
385
  h
@@ -405,30 +387,34 @@ function or(e, r, t) {
405
387
  }
406
388
  };
407
389
  }
408
- function pr(e) {
409
- const r = d(() => Object.freeze(F(e.initialData))), t = y(F(r)), a = w({
390
+ function Vr(e) {
391
+ const r = f(() => Object.freeze(y(e.initialData))), t = A(y(r)), s = m({
410
392
  initialData: r,
411
393
  data: t
412
- }), s = Q(a), n = ir(a, e), o = X(s), v = () => {
413
- t.value = F(r), s.getFields().forEach(
414
- (f) => f.reset()
394
+ });
395
+ F(r, (d) => {
396
+ s.data = y(d);
397
+ });
398
+ const a = H(s), n = ar(s, e), o = Q(a), v = () => {
399
+ t.value = y(r), a.getFields().forEach(
400
+ (d) => d.reset()
415
401
  );
416
402
  };
417
- function l(f, p) {
418
- return or(c, f);
403
+ function l(d, V) {
404
+ return nr(c, d);
419
405
  }
420
406
  const c = {
421
- ...s,
407
+ ...a,
422
408
  ...n,
423
409
  ...o,
424
410
  reset: v,
425
411
  getSubForm: l,
426
- initialData: P(a, "initialData"),
427
- data: P(a, "data")
412
+ initialData: D(s, "initialData"),
413
+ data: D(s, "data")
428
414
  };
429
415
  return c;
430
416
  }
431
- const Vr = /* @__PURE__ */ T({
417
+ const pr = /* @__PURE__ */ B({
432
418
  __name: "Field",
433
419
  props: {
434
420
  form: {},
@@ -441,10 +427,10 @@ const Vr = /* @__PURE__ */ T({
441
427
  const r = e, t = r.form.defineField({
442
428
  path: r.path
443
429
  });
444
- return (a, s) => G(a.$slots, "default", L(U(w(u(t)))));
430
+ return (s, a) => G(s.$slots, "default", L(U(m(u(t)))));
445
431
  }
446
432
  });
447
433
  export {
448
- Vr as Field,
449
- pr as useForm
434
+ pr as Field,
435
+ Vr as useForm
450
436
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teamnovu/kit-vue-forms",
3
- "version": "0.0.11",
3
+ "version": "0.0.13",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "exports": {
@@ -27,10 +27,16 @@ export function useFieldRegistry<T extends FormDataDefault>(
27
27
  }
28
28
 
29
29
  const getField = <K extends Paths<T>>(path: K): ResolvedFormField<T, K> => {
30
- if (!(path in fields)) {
31
- console.warn(`Field with path "${path}" is not registered.`)
30
+ if (!fields[path]) {
31
+ const field = useField({
32
+ path,
33
+ value: getLens(toRef(formState, 'data'), path),
34
+ initialValue: computed(() => getNestedValue(formState.initialData, path)),
35
+ })
32
36
 
33
- return getEmptyField() as ResolvedFormField<T, K>
37
+ registerField(field)
38
+
39
+ return field
34
40
  }
35
41
 
36
42
  return fields[path] as ResolvedFormField<T, K>
@@ -40,14 +46,11 @@ export function useFieldRegistry<T extends FormDataDefault>(
40
46
  return Object.values(fields) as FieldsTuple<TData>
41
47
  }
42
48
 
43
- const defineField = <K extends Paths<T>>(options: DefineFieldOptions<PickProps<T, K>, K>) => {
44
- const field = useField({
45
- ...options,
46
- value: getLens(toRef(formState, 'data'), options.path),
47
- initialValue: computed(() => getNestedValue(formState.initialData, unref(options.path))),
48
- })
49
+ const defineField = <K extends Paths<T>>(options: DefineFieldOptions<PickProps<T, K>, K>): ResolvedFormField<T, K> => {
50
+ const field = getField(options.path)
49
51
 
50
- registerField(field)
52
+ // TODO: If more options are ever needed than only the path we have to update the field
53
+ // here with the new options
51
54
 
52
55
  return field
53
56
  }
@@ -1,4 +1,4 @@
1
- import { computed, reactive, ref, toRef, type MaybeRef, type MaybeRefOrGetter, type Ref } from 'vue'
1
+ import { computed, reactive, ref, toRef, watch, type MaybeRef, type MaybeRefOrGetter, type Ref } from 'vue'
2
2
  import type { AnyField, Form, FormDataDefault } from '../types/form'
3
3
  import type { EntityPaths, PickEntity } from '../types/util'
4
4
  import type { ValidationStrategy } from '../types/validation'
@@ -7,6 +7,7 @@ import { useFieldRegistry } from './useFieldRegistry'
7
7
  import { useFormState } from './useFormState'
8
8
  import { createSubformInterface, type SubformOptions } from './useSubform'
9
9
  import { useValidation, type ValidationOptions } from './useValidation'
10
+ import { syncRef } from '@vueuse/core'
10
11
 
11
12
  // TODO @Elias implement validation strategy handling
12
13
 
@@ -22,10 +23,14 @@ export function useForm<T extends FormDataDefault>(options: UseFormOptions<T>) {
22
23
  const data = ref<T>(cloneRefValue(initialData)) as Ref<T>
23
24
 
24
25
  const state = reactive({
25
- initialData: initialData,
26
+ initialData,
26
27
  data,
27
28
  })
28
29
 
30
+ watch(initialData, (newValue) => {
31
+ state.data = cloneRefValue(newValue)
32
+ })
33
+
29
34
  const fields = useFieldRegistry(state)
30
35
  const validationState = useValidation(state, options)
31
36
  const formState = useFormState(fields)
@@ -195,6 +195,6 @@ describe('Integration Tests', () => {
195
195
 
196
196
  // Try to get non-existent field
197
197
  const nonExistentField = form.getField('nonexistent')
198
- expect(nonExistentField).toBeUndefined()
198
+ expect(nonExistentField).toBeDefined()
199
199
  })
200
200
  })
@@ -540,16 +540,14 @@ describe('Nested Path Handling', () => {
540
540
  })
541
541
 
542
542
  describe('Performance and Memory', () => {
543
- it('should replace field when defining same path twice', () => {
543
+ it('should return the same field when defining same path twice', () => {
544
544
  const form = useForm({ initialData })
545
545
 
546
546
  const field1 = form.defineField({ path: 'user.name' })
547
547
  const field2 = form.defineField({ path: 'user.name' })
548
548
 
549
- // Fields are not the same object, but second field replaces the first
550
- expect(field1).not.toBe(field2)
551
- expect(form.getField('user.name')).toBe(field2)
552
- expect(form.getFields().length).toBe(1)
549
+ // Fields are the same object
550
+ expect(field1).toBe(field2)
553
551
  })
554
552
 
555
553
  it('should handle large numbers of nested fields', () => {
@@ -40,6 +40,31 @@ describe('useForm', () => {
40
40
  })
41
41
  })
42
42
 
43
+ it('should reinitialize form with new initial data', async () => {
44
+ const initialData = ref({
45
+ name: 'John',
46
+ age: 30,
47
+ })
48
+ const form = useForm({ initialData })
49
+
50
+ expect(form.data.value).toEqual({
51
+ name: 'John',
52
+ age: 30,
53
+ })
54
+
55
+ // Update reactive initial data
56
+ initialData.value = {
57
+ name: 'Jane',
58
+ age: 25,
59
+ }
60
+ await nextTick()
61
+
62
+ expect(form.data.value).toEqual({
63
+ name: 'Jane',
64
+ age: 25,
65
+ })
66
+ })
67
+
43
68
  it('should have initial state values', () => {
44
69
  const form = useForm({ initialData: { name: 'John' } })
45
70
 
@@ -81,13 +106,6 @@ describe('useForm', () => {
81
106
  expect(retrievedField).toBe(nameField)
82
107
  })
83
108
 
84
- it('should return undefined for non-existent fields', () => {
85
- const form = useForm({ initialData: { name: 'John' } })
86
-
87
- const field = form.getField('nonexistent')
88
- expect(field).toBeUndefined()
89
- })
90
-
91
109
  it('should handle nested object initial data', () => {
92
110
  const initialData = {
93
111
  user: {