@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.
- package/dist/composables/useFieldRegistry.d.ts +1 -1
- package/dist/index.mjs +155 -169
- package/package.json +1 -1
- package/src/composables/useFieldRegistry.ts +13 -10
- package/src/composables/useForm.ts +7 -2
- package/tests/integration.test.ts +1 -1
- package/tests/nestedPath.test.ts +3 -5
- package/tests/useForm.test.ts +25 -7
|
@@ -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>) =>
|
|
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
|
|
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
|
-
|
|
7
|
-
|
|
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
|
|
14
|
+
function w(e, r) {
|
|
14
15
|
return (Array.isArray(r) ? r : N(r)).reduce(
|
|
15
|
-
(
|
|
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
|
|
21
|
-
if (
|
|
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
|
|
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[
|
|
29
|
+
n[a] = t;
|
|
29
30
|
}
|
|
30
|
-
const
|
|
31
|
+
const z = (e, r) => f({
|
|
31
32
|
get() {
|
|
32
|
-
return
|
|
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
|
|
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}.`,
|
|
45
|
-
Object.entries(e.propertyErrors).filter(([
|
|
46
|
-
([
|
|
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:
|
|
53
|
+
propertyErrors: s
|
|
53
54
|
};
|
|
54
55
|
}
|
|
55
|
-
function q() {
|
|
56
|
-
|
|
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:
|
|
60
|
+
initialValue: f(() => Object.freeze(y(e.initialValue))),
|
|
82
61
|
errors: u(e.errors) || [],
|
|
83
62
|
touched: !1
|
|
84
63
|
});
|
|
85
|
-
|
|
86
|
-
r.errors =
|
|
64
|
+
F(() => u(e.errors), (d) => {
|
|
65
|
+
r.errors = d || [];
|
|
87
66
|
});
|
|
88
|
-
const t =
|
|
89
|
-
r.value =
|
|
90
|
-
},
|
|
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 =
|
|
95
|
-
}, v = (
|
|
96
|
-
r.errors =
|
|
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 =
|
|
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:
|
|
108
|
-
onBlur:
|
|
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
|
|
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:
|
|
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
|
|
136
|
-
const r =
|
|
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
|
|
124
|
+
function X(e) {
|
|
143
125
|
return e.filter(
|
|
144
|
-
(r, t,
|
|
126
|
+
(r, t, s) => s.indexOf(r) === t
|
|
145
127
|
);
|
|
146
128
|
}
|
|
147
|
-
function
|
|
129
|
+
function C(...e) {
|
|
148
130
|
return e.slice(1).reduce((r, t) => {
|
|
149
131
|
if (!r && !t)
|
|
150
132
|
return;
|
|
151
|
-
const
|
|
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 (!
|
|
136
|
+
if (!s)
|
|
155
137
|
return r;
|
|
156
|
-
const
|
|
157
|
-
return
|
|
138
|
+
const a = (r ?? []).concat(t);
|
|
139
|
+
return X(a);
|
|
158
140
|
}, e[0]);
|
|
159
141
|
}
|
|
160
|
-
function
|
|
161
|
-
return e.map((t) => Object.keys(t)).flat().reduce((t,
|
|
162
|
-
const
|
|
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
|
-
[
|
|
147
|
+
[s]: C(...a)
|
|
166
148
|
};
|
|
167
149
|
}, {});
|
|
168
150
|
}
|
|
169
|
-
function
|
|
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,
|
|
178
|
-
general:
|
|
179
|
-
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
|
|
185
|
-
var
|
|
186
|
-
const r = (((
|
|
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
|
|
190
|
-
const r = e.issues.filter((
|
|
191
|
-
const n =
|
|
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
|
-
...
|
|
194
|
-
[n]: [...
|
|
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
|
|
184
|
+
const p = {
|
|
203
185
|
isValid: !0,
|
|
204
186
|
errors: {
|
|
205
187
|
general: [],
|
|
206
188
|
propertyErrors: {}
|
|
207
189
|
}
|
|
208
190
|
};
|
|
209
|
-
class
|
|
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
|
|
197
|
+
return p;
|
|
216
198
|
const t = await this.schema.safeParseAsync(r);
|
|
217
199
|
if (t.success)
|
|
218
|
-
return
|
|
219
|
-
const
|
|
200
|
+
return p;
|
|
201
|
+
const s = rr(t.error);
|
|
220
202
|
return {
|
|
221
203
|
isValid: !1,
|
|
222
204
|
errors: {
|
|
223
|
-
general:
|
|
224
|
-
propertyErrors:
|
|
205
|
+
general: s.general ?? [],
|
|
206
|
+
propertyErrors: s.propertyErrors ?? {}
|
|
225
207
|
}
|
|
226
208
|
};
|
|
227
209
|
}
|
|
228
210
|
}
|
|
229
|
-
class
|
|
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
|
|
217
|
+
return p;
|
|
236
218
|
try {
|
|
237
219
|
const t = await this.validateFn(r);
|
|
238
|
-
return t.isValid ?
|
|
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
|
|
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,
|
|
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 &&
|
|
263
|
-
errors:
|
|
244
|
+
isValid: t.isValid && s.isValid,
|
|
245
|
+
errors: P(t.errors, s.errors)
|
|
264
246
|
};
|
|
265
247
|
}
|
|
266
248
|
}
|
|
267
|
-
function
|
|
268
|
-
return
|
|
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
|
|
274
|
-
const t =
|
|
275
|
-
validators:
|
|
255
|
+
function ar(e, r) {
|
|
256
|
+
const t = m({
|
|
257
|
+
validators: A([b(r)]),
|
|
276
258
|
isValidated: !1,
|
|
277
|
-
errors: u(r.errors) ??
|
|
259
|
+
errors: u(r.errors) ?? p.errors
|
|
278
260
|
});
|
|
279
|
-
|
|
280
|
-
const l = await
|
|
261
|
+
F(() => u(r.errors), async () => {
|
|
262
|
+
const l = await a();
|
|
281
263
|
n(l.errors);
|
|
282
|
-
}, { immediate: !0 }),
|
|
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
|
|
269
|
+
const c = await a();
|
|
288
270
|
t.errors = c.errors;
|
|
289
271
|
} else
|
|
290
|
-
t.errors =
|
|
272
|
+
t.errors = p.errors;
|
|
291
273
|
},
|
|
292
274
|
{ immediate: !0 }
|
|
293
|
-
),
|
|
275
|
+
), F(() => e.data, () => {
|
|
294
276
|
t.isValidated && o();
|
|
295
277
|
});
|
|
296
|
-
const
|
|
297
|
-
const c = _(l) ? l :
|
|
298
|
-
return t.validators.push(c),
|
|
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
|
-
(
|
|
282
|
+
(d) => d !== c
|
|
301
283
|
);
|
|
302
284
|
}), c;
|
|
303
285
|
};
|
|
304
|
-
async function
|
|
286
|
+
async function a() {
|
|
305
287
|
const l = await Promise.all(
|
|
306
|
-
t.validators.filter((
|
|
307
|
-
), c = l.every((
|
|
308
|
-
let { errors:
|
|
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
|
|
311
|
-
|
|
292
|
+
const V = l.map((R) => R.errors);
|
|
293
|
+
d = P(...V);
|
|
312
294
|
}
|
|
313
295
|
return {
|
|
314
|
-
errors:
|
|
296
|
+
errors: d,
|
|
315
297
|
isValid: c
|
|
316
298
|
};
|
|
317
299
|
}
|
|
318
300
|
const n = (l) => {
|
|
319
|
-
t.errors =
|
|
301
|
+
t.errors = P(u(r.errors) ?? p.errors, l);
|
|
320
302
|
}, o = async () => {
|
|
321
|
-
const l = await
|
|
303
|
+
const l = await a();
|
|
322
304
|
return n(l.errors), t.isValidated = !0, {
|
|
323
|
-
isValid: !
|
|
305
|
+
isValid: !j(l.errors),
|
|
324
306
|
errors: t.errors
|
|
325
307
|
};
|
|
326
|
-
}, v =
|
|
308
|
+
}, v = f(() => !j(t.errors));
|
|
327
309
|
return {
|
|
328
|
-
...
|
|
310
|
+
...O(t),
|
|
329
311
|
validateForm: o,
|
|
330
|
-
defineValidator:
|
|
312
|
+
defineValidator: s,
|
|
331
313
|
isValid: v
|
|
332
314
|
};
|
|
333
315
|
}
|
|
334
|
-
class
|
|
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 =
|
|
321
|
+
const t = w(r, this.path);
|
|
340
322
|
if (!this.validator)
|
|
341
|
-
return
|
|
342
|
-
const
|
|
323
|
+
return p;
|
|
324
|
+
const s = await this.validator.validate(t);
|
|
343
325
|
return {
|
|
344
|
-
isValid:
|
|
326
|
+
isValid: s.isValid,
|
|
345
327
|
errors: {
|
|
346
|
-
general:
|
|
347
|
-
propertyErrors:
|
|
348
|
-
Object.entries(
|
|
349
|
-
|
|
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
|
|
358
|
-
const
|
|
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:
|
|
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 =
|
|
347
|
+
const h = E(r, i), g = e.getField(h);
|
|
366
348
|
return g ? n(g) : {};
|
|
367
349
|
}, v = (i) => {
|
|
368
|
-
const h =
|
|
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
|
-
}),
|
|
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:
|
|
382
|
-
initialData:
|
|
363
|
+
data: s,
|
|
364
|
+
initialData: a,
|
|
383
365
|
defineField: v,
|
|
384
366
|
getField: o,
|
|
385
367
|
getFields: l,
|
|
386
|
-
isDirty:
|
|
387
|
-
isTouched:
|
|
388
|
-
isValid:
|
|
389
|
-
isValidated:
|
|
390
|
-
errors:
|
|
368
|
+
isDirty: d,
|
|
369
|
+
isTouched: V,
|
|
370
|
+
isValid: R,
|
|
371
|
+
isValidated: M,
|
|
372
|
+
errors: $,
|
|
391
373
|
defineValidator: (i) => {
|
|
392
|
-
const h = _(i) ? i :
|
|
393
|
-
() => new
|
|
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 =
|
|
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
|
|
409
|
-
const r =
|
|
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
|
-
})
|
|
413
|
-
|
|
414
|
-
|
|
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(
|
|
418
|
-
return
|
|
403
|
+
function l(d, V) {
|
|
404
|
+
return nr(c, d);
|
|
419
405
|
}
|
|
420
406
|
const c = {
|
|
421
|
-
...
|
|
407
|
+
...a,
|
|
422
408
|
...n,
|
|
423
409
|
...o,
|
|
424
410
|
reset: v,
|
|
425
411
|
getSubForm: l,
|
|
426
|
-
initialData:
|
|
427
|
-
data:
|
|
412
|
+
initialData: D(s, "initialData"),
|
|
413
|
+
data: D(s, "data")
|
|
428
414
|
};
|
|
429
415
|
return c;
|
|
430
416
|
}
|
|
431
|
-
const
|
|
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 (
|
|
430
|
+
return (s, a) => G(s.$slots, "default", L(U(m(u(t)))));
|
|
445
431
|
}
|
|
446
432
|
});
|
|
447
433
|
export {
|
|
448
|
-
|
|
449
|
-
|
|
434
|
+
pr as Field,
|
|
435
|
+
Vr as useForm
|
|
450
436
|
};
|
package/package.json
CHANGED
|
@@ -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 (!
|
|
31
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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)
|
package/tests/nestedPath.test.ts
CHANGED
|
@@ -540,16 +540,14 @@ describe('Nested Path Handling', () => {
|
|
|
540
540
|
})
|
|
541
541
|
|
|
542
542
|
describe('Performance and Memory', () => {
|
|
543
|
-
it('should
|
|
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
|
|
550
|
-
expect(field1).
|
|
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', () => {
|
package/tests/useForm.test.ts
CHANGED
|
@@ -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: {
|