@teamnovu/kit-vue-forms 0.1.12 → 0.1.14
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/useFormData.d.ts +5 -0
- package/dist/index.js +184 -173
- package/package.json +1 -1
- package/src/composables/useField.ts +11 -10
- package/src/composables/useFieldRegistry.ts +20 -2
- package/src/composables/useFormData.ts +1 -1
- package/src/composables/useValidation.ts +1 -1
- package/src/utils/path.ts +1 -1
- package/tests/useForm.test.ts +33 -0
package/dist/index.js
CHANGED
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var w = (t, e, r) =>
|
|
4
|
-
import { toValue as
|
|
5
|
-
import { cloneDeep as
|
|
1
|
+
var G = Object.defineProperty;
|
|
2
|
+
var L = (t, e, r) => e in t ? G(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r;
|
|
3
|
+
var w = (t, e, r) => L(t, typeof e != "symbol" ? e + "" : e, r);
|
|
4
|
+
import { toValue as Z, toRaw as q, computed as u, unref as d, isRef as j, shallowRef as _, reactive as D, watch as F, toRefs as W, shallowReactive as H, toRef as S, onScopeDispose as Q, watchEffect as X, triggerRef as Y, ref as k, getCurrentScope as x, onBeforeUnmount as ee, defineComponent as $, renderSlot as C, normalizeProps as B, guardReactiveProps as I, resolveComponent as re, createBlock as A, openBlock as M, withCtx as z, resolveDynamicComponent as te, mergeProps as se } from "vue";
|
|
5
|
+
import { cloneDeep as ae } from "lodash-es";
|
|
6
6
|
import "zod";
|
|
7
|
-
function
|
|
8
|
-
const e =
|
|
9
|
-
return
|
|
7
|
+
function y(t) {
|
|
8
|
+
const e = Z(t), r = q(e);
|
|
9
|
+
return ae(r);
|
|
10
10
|
}
|
|
11
|
-
function
|
|
11
|
+
function K(t) {
|
|
12
12
|
return t === "" ? [] : t.split(/\s*\.\s*/).filter(Boolean);
|
|
13
13
|
}
|
|
14
14
|
function P(t, e) {
|
|
15
|
-
return (Array.isArray(e) ? e :
|
|
16
|
-
(s,
|
|
15
|
+
return (Array.isArray(e) ? e : K(e)).reduce(
|
|
16
|
+
(s, i) => s == null ? void 0 : s[i],
|
|
17
17
|
t
|
|
18
18
|
);
|
|
19
19
|
}
|
|
20
|
-
function
|
|
21
|
-
const s = Array.isArray(e) ? e :
|
|
22
|
-
if (
|
|
23
|
-
const
|
|
24
|
-
(h, v) => h[v],
|
|
20
|
+
function ie(t, e, r) {
|
|
21
|
+
const s = Array.isArray(e) ? e : K(e), i = s.at(-1);
|
|
22
|
+
if (i) {
|
|
23
|
+
const n = s.slice(0, -1).reduce(
|
|
24
|
+
(h, v) => h == null ? void 0 : h[v],
|
|
25
25
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
26
|
-
|
|
26
|
+
d(t)
|
|
27
27
|
);
|
|
28
|
-
i
|
|
28
|
+
n[i] = r;
|
|
29
29
|
} else {
|
|
30
|
-
if (!
|
|
30
|
+
if (!j(t))
|
|
31
31
|
return;
|
|
32
32
|
t.value = r;
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
-
const
|
|
35
|
+
const U = (t, e) => u({
|
|
36
36
|
get() {
|
|
37
|
-
return P(
|
|
37
|
+
return P(d(t), d(e));
|
|
38
38
|
},
|
|
39
39
|
set(r) {
|
|
40
|
-
|
|
40
|
+
ie(t, d(e), r);
|
|
41
41
|
}
|
|
42
42
|
});
|
|
43
43
|
function R(t, e) {
|
|
44
44
|
return !t && !e ? "" : !t && e ? e : !e && t ? t : `${t}.${e}`;
|
|
45
45
|
}
|
|
46
|
-
function
|
|
46
|
+
function ne(t, e) {
|
|
47
47
|
if (!e)
|
|
48
48
|
return t;
|
|
49
49
|
const r = `${e}.`, s = Object.fromEntries(
|
|
50
|
-
Object.entries(t.propertyErrors).filter(([
|
|
51
|
-
([
|
|
50
|
+
Object.entries(t.propertyErrors).filter(([i]) => i.startsWith(r)).map(
|
|
51
|
+
([i, n]) => [i.slice(r.length), n]
|
|
52
52
|
)
|
|
53
53
|
);
|
|
54
54
|
return {
|
|
@@ -57,7 +57,7 @@ function se(t, e) {
|
|
|
57
57
|
propertyErrors: s
|
|
58
58
|
};
|
|
59
59
|
}
|
|
60
|
-
class
|
|
60
|
+
class oe {
|
|
61
61
|
constructor(e) {
|
|
62
62
|
w(this, "rc", 1);
|
|
63
63
|
this.drop = e;
|
|
@@ -69,32 +69,32 @@ class ae {
|
|
|
69
69
|
this.rc > 0 && (this.rc -= 1, this.rc === 0 && this.drop && this.drop());
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
|
-
function
|
|
73
|
-
const e =
|
|
74
|
-
E(
|
|
75
|
-
() => f(t.initialValue),
|
|
76
|
-
(u) => {
|
|
77
|
-
e.value = Object.freeze(g(u));
|
|
78
|
-
},
|
|
79
|
-
{ flush: "sync" }
|
|
80
|
-
);
|
|
81
|
-
const r = D({
|
|
72
|
+
function le(t) {
|
|
73
|
+
const e = _(Object.freeze(y(t.initialValue))), r = D({
|
|
82
74
|
value: t.value,
|
|
83
75
|
path: t.path,
|
|
84
76
|
initialValue: e,
|
|
85
77
|
errors: t.errors,
|
|
86
78
|
touched: !1
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
|
|
79
|
+
});
|
|
80
|
+
F(
|
|
81
|
+
_(t.initialValue),
|
|
82
|
+
() => {
|
|
83
|
+
e.value = Object.freeze(y(t.initialValue)), r.value = y(t.initialValue);
|
|
84
|
+
},
|
|
85
|
+
{ flush: "sync" }
|
|
86
|
+
);
|
|
87
|
+
const s = u(() => JSON.stringify(r.value) !== JSON.stringify(r.initialValue)), i = (f) => {
|
|
88
|
+
r.value = f;
|
|
89
|
+
}, n = () => {
|
|
90
90
|
r.touched = !0;
|
|
91
91
|
}, h = () => {
|
|
92
92
|
}, v = () => {
|
|
93
|
-
r.value =
|
|
94
|
-
}, V = (
|
|
95
|
-
s.value ||
|
|
96
|
-
},
|
|
97
|
-
r.errors =
|
|
93
|
+
r.value = y(r.initialValue), r.touched = !1, r.errors = [];
|
|
94
|
+
}, V = (f) => {
|
|
95
|
+
s.value || i(y(f)), r.initialValue = f;
|
|
96
|
+
}, o = (f) => {
|
|
97
|
+
r.errors = f;
|
|
98
98
|
}, a = () => {
|
|
99
99
|
r.errors = [];
|
|
100
100
|
}, c = W(r);
|
|
@@ -105,70 +105,81 @@ function oe(t) {
|
|
|
105
105
|
errors: c.errors,
|
|
106
106
|
touched: c.touched,
|
|
107
107
|
dirty: s,
|
|
108
|
-
setData:
|
|
108
|
+
setData: i,
|
|
109
109
|
setInitialData: V,
|
|
110
|
-
onBlur:
|
|
110
|
+
onBlur: n,
|
|
111
111
|
onFocus: h,
|
|
112
112
|
reset: v,
|
|
113
|
-
setErrors:
|
|
113
|
+
setErrors: o,
|
|
114
114
|
clearErrors: a
|
|
115
115
|
};
|
|
116
116
|
}
|
|
117
|
-
function
|
|
118
|
-
const
|
|
119
|
-
|
|
117
|
+
function ce(t) {
|
|
118
|
+
const e = _(t());
|
|
119
|
+
return X(
|
|
120
|
+
() => {
|
|
121
|
+
e.value = t(), Y(e);
|
|
122
|
+
},
|
|
123
|
+
{ flush: "sync" }
|
|
124
|
+
), e;
|
|
125
|
+
}
|
|
126
|
+
function ue(t, e) {
|
|
127
|
+
const r = /* @__PURE__ */ new Map(), s = H(/* @__PURE__ */ new Map()), i = (a) => {
|
|
128
|
+
const c = d(a.path);
|
|
120
129
|
s.set(c, a);
|
|
121
|
-
},
|
|
130
|
+
}, n = (a) => {
|
|
122
131
|
s.delete(a);
|
|
123
132
|
}, h = (a) => {
|
|
124
133
|
var c;
|
|
125
|
-
r.has(a) ? (c = r.get(a)) == null || c.inc() : r.set(a, new
|
|
134
|
+
r.has(a) ? (c = r.get(a)) == null || c.inc() : r.set(a, new oe(() => n(a)));
|
|
126
135
|
}, v = (a) => {
|
|
127
136
|
var c;
|
|
128
137
|
r.has(a) && ((c = r.get(a)) == null || c.dec());
|
|
129
138
|
}, V = (a) => {
|
|
130
139
|
if (!s.has(a)) {
|
|
131
|
-
const
|
|
140
|
+
const f = le({
|
|
132
141
|
path: a,
|
|
133
|
-
value:
|
|
134
|
-
initialValue:
|
|
135
|
-
|
|
142
|
+
value: U(S(t, "data"), a),
|
|
143
|
+
initialValue: ce(
|
|
144
|
+
() => P(t.initialData, a)
|
|
145
|
+
),
|
|
146
|
+
errors: u({
|
|
136
147
|
get() {
|
|
137
148
|
return e.errors.value.propertyErrors[a] || [];
|
|
138
149
|
},
|
|
139
|
-
set(
|
|
140
|
-
e.errors.value.propertyErrors[a] =
|
|
150
|
+
set(E) {
|
|
151
|
+
e.errors.value.propertyErrors[a] = E;
|
|
141
152
|
}
|
|
142
153
|
})
|
|
143
154
|
});
|
|
144
|
-
|
|
155
|
+
i(f);
|
|
145
156
|
}
|
|
146
157
|
const c = s.get(a);
|
|
147
|
-
return h(a),
|
|
158
|
+
return h(a), Q(() => {
|
|
148
159
|
v(a);
|
|
149
160
|
}), c;
|
|
150
|
-
},
|
|
161
|
+
}, o = (a) => V(a.path);
|
|
151
162
|
return {
|
|
152
|
-
fields:
|
|
163
|
+
fields: u(() => [...s.values()]),
|
|
153
164
|
getField: V,
|
|
154
|
-
registerField:
|
|
155
|
-
deregisterField:
|
|
156
|
-
defineField:
|
|
165
|
+
registerField: i,
|
|
166
|
+
deregisterField: n,
|
|
167
|
+
defineField: o
|
|
157
168
|
};
|
|
158
169
|
}
|
|
159
|
-
function
|
|
160
|
-
const e =
|
|
170
|
+
function de(t) {
|
|
171
|
+
const e = u(() => t.fields.value.some((s) => d(s.dirty))), r = u(() => t.fields.value.some((s) => d(s.touched)));
|
|
161
172
|
return {
|
|
162
173
|
isDirty: e,
|
|
163
174
|
isTouched: r
|
|
164
175
|
};
|
|
165
176
|
}
|
|
166
|
-
function
|
|
177
|
+
function fe(t) {
|
|
167
178
|
return t.filter(
|
|
168
179
|
(e, r, s) => s.indexOf(e) === r
|
|
169
180
|
);
|
|
170
181
|
}
|
|
171
|
-
function
|
|
182
|
+
function J(...t) {
|
|
172
183
|
return t.slice(1).reduce((e, r) => {
|
|
173
184
|
if (!e && !r)
|
|
174
185
|
return;
|
|
@@ -177,20 +188,20 @@ function U(...t) {
|
|
|
177
188
|
return r;
|
|
178
189
|
if (!s)
|
|
179
190
|
return e;
|
|
180
|
-
const
|
|
181
|
-
return
|
|
191
|
+
const i = (e ?? []).concat(r);
|
|
192
|
+
return fe(i);
|
|
182
193
|
}, t[0]);
|
|
183
194
|
}
|
|
184
|
-
function
|
|
195
|
+
function he(...t) {
|
|
185
196
|
return t.map((r) => Object.keys(r)).flat().reduce((r, s) => {
|
|
186
|
-
const
|
|
197
|
+
const i = t.map((n) => n[s]).filter(Boolean);
|
|
187
198
|
return {
|
|
188
199
|
...r,
|
|
189
|
-
[s]:
|
|
200
|
+
[s]: J(...i)
|
|
190
201
|
};
|
|
191
202
|
}, {});
|
|
192
203
|
}
|
|
193
|
-
function
|
|
204
|
+
function b(...t) {
|
|
194
205
|
if (!t.length)
|
|
195
206
|
return {
|
|
196
207
|
general: [],
|
|
@@ -199,23 +210,23 @@ function S(...t) {
|
|
|
199
210
|
const e = t[0];
|
|
200
211
|
return t.length === 1 ? e : t.slice(1).reduce(
|
|
201
212
|
(r, s) => ({
|
|
202
|
-
general:
|
|
203
|
-
propertyErrors:
|
|
213
|
+
general: J(r.general, s.general),
|
|
214
|
+
propertyErrors: he(r.propertyErrors ?? {}, s.propertyErrors ?? {})
|
|
204
215
|
}),
|
|
205
216
|
e
|
|
206
217
|
);
|
|
207
218
|
}
|
|
208
219
|
function N(t) {
|
|
209
220
|
var s;
|
|
210
|
-
const e = (((s = t.general) == null ? void 0 : s.length) ?? 0) > 0, r = Object.entries(t.propertyErrors).filter(([,
|
|
221
|
+
const e = (((s = t.general) == null ? void 0 : s.length) ?? 0) > 0, r = Object.entries(t.propertyErrors).filter(([, i]) => i == null ? void 0 : i.length).length > 0;
|
|
211
222
|
return e || r;
|
|
212
223
|
}
|
|
213
|
-
function
|
|
214
|
-
const e = t.issues.filter((s) => s.path.length === 0).map((s) => s.message), r = t.issues.filter((s) => s.path.length > 0).reduce((s,
|
|
215
|
-
const
|
|
224
|
+
function pe(t) {
|
|
225
|
+
const e = t.issues.filter((s) => s.path.length === 0).map((s) => s.message), r = t.issues.filter((s) => s.path.length > 0).reduce((s, i) => {
|
|
226
|
+
const n = i.path.join(".");
|
|
216
227
|
return {
|
|
217
228
|
...s,
|
|
218
|
-
[
|
|
229
|
+
[n]: [...s[n] ?? [], i.message]
|
|
219
230
|
};
|
|
220
231
|
}, {});
|
|
221
232
|
return {
|
|
@@ -230,7 +241,7 @@ const m = {
|
|
|
230
241
|
propertyErrors: {}
|
|
231
242
|
}
|
|
232
243
|
};
|
|
233
|
-
class
|
|
244
|
+
class ve {
|
|
234
245
|
constructor(e) {
|
|
235
246
|
this.schema = e;
|
|
236
247
|
}
|
|
@@ -240,7 +251,7 @@ class de {
|
|
|
240
251
|
const r = await this.schema.safeParseAsync(e);
|
|
241
252
|
if (r.success)
|
|
242
253
|
return m;
|
|
243
|
-
const s =
|
|
254
|
+
const s = pe(r.error);
|
|
244
255
|
return {
|
|
245
256
|
isValid: !1,
|
|
246
257
|
errors: {
|
|
@@ -250,7 +261,7 @@ class de {
|
|
|
250
261
|
};
|
|
251
262
|
}
|
|
252
263
|
}
|
|
253
|
-
class
|
|
264
|
+
class me {
|
|
254
265
|
constructor(e) {
|
|
255
266
|
this.validateFn = e;
|
|
256
267
|
}
|
|
@@ -271,11 +282,11 @@ class fe {
|
|
|
271
282
|
}
|
|
272
283
|
}
|
|
273
284
|
}
|
|
274
|
-
class
|
|
285
|
+
class Ve {
|
|
275
286
|
constructor(e, r) {
|
|
276
287
|
w(this, "schemaValidator");
|
|
277
288
|
w(this, "functionValidator");
|
|
278
|
-
this.schema = e, this.validateFn = r, this.schemaValidator = new
|
|
289
|
+
this.schema = e, this.validateFn = r, this.schemaValidator = new ve(this.schema), this.functionValidator = new me(this.validateFn);
|
|
279
290
|
}
|
|
280
291
|
async validate(e) {
|
|
281
292
|
const [r, s] = await Promise.all([
|
|
@@ -284,60 +295,60 @@ class pe {
|
|
|
284
295
|
]);
|
|
285
296
|
return {
|
|
286
297
|
isValid: r.isValid && s.isValid,
|
|
287
|
-
errors:
|
|
298
|
+
errors: b(r.errors, s.errors)
|
|
288
299
|
};
|
|
289
300
|
}
|
|
290
301
|
}
|
|
291
|
-
function
|
|
292
|
-
return
|
|
293
|
-
|
|
294
|
-
|
|
302
|
+
function O(t) {
|
|
303
|
+
return u(() => new Ve(
|
|
304
|
+
d(t.schema),
|
|
305
|
+
d(t.validateFn)
|
|
295
306
|
));
|
|
296
307
|
}
|
|
297
|
-
function
|
|
308
|
+
function ye(t, e) {
|
|
298
309
|
const r = D({
|
|
299
|
-
validators:
|
|
310
|
+
validators: k([O(e)]),
|
|
300
311
|
isValidated: !1,
|
|
301
|
-
errors:
|
|
302
|
-
}), s = (
|
|
303
|
-
r.errors =
|
|
312
|
+
errors: d(e.errors) ?? m.errors
|
|
313
|
+
}), s = (o = m.errors) => {
|
|
314
|
+
r.errors = b(d(e.errors) ?? m.errors, o);
|
|
304
315
|
};
|
|
305
|
-
|
|
316
|
+
F(() => d(e.errors), async () => {
|
|
306
317
|
if (r.isValidated) {
|
|
307
|
-
const
|
|
308
|
-
s(
|
|
318
|
+
const o = await n();
|
|
319
|
+
s(o.errors);
|
|
309
320
|
} else
|
|
310
321
|
s();
|
|
311
|
-
}, { immediate: !0 }),
|
|
322
|
+
}, { immediate: !0 }), F(
|
|
312
323
|
[() => r.validators],
|
|
313
|
-
async (
|
|
324
|
+
async (o) => {
|
|
314
325
|
if (r.isValidated)
|
|
315
|
-
if (
|
|
316
|
-
const a = await
|
|
326
|
+
if (o) {
|
|
327
|
+
const a = await n();
|
|
317
328
|
r.errors = a.errors;
|
|
318
329
|
} else
|
|
319
330
|
r.errors = m.errors;
|
|
320
331
|
},
|
|
321
332
|
{ immediate: !0 }
|
|
322
|
-
),
|
|
333
|
+
), F([() => t.data, () => d(e.schema)], () => {
|
|
323
334
|
r.isValidated && h();
|
|
324
335
|
});
|
|
325
|
-
const
|
|
326
|
-
const a =
|
|
327
|
-
return r.validators.push(a),
|
|
336
|
+
const i = (o) => {
|
|
337
|
+
const a = j(o) ? o : O(o);
|
|
338
|
+
return r.validators.push(a), x() && ee(() => {
|
|
328
339
|
r.validators = r.validators.filter(
|
|
329
340
|
(c) => c !== a
|
|
330
341
|
);
|
|
331
342
|
}), a;
|
|
332
343
|
};
|
|
333
|
-
async function
|
|
334
|
-
const
|
|
335
|
-
r.validators.filter((
|
|
336
|
-
), a =
|
|
344
|
+
async function n() {
|
|
345
|
+
const o = await Promise.all(
|
|
346
|
+
r.validators.filter((f) => d(f) !== void 0).map((f) => d(f).validate(t.data))
|
|
347
|
+
), a = o.every((f) => f.isValid);
|
|
337
348
|
let { errors: c } = m;
|
|
338
349
|
if (!a) {
|
|
339
|
-
const
|
|
340
|
-
c =
|
|
350
|
+
const f = o.map((E) => E.errors);
|
|
351
|
+
c = b(...f);
|
|
341
352
|
}
|
|
342
353
|
return {
|
|
343
354
|
errors: c,
|
|
@@ -345,23 +356,23 @@ function he(t, e) {
|
|
|
345
356
|
};
|
|
346
357
|
}
|
|
347
358
|
const h = async () => {
|
|
348
|
-
const
|
|
349
|
-
return s(
|
|
350
|
-
isValid: !N(
|
|
359
|
+
const o = await n();
|
|
360
|
+
return s(o.errors), r.isValidated = !0, {
|
|
361
|
+
isValid: !N(o.errors),
|
|
351
362
|
errors: r.errors
|
|
352
363
|
};
|
|
353
|
-
}, v =
|
|
354
|
-
r.isValidated = !1, r.errors =
|
|
364
|
+
}, v = u(() => !N(r.errors)), V = () => {
|
|
365
|
+
r.isValidated = !1, r.errors = d(e.errors) ?? m.errors;
|
|
355
366
|
};
|
|
356
367
|
return {
|
|
357
368
|
...W(r),
|
|
358
369
|
validateForm: h,
|
|
359
|
-
defineValidator:
|
|
370
|
+
defineValidator: i,
|
|
360
371
|
isValid: v,
|
|
361
372
|
reset: V
|
|
362
373
|
};
|
|
363
374
|
}
|
|
364
|
-
class
|
|
375
|
+
class ge {
|
|
365
376
|
constructor(e, r) {
|
|
366
377
|
this.path = e, this.validator = r;
|
|
367
378
|
}
|
|
@@ -375,94 +386,94 @@ class ve {
|
|
|
375
386
|
errors: {
|
|
376
387
|
general: s.errors.general || [],
|
|
377
388
|
propertyErrors: s.errors.propertyErrors ? Object.fromEntries(
|
|
378
|
-
Object.entries(s.errors.propertyErrors).map(([
|
|
379
|
-
R(this.path,
|
|
380
|
-
|
|
389
|
+
Object.entries(s.errors.propertyErrors).map(([i, n]) => [
|
|
390
|
+
R(this.path, i),
|
|
391
|
+
n
|
|
381
392
|
])
|
|
382
393
|
) : {}
|
|
383
394
|
}
|
|
384
395
|
};
|
|
385
396
|
}
|
|
386
397
|
}
|
|
387
|
-
function
|
|
388
|
-
const s =
|
|
398
|
+
function Ee(t, e, r) {
|
|
399
|
+
const s = U(t.data, e), i = u(() => P(t.initialData.value, e)), n = (l) => ({
|
|
389
400
|
...l,
|
|
390
|
-
path:
|
|
401
|
+
path: u(() => d(l.path).replace(e + ".", "")),
|
|
391
402
|
setData: (p) => {
|
|
392
403
|
l.setData(p);
|
|
393
404
|
}
|
|
394
405
|
}), h = (l) => {
|
|
395
|
-
const p = R(e, l),
|
|
396
|
-
return
|
|
406
|
+
const p = R(e, l), g = t.getField(p);
|
|
407
|
+
return g ? n(g) : {};
|
|
397
408
|
}, v = (l) => {
|
|
398
|
-
const p = R(e, l.path),
|
|
409
|
+
const p = R(e, l.path), g = t.defineField({
|
|
399
410
|
...l,
|
|
400
411
|
path: p
|
|
401
412
|
});
|
|
402
|
-
return
|
|
403
|
-
}, V =
|
|
413
|
+
return n(g);
|
|
414
|
+
}, V = u(() => t.fields.value.filter((l) => {
|
|
404
415
|
const p = l.path.value;
|
|
405
416
|
return p.startsWith(e + ".") || p === e;
|
|
406
|
-
}).map((l) =>
|
|
417
|
+
}).map((l) => n(l))), o = () => t.fields.value.filter((l) => {
|
|
407
418
|
const p = l.path.value;
|
|
408
419
|
return p.startsWith(e + ".") || p === e;
|
|
409
|
-
}), a =
|
|
420
|
+
}), a = u(() => o().some((l) => l.dirty.value)), c = u(() => o().some((l) => l.touched.value)), f = u(() => t.isValid.value), E = u(() => t.isValidated.value), T = u(() => ne(d(t.errors), e));
|
|
410
421
|
return {
|
|
411
422
|
data: s,
|
|
412
423
|
fields: V,
|
|
413
|
-
initialData:
|
|
424
|
+
initialData: i,
|
|
414
425
|
defineField: v,
|
|
415
426
|
getField: h,
|
|
416
427
|
isDirty: a,
|
|
417
428
|
isTouched: c,
|
|
418
|
-
isValid:
|
|
419
|
-
isValidated:
|
|
420
|
-
errors:
|
|
429
|
+
isValid: f,
|
|
430
|
+
isValidated: E,
|
|
431
|
+
errors: T,
|
|
421
432
|
defineValidator: (l) => {
|
|
422
|
-
const p =
|
|
423
|
-
() => new
|
|
433
|
+
const p = j(l) ? l : O(l), g = u(
|
|
434
|
+
() => new ge(e, d(p))
|
|
424
435
|
);
|
|
425
|
-
return t.defineValidator(
|
|
436
|
+
return t.defineValidator(g), p;
|
|
426
437
|
},
|
|
427
|
-
reset: () =>
|
|
438
|
+
reset: () => o().forEach((l) => l.reset()),
|
|
428
439
|
validateForm: () => t.validateForm(),
|
|
429
440
|
getSubForm: (l, p) => {
|
|
430
|
-
const
|
|
441
|
+
const g = R(e, l);
|
|
431
442
|
return t.getSubForm(
|
|
432
|
-
|
|
443
|
+
g,
|
|
433
444
|
p
|
|
434
445
|
);
|
|
435
446
|
}
|
|
436
447
|
};
|
|
437
448
|
}
|
|
438
|
-
function
|
|
439
|
-
const e =
|
|
449
|
+
function Oe(t) {
|
|
450
|
+
const e = u(() => Object.freeze(y(t.initialData))), r = k(y(e)), s = D({
|
|
440
451
|
initialData: e,
|
|
441
452
|
data: r
|
|
442
453
|
});
|
|
443
|
-
|
|
444
|
-
s.data =
|
|
454
|
+
F(e, (a) => {
|
|
455
|
+
s.data = y(a);
|
|
445
456
|
}, { flush: "sync" });
|
|
446
|
-
const
|
|
447
|
-
r.value =
|
|
457
|
+
const i = ye(s, t), n = ue(s, i), h = de(n), v = () => {
|
|
458
|
+
r.value = y(e), i.reset(), n.fields.value.forEach(
|
|
448
459
|
(a) => a.reset()
|
|
449
460
|
);
|
|
450
461
|
};
|
|
451
462
|
function V(a, c) {
|
|
452
|
-
return
|
|
463
|
+
return Ee(o, a);
|
|
453
464
|
}
|
|
454
|
-
const
|
|
465
|
+
const o = {
|
|
466
|
+
...n,
|
|
455
467
|
...i,
|
|
456
|
-
...o,
|
|
457
468
|
...h,
|
|
458
469
|
reset: v,
|
|
459
470
|
getSubForm: V,
|
|
460
|
-
initialData:
|
|
461
|
-
data:
|
|
471
|
+
initialData: S(s, "initialData"),
|
|
472
|
+
data: S(s, "data")
|
|
462
473
|
};
|
|
463
|
-
return
|
|
474
|
+
return o;
|
|
464
475
|
}
|
|
465
|
-
const
|
|
476
|
+
const je = /* @__PURE__ */ $({
|
|
466
477
|
__name: "Field",
|
|
467
478
|
props: {
|
|
468
479
|
form: {},
|
|
@@ -475,9 +486,9 @@ const _e = /* @__PURE__ */ $({
|
|
|
475
486
|
const e = t, r = e.form.defineField({
|
|
476
487
|
path: e.path
|
|
477
488
|
}), s = D(r);
|
|
478
|
-
return (
|
|
489
|
+
return (i, n) => C(i.$slots, "default", B(I(s)));
|
|
479
490
|
}
|
|
480
|
-
}),
|
|
491
|
+
}), $e = /* @__PURE__ */ $({
|
|
481
492
|
inheritAttrs: !1,
|
|
482
493
|
__name: "FormFieldWrapper",
|
|
483
494
|
props: {
|
|
@@ -488,20 +499,20 @@ const _e = /* @__PURE__ */ $({
|
|
|
488
499
|
},
|
|
489
500
|
setup(t) {
|
|
490
501
|
return (e, r) => {
|
|
491
|
-
const s =
|
|
492
|
-
return M(),
|
|
502
|
+
const s = re("Field");
|
|
503
|
+
return M(), A(s, {
|
|
493
504
|
form: e.form,
|
|
494
505
|
path: e.path
|
|
495
506
|
}, {
|
|
496
|
-
default: z(({ errors:
|
|
497
|
-
(M(),
|
|
498
|
-
"model-value":
|
|
499
|
-
errors:
|
|
507
|
+
default: z(({ errors: i, data: n, setData: h }) => [
|
|
508
|
+
(M(), A(te(e.component), se({ ...e.componentProps, ...e.$attrs }, {
|
|
509
|
+
"model-value": n,
|
|
510
|
+
errors: i,
|
|
500
511
|
name: e.path,
|
|
501
512
|
"onUpdate:modelValue": h
|
|
502
513
|
}), {
|
|
503
514
|
default: z(() => [
|
|
504
|
-
|
|
515
|
+
C(e.$slots, "default")
|
|
505
516
|
]),
|
|
506
517
|
_: 2
|
|
507
518
|
}, 1040, ["model-value", "errors", "name", "onUpdate:modelValue"]))
|
|
@@ -510,20 +521,20 @@ const _e = /* @__PURE__ */ $({
|
|
|
510
521
|
}, 8, ["form", "path"]);
|
|
511
522
|
};
|
|
512
523
|
}
|
|
513
|
-
}),
|
|
524
|
+
}), Ce = /* @__PURE__ */ $({
|
|
514
525
|
__name: "FormPart",
|
|
515
526
|
props: {
|
|
516
527
|
form: {},
|
|
517
528
|
path: {}
|
|
518
529
|
},
|
|
519
530
|
setup(t) {
|
|
520
|
-
const e = t, r =
|
|
521
|
-
return (s,
|
|
531
|
+
const e = t, r = u(() => e.form.getSubForm(e.path));
|
|
532
|
+
return (s, i) => C(s.$slots, "default", B(I({ subform: r.value })));
|
|
522
533
|
}
|
|
523
534
|
});
|
|
524
535
|
export {
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
536
|
+
je as Field,
|
|
537
|
+
$e as FormFieldWrapper,
|
|
538
|
+
Ce as FormPart,
|
|
539
|
+
Oe as useForm
|
|
529
540
|
};
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { computed, reactive,
|
|
1
|
+
import { computed, reactive, shallowRef, toRefs, watch, type MaybeRef, type MaybeRefOrGetter, type Ref, type WritableComputedRef } from 'vue'
|
|
2
2
|
import type { FormField } from '../types/form'
|
|
3
3
|
import type { ValidationErrorMessage, ValidationErrors } from '../types/validation'
|
|
4
4
|
import { cloneRefValue } from '../utils/general'
|
|
@@ -11,15 +11,7 @@ export interface UseFieldOptions<T, K extends string> {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export function useField<T, K extends string>(options: UseFieldOptions<T, K>): FormField<T, K> {
|
|
14
|
-
const initialValue =
|
|
15
|
-
|
|
16
|
-
watch(
|
|
17
|
-
() => unref(options.initialValue),
|
|
18
|
-
(newInitialValue) => {
|
|
19
|
-
initialValue.value = Object.freeze(cloneRefValue(newInitialValue))
|
|
20
|
-
},
|
|
21
|
-
{ flush: 'sync' },
|
|
22
|
-
)
|
|
14
|
+
const initialValue = shallowRef(Object.freeze(cloneRefValue(options.initialValue))) as Ref<Readonly<T | undefined>>
|
|
23
15
|
|
|
24
16
|
const state = reactive({
|
|
25
17
|
value: options.value,
|
|
@@ -29,6 +21,15 @@ export function useField<T, K extends string>(options: UseFieldOptions<T, K>): F
|
|
|
29
21
|
touched: false,
|
|
30
22
|
})
|
|
31
23
|
|
|
24
|
+
watch(
|
|
25
|
+
shallowRef(options.initialValue),
|
|
26
|
+
() => {
|
|
27
|
+
initialValue.value = Object.freeze(cloneRefValue(options.initialValue))
|
|
28
|
+
state.value = cloneRefValue(options.initialValue)
|
|
29
|
+
},
|
|
30
|
+
{ flush: 'sync' },
|
|
31
|
+
)
|
|
32
|
+
|
|
32
33
|
const dirty = computed(() => {
|
|
33
34
|
return JSON.stringify(state.value) !== JSON.stringify(state.initialValue)
|
|
34
35
|
})
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { computed, onScopeDispose, shallowReactive, toRef, unref } from 'vue'
|
|
1
|
+
import { computed, onScopeDispose, shallowReactive, shallowRef, toRef, triggerRef, unref, watch, watchEffect, type MaybeRef, type WatchSource } from 'vue'
|
|
2
2
|
import type { FieldsTuple, FormDataDefault, FormField } from '../types/form'
|
|
3
3
|
import type { Paths, PickProps } from '../types/util'
|
|
4
4
|
import { getLens, getNestedValue } from '../utils/path'
|
|
@@ -18,6 +18,22 @@ interface FormState<T extends FormDataDefault, TIn extends FormDataDefault = T>
|
|
|
18
18
|
initialData: TIn
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
// A computed that always reflects the latest value from the getter
|
|
22
|
+
// This computed forces updates even if the value is the same (to trigger watchers)
|
|
23
|
+
function alwaysComputed<T>(getter: () => T) {
|
|
24
|
+
const initialValueRef = shallowRef(getter())
|
|
25
|
+
|
|
26
|
+
watchEffect(
|
|
27
|
+
() => {
|
|
28
|
+
initialValueRef.value = getter()
|
|
29
|
+
triggerRef(initialValueRef)
|
|
30
|
+
},
|
|
31
|
+
{ flush: 'sync' },
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
return initialValueRef
|
|
35
|
+
}
|
|
36
|
+
|
|
21
37
|
export function useFieldRegistry<T extends FormDataDefault>(
|
|
22
38
|
formState: FormState<T>,
|
|
23
39
|
validationState: ValidationState<T>,
|
|
@@ -53,7 +69,9 @@ export function useFieldRegistry<T extends FormDataDefault>(
|
|
|
53
69
|
const field = useField({
|
|
54
70
|
path,
|
|
55
71
|
value: getLens(toRef(formState, 'data'), path),
|
|
56
|
-
initialValue:
|
|
72
|
+
initialValue: alwaysComputed(
|
|
73
|
+
() => getNestedValue(formState.initialData, path),
|
|
74
|
+
),
|
|
57
75
|
errors: computed({
|
|
58
76
|
get() {
|
|
59
77
|
return validationState.errors.value.propertyErrors[path] || []
|
|
@@ -4,7 +4,7 @@ import type { FormDataDefault } from '../types/form'
|
|
|
4
4
|
export function useFormData<T extends FormDataDefault>(
|
|
5
5
|
initialData: Ref<T>,
|
|
6
6
|
) {
|
|
7
|
-
const data = ref(unref(initialData))
|
|
7
|
+
const data = ref(unref(initialData)) as Ref<T>
|
|
8
8
|
|
|
9
9
|
watch(initialData, (newData) => {
|
|
10
10
|
if (newData !== data.value) {
|
|
@@ -157,7 +157,7 @@ export function useValidation<T extends FormDataDefault>(
|
|
|
157
157
|
)
|
|
158
158
|
|
|
159
159
|
// Watch for changes in form data to trigger validation
|
|
160
|
-
watch(() => formState.data, () => {
|
|
160
|
+
watch([() => formState.data, () => unref(options.schema)], () => {
|
|
161
161
|
if (validationState.isValidated) {
|
|
162
162
|
validateForm()
|
|
163
163
|
}
|
package/src/utils/path.ts
CHANGED
|
@@ -33,7 +33,7 @@ export function setNestedValue<T, K extends Paths<T>>(obj: MaybeRef<T>, path: K
|
|
|
33
33
|
const target = keys
|
|
34
34
|
.slice(0, -1)
|
|
35
35
|
.reduce(
|
|
36
|
-
(current, key) => current[key],
|
|
36
|
+
(current, key) => current?.[key],
|
|
37
37
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
38
38
|
unref(obj) as Record<string, any>,
|
|
39
39
|
)
|
package/tests/useForm.test.ts
CHANGED
|
@@ -323,4 +323,37 @@ describe('useForm', () => {
|
|
|
323
323
|
expect(nameField.initialValue.value).toBe('another')
|
|
324
324
|
expect(nameField.data.value).toBe('another')
|
|
325
325
|
})
|
|
326
|
+
|
|
327
|
+
it('it should take over the new initial data from the form after setting initial data on field', { timeout: 500 }, async () => {
|
|
328
|
+
const initialData = ref({
|
|
329
|
+
name: null as null | number,
|
|
330
|
+
})
|
|
331
|
+
|
|
332
|
+
const form = useForm({
|
|
333
|
+
initialData,
|
|
334
|
+
})
|
|
335
|
+
|
|
336
|
+
const nameField = form.getField('name')
|
|
337
|
+
|
|
338
|
+
expect(form.isDirty.value).toBe(false)
|
|
339
|
+
expect(nameField.dirty.value).toBe(false)
|
|
340
|
+
|
|
341
|
+
nameField.setInitialData(0)
|
|
342
|
+
|
|
343
|
+
expect(form.isDirty.value).toBe(false)
|
|
344
|
+
expect(nameField.dirty.value).toBe(false)
|
|
345
|
+
|
|
346
|
+
initialData.value = {
|
|
347
|
+
name: null,
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
expect(form.initialData.value.name).toBe(null)
|
|
351
|
+
expect(nameField.initialValue.value).toBe(null)
|
|
352
|
+
expect(nameField.data.value).toBe(null)
|
|
353
|
+
|
|
354
|
+
nameField.setInitialData(23)
|
|
355
|
+
|
|
356
|
+
expect(nameField.initialValue.value).toBe(23)
|
|
357
|
+
expect(nameField.data.value).toBe(23)
|
|
358
|
+
})
|
|
326
359
|
})
|