@teamnovu/kit-vue-forms 0.1.0 → 0.1.1
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/components/Field.vue.d.ts +7 -7
- package/dist/index.js +65 -65
- package/package.json +1 -1
- package/src/components/Field.vue +4 -1
- package/tests/useForm.test.ts +23 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Form } from '../types/form.ts';
|
|
2
2
|
import { Paths, PickProps } from '../types/util.ts';
|
|
3
3
|
import { UseFieldOptions } from '../composables/useField.ts';
|
|
4
|
-
import { VNodeProps, AllowedComponentProps, ComponentCustomProps, PublicProps, ShallowUnwrapRef,
|
|
4
|
+
import { VNodeProps, AllowedComponentProps, ComponentCustomProps, PublicProps, ShallowUnwrapRef, VNode } from 'vue';
|
|
5
5
|
import { ValidationErrors, ErrorMessage } from '../index.js';
|
|
6
6
|
export interface FieldProps<TData extends object, TPath extends string> extends UseFieldOptions<PickProps<TData, TPath>, TPath> {
|
|
7
7
|
form: Form<TData>;
|
|
@@ -12,12 +12,12 @@ declare const _default: <TData extends object, TPath extends Paths<TData>>(__VLS
|
|
|
12
12
|
attrs: any;
|
|
13
13
|
slots: {
|
|
14
14
|
default?(_: {
|
|
15
|
-
data:
|
|
16
|
-
path:
|
|
17
|
-
initialValue:
|
|
18
|
-
errors:
|
|
19
|
-
touched:
|
|
20
|
-
dirty:
|
|
15
|
+
data: PickProps<TData, TPath>;
|
|
16
|
+
path: TPath;
|
|
17
|
+
initialValue: PickProps<TData, TPath>;
|
|
18
|
+
errors: ValidationErrors;
|
|
19
|
+
touched: boolean;
|
|
20
|
+
dirty: boolean;
|
|
21
21
|
setData: (newData: PickProps<TData, TPath>) => void;
|
|
22
22
|
onBlur: () => void;
|
|
23
23
|
onFocus: () => void;
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var T = Object.defineProperty;
|
|
2
2
|
var G = (e, r, t) => r in e ? T(e, r, { enumerable: !0, configurable: !0, writable: !0, value: t }) : e[r] = t;
|
|
3
3
|
var R = (e, r, t) => G(e, typeof r != "symbol" ? r + "" : r, t);
|
|
4
|
-
import { toValue as L, toRaw as Z, computed as
|
|
4
|
+
import { toValue as L, toRaw as Z, computed as u, unref as d, reactive as g, toRefs as N, markRaw as q, toRef as D, ref as W, watch as E, isRef as z, getCurrentScope as H, onBeforeUnmount as Q, defineComponent as S, renderSlot as j, normalizeProps as M, guardReactiveProps as k, resolveComponent as X, createBlock as O, openBlock as $, withCtx as A, resolveDynamicComponent as Y, mergeProps as x } from "vue";
|
|
5
5
|
import { cloneDeep as rr } from "lodash-es";
|
|
6
6
|
import "zod";
|
|
7
7
|
function y(e) {
|
|
@@ -28,7 +28,7 @@ function er(e, r, t) {
|
|
|
28
28
|
);
|
|
29
29
|
o[s] = t;
|
|
30
30
|
}
|
|
31
|
-
const K = (e, r) =>
|
|
31
|
+
const K = (e, r) => u({
|
|
32
32
|
get() {
|
|
33
33
|
return w(d(e), d(r));
|
|
34
34
|
},
|
|
@@ -36,7 +36,7 @@ const K = (e, r) => c({
|
|
|
36
36
|
er(d(e), d(r), t);
|
|
37
37
|
}
|
|
38
38
|
});
|
|
39
|
-
function
|
|
39
|
+
function F(e, r) {
|
|
40
40
|
return !e && !r ? "" : !e && r ? r : !r && e ? e : `${e}.${r}`;
|
|
41
41
|
}
|
|
42
42
|
function tr(e, r) {
|
|
@@ -54,13 +54,13 @@ function tr(e, r) {
|
|
|
54
54
|
};
|
|
55
55
|
}
|
|
56
56
|
function ar(e) {
|
|
57
|
-
const r =
|
|
57
|
+
const r = g({
|
|
58
58
|
value: e.value,
|
|
59
59
|
path: e.path,
|
|
60
|
-
initialValue:
|
|
60
|
+
initialValue: u(() => Object.freeze(y(e.initialValue))),
|
|
61
61
|
errors: e.errors,
|
|
62
62
|
touched: !1
|
|
63
|
-
}), t =
|
|
63
|
+
}), t = u(() => JSON.stringify(r.value) !== JSON.stringify(r.initialValue)), a = (f) => {
|
|
64
64
|
r.value = f;
|
|
65
65
|
}, s = () => {
|
|
66
66
|
r.touched = !0;
|
|
@@ -71,13 +71,13 @@ function ar(e) {
|
|
|
71
71
|
r.errors = f;
|
|
72
72
|
}, l = () => {
|
|
73
73
|
r.errors = [];
|
|
74
|
-
},
|
|
74
|
+
}, c = N(r);
|
|
75
75
|
return {
|
|
76
|
-
data:
|
|
77
|
-
path:
|
|
78
|
-
initialValue:
|
|
79
|
-
errors:
|
|
80
|
-
touched:
|
|
76
|
+
data: c.value,
|
|
77
|
+
path: c.path,
|
|
78
|
+
initialValue: c.initialValue,
|
|
79
|
+
errors: c.errors,
|
|
80
|
+
touched: c.touched,
|
|
81
81
|
dirty: t,
|
|
82
82
|
setData: a,
|
|
83
83
|
onBlur: s,
|
|
@@ -88,16 +88,16 @@ function ar(e) {
|
|
|
88
88
|
};
|
|
89
89
|
}
|
|
90
90
|
function sr(e, r) {
|
|
91
|
-
const t =
|
|
91
|
+
const t = g({}), a = (i) => {
|
|
92
92
|
const h = d(i.path);
|
|
93
93
|
t[h] = q(i);
|
|
94
94
|
}, s = (i) => {
|
|
95
95
|
if (!t[i]) {
|
|
96
96
|
const h = ar({
|
|
97
97
|
path: i,
|
|
98
|
-
value: K(
|
|
99
|
-
initialValue:
|
|
100
|
-
errors:
|
|
98
|
+
value: K(D(e, "data"), i),
|
|
99
|
+
initialValue: u(() => w(e.initialData, i)),
|
|
100
|
+
errors: u({
|
|
101
101
|
get() {
|
|
102
102
|
return r.errors.value.propertyErrors[i] || [];
|
|
103
103
|
},
|
|
@@ -111,14 +111,14 @@ function sr(e, r) {
|
|
|
111
111
|
return t[i];
|
|
112
112
|
}, o = (i) => s(i.path);
|
|
113
113
|
return {
|
|
114
|
-
fields:
|
|
114
|
+
fields: u(() => Object.values(t)),
|
|
115
115
|
getField: s,
|
|
116
116
|
registerField: a,
|
|
117
117
|
defineField: o
|
|
118
118
|
};
|
|
119
119
|
}
|
|
120
120
|
function or(e) {
|
|
121
|
-
const r =
|
|
121
|
+
const r = u(() => e.fields.value.some((a) => d(a.dirty))), t = u(() => e.fields.value.some((a) => d(a.touched)));
|
|
122
122
|
return {
|
|
123
123
|
isDirty: r,
|
|
124
124
|
isTouched: t
|
|
@@ -151,7 +151,7 @@ function ir(...e) {
|
|
|
151
151
|
};
|
|
152
152
|
}, {});
|
|
153
153
|
}
|
|
154
|
-
function
|
|
154
|
+
function _(...e) {
|
|
155
155
|
if (!e.length)
|
|
156
156
|
return {
|
|
157
157
|
general: [],
|
|
@@ -191,7 +191,7 @@ const m = {
|
|
|
191
191
|
propertyErrors: {}
|
|
192
192
|
}
|
|
193
193
|
};
|
|
194
|
-
class
|
|
194
|
+
class cr {
|
|
195
195
|
constructor(r) {
|
|
196
196
|
this.schema = r;
|
|
197
197
|
}
|
|
@@ -211,7 +211,7 @@ class ur {
|
|
|
211
211
|
};
|
|
212
212
|
}
|
|
213
213
|
}
|
|
214
|
-
class
|
|
214
|
+
class ur {
|
|
215
215
|
constructor(r) {
|
|
216
216
|
this.validateFn = r;
|
|
217
217
|
}
|
|
@@ -236,7 +236,7 @@ class dr {
|
|
|
236
236
|
constructor(r, t) {
|
|
237
237
|
R(this, "schemaValidator");
|
|
238
238
|
R(this, "functionValidator");
|
|
239
|
-
this.schema = r, this.validateFn = t, this.schemaValidator = new
|
|
239
|
+
this.schema = r, this.validateFn = t, this.schemaValidator = new cr(this.schema), this.functionValidator = new ur(this.validateFn);
|
|
240
240
|
}
|
|
241
241
|
async validate(r) {
|
|
242
242
|
const [t, a] = await Promise.all([
|
|
@@ -245,70 +245,70 @@ class dr {
|
|
|
245
245
|
]);
|
|
246
246
|
return {
|
|
247
247
|
isValid: t.isValid && a.isValid,
|
|
248
|
-
errors:
|
|
248
|
+
errors: _(t.errors, a.errors)
|
|
249
249
|
};
|
|
250
250
|
}
|
|
251
251
|
}
|
|
252
252
|
function b(e) {
|
|
253
|
-
return
|
|
253
|
+
return u(() => new dr(
|
|
254
254
|
d(e.schema),
|
|
255
255
|
d(e.validateFn)
|
|
256
256
|
));
|
|
257
257
|
}
|
|
258
258
|
function fr(e, r) {
|
|
259
|
-
const t =
|
|
259
|
+
const t = g({
|
|
260
260
|
validators: W([b(r)]),
|
|
261
261
|
isValidated: !1,
|
|
262
262
|
errors: d(r.errors) ?? m.errors
|
|
263
263
|
});
|
|
264
|
-
|
|
264
|
+
E(() => d(r.errors), async () => {
|
|
265
265
|
const l = await s();
|
|
266
266
|
o(l.errors);
|
|
267
|
-
}, { immediate: !0 }),
|
|
267
|
+
}, { immediate: !0 }), E(
|
|
268
268
|
[() => t.validators],
|
|
269
269
|
async (l) => {
|
|
270
270
|
if (t.isValidated)
|
|
271
271
|
if (l) {
|
|
272
|
-
const
|
|
273
|
-
t.errors =
|
|
272
|
+
const c = await s();
|
|
273
|
+
t.errors = c.errors;
|
|
274
274
|
} else
|
|
275
275
|
t.errors = m.errors;
|
|
276
276
|
},
|
|
277
277
|
{ immediate: !0 }
|
|
278
|
-
),
|
|
278
|
+
), E(() => e.data, () => {
|
|
279
279
|
t.isValidated && i();
|
|
280
280
|
});
|
|
281
281
|
const a = (l) => {
|
|
282
|
-
const
|
|
283
|
-
return t.validators.push(
|
|
282
|
+
const c = z(l) ? l : b(l);
|
|
283
|
+
return t.validators.push(c), H() && Q(() => {
|
|
284
284
|
t.validators = t.validators.filter(
|
|
285
|
-
(f) => f !==
|
|
285
|
+
(f) => f !== c
|
|
286
286
|
);
|
|
287
|
-
}),
|
|
287
|
+
}), c;
|
|
288
288
|
};
|
|
289
289
|
async function s() {
|
|
290
290
|
const l = await Promise.all(
|
|
291
291
|
t.validators.filter((v) => d(v) !== void 0).map((v) => d(v).validate(e.data))
|
|
292
|
-
),
|
|
292
|
+
), c = l.every((v) => v.isValid);
|
|
293
293
|
let { errors: f } = m;
|
|
294
|
-
if (!
|
|
294
|
+
if (!c) {
|
|
295
295
|
const v = l.map((P) => P.errors);
|
|
296
|
-
f =
|
|
296
|
+
f = _(...v);
|
|
297
297
|
}
|
|
298
298
|
return {
|
|
299
299
|
errors: f,
|
|
300
|
-
isValid:
|
|
300
|
+
isValid: c
|
|
301
301
|
};
|
|
302
302
|
}
|
|
303
303
|
const o = (l) => {
|
|
304
|
-
t.errors =
|
|
304
|
+
t.errors = _(d(r.errors) ?? m.errors, l);
|
|
305
305
|
}, i = async () => {
|
|
306
306
|
const l = await s();
|
|
307
307
|
return o(l.errors), t.isValidated = !0, {
|
|
308
308
|
isValid: !C(l.errors),
|
|
309
309
|
errors: t.errors
|
|
310
310
|
};
|
|
311
|
-
}, h =
|
|
311
|
+
}, h = u(() => !C(t.errors));
|
|
312
312
|
return {
|
|
313
313
|
...N(t),
|
|
314
314
|
validateForm: i,
|
|
@@ -331,7 +331,7 @@ class pr {
|
|
|
331
331
|
general: a.errors.general || [],
|
|
332
332
|
propertyErrors: a.errors.propertyErrors ? Object.fromEntries(
|
|
333
333
|
Object.entries(a.errors.propertyErrors).map(([s, o]) => [
|
|
334
|
-
|
|
334
|
+
F(this.path, s),
|
|
335
335
|
o
|
|
336
336
|
])
|
|
337
337
|
) : {}
|
|
@@ -340,28 +340,28 @@ class pr {
|
|
|
340
340
|
}
|
|
341
341
|
}
|
|
342
342
|
function hr(e, r, t) {
|
|
343
|
-
const a = K(e.data, r), s =
|
|
343
|
+
const a = K(e.data, r), s = u(() => w(e.initialData.value, r)), o = (n) => ({
|
|
344
344
|
...n,
|
|
345
|
-
path:
|
|
345
|
+
path: u(() => d(n.path).replace(r + ".", "")),
|
|
346
346
|
setData: (p) => {
|
|
347
347
|
n.setData(p);
|
|
348
348
|
}
|
|
349
349
|
}), i = (n) => {
|
|
350
|
-
const p =
|
|
350
|
+
const p = F(r, n), V = e.getField(p);
|
|
351
351
|
return V ? o(V) : {};
|
|
352
352
|
}, h = (n) => {
|
|
353
|
-
const p =
|
|
353
|
+
const p = F(r, n.path), V = e.defineField({
|
|
354
354
|
...n,
|
|
355
355
|
path: p
|
|
356
356
|
});
|
|
357
357
|
return o(V);
|
|
358
|
-
}, l =
|
|
358
|
+
}, l = u(() => e.fields.value.filter((n) => {
|
|
359
359
|
const p = n.path.value;
|
|
360
360
|
return p.startsWith(r + ".") || p === r;
|
|
361
|
-
}).map((n) => o(n))),
|
|
361
|
+
}).map((n) => o(n))), c = () => e.fields.value.filter((n) => {
|
|
362
362
|
const p = n.path.value;
|
|
363
363
|
return p.startsWith(r + ".") || p === r;
|
|
364
|
-
}), f =
|
|
364
|
+
}), f = u(() => c().some((n) => n.dirty.value)), v = u(() => c().some((n) => n.touched.value)), P = u(() => e.isValid.value), I = u(() => e.isValidated.value), J = u(() => tr(d(e.errors), r));
|
|
365
365
|
return {
|
|
366
366
|
data: a,
|
|
367
367
|
fields: l,
|
|
@@ -374,15 +374,15 @@ function hr(e, r, t) {
|
|
|
374
374
|
isValidated: I,
|
|
375
375
|
errors: J,
|
|
376
376
|
defineValidator: (n) => {
|
|
377
|
-
const p = z(n) ? n : b(n), V =
|
|
377
|
+
const p = z(n) ? n : b(n), V = u(
|
|
378
378
|
() => new pr(r, d(p))
|
|
379
379
|
);
|
|
380
380
|
return e.defineValidator(V), p;
|
|
381
381
|
},
|
|
382
|
-
reset: () =>
|
|
382
|
+
reset: () => c().forEach((n) => n.reset()),
|
|
383
383
|
validateForm: () => e.validateForm(),
|
|
384
384
|
getSubForm: (n, p) => {
|
|
385
|
-
const V =
|
|
385
|
+
const V = F(r, n);
|
|
386
386
|
return e.getSubForm(
|
|
387
387
|
V,
|
|
388
388
|
p
|
|
@@ -391,11 +391,11 @@ function hr(e, r, t) {
|
|
|
391
391
|
};
|
|
392
392
|
}
|
|
393
393
|
function Pr(e) {
|
|
394
|
-
const r =
|
|
394
|
+
const r = u(() => Object.freeze(y(e.initialData))), t = W(y(r)), a = g({
|
|
395
395
|
initialData: r,
|
|
396
396
|
data: t
|
|
397
397
|
});
|
|
398
|
-
|
|
398
|
+
E(r, (f) => {
|
|
399
399
|
a.data = y(f);
|
|
400
400
|
});
|
|
401
401
|
const s = fr(a, e), o = sr(a, s), i = or(o), h = () => {
|
|
@@ -404,18 +404,18 @@ function Pr(e) {
|
|
|
404
404
|
);
|
|
405
405
|
};
|
|
406
406
|
function l(f, v) {
|
|
407
|
-
return hr(
|
|
407
|
+
return hr(c, f);
|
|
408
408
|
}
|
|
409
|
-
const
|
|
409
|
+
const c = {
|
|
410
410
|
...o,
|
|
411
411
|
...s,
|
|
412
412
|
...i,
|
|
413
413
|
reset: h,
|
|
414
414
|
getSubForm: l,
|
|
415
|
-
initialData:
|
|
416
|
-
data:
|
|
415
|
+
initialData: D(a, "initialData"),
|
|
416
|
+
data: D(a, "data")
|
|
417
417
|
};
|
|
418
|
-
return
|
|
418
|
+
return c;
|
|
419
419
|
}
|
|
420
420
|
const Rr = /* @__PURE__ */ S({
|
|
421
421
|
__name: "Field",
|
|
@@ -429,10 +429,10 @@ const Rr = /* @__PURE__ */ S({
|
|
|
429
429
|
setup(e) {
|
|
430
430
|
const r = e, t = r.form.defineField({
|
|
431
431
|
path: r.path
|
|
432
|
-
});
|
|
433
|
-
return (
|
|
432
|
+
}), a = g(t);
|
|
433
|
+
return (s, o) => j(s.$slots, "default", M(k(a)));
|
|
434
434
|
}
|
|
435
|
-
}),
|
|
435
|
+
}), Dr = /* @__PURE__ */ S({
|
|
436
436
|
inheritAttrs: !1,
|
|
437
437
|
__name: "FormFieldWrapper",
|
|
438
438
|
props: {
|
|
@@ -465,20 +465,20 @@ const Rr = /* @__PURE__ */ S({
|
|
|
465
465
|
}, 8, ["form", "path"]);
|
|
466
466
|
};
|
|
467
467
|
}
|
|
468
|
-
}),
|
|
468
|
+
}), _r = /* @__PURE__ */ S({
|
|
469
469
|
__name: "FormPart",
|
|
470
470
|
props: {
|
|
471
471
|
form: {},
|
|
472
472
|
path: {}
|
|
473
473
|
},
|
|
474
474
|
setup(e) {
|
|
475
|
-
const r = e, t =
|
|
475
|
+
const r = e, t = u(() => r.form.getSubForm(r.path));
|
|
476
476
|
return (a, s) => j(a.$slots, "default", M(k({ subform: t.value })));
|
|
477
477
|
}
|
|
478
478
|
});
|
|
479
479
|
export {
|
|
480
480
|
Rr as Field,
|
|
481
|
-
|
|
482
|
-
|
|
481
|
+
Dr as FormFieldWrapper,
|
|
482
|
+
_r as FormPart,
|
|
483
483
|
Pr as useForm
|
|
484
484
|
};
|
package/package.json
CHANGED
package/src/components/Field.vue
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<slot v-bind="
|
|
2
|
+
<slot v-bind="slotData" />
|
|
3
3
|
</template>
|
|
4
4
|
|
|
5
5
|
<script
|
|
6
6
|
setup lang="ts"
|
|
7
7
|
generic="TData extends object, TPath extends Paths<TData>"
|
|
8
8
|
>
|
|
9
|
+
import { reactive } from 'vue'
|
|
9
10
|
import type { Form } from '../types/form.ts'
|
|
10
11
|
import type { Paths, PickProps } from '../types/util.ts'
|
|
11
12
|
import type { UseFieldOptions } from '../composables/useField.ts'
|
|
@@ -19,4 +20,6 @@ const props = defineProps<FieldProps<TData, TPath>>()
|
|
|
19
20
|
const field = props.form.defineField({
|
|
20
21
|
path: props.path,
|
|
21
22
|
})
|
|
23
|
+
|
|
24
|
+
const slotData = reactive(field)
|
|
22
25
|
</script>
|
package/tests/useForm.test.ts
CHANGED
|
@@ -215,4 +215,27 @@ describe('useForm', () => {
|
|
|
215
215
|
expect(rootField.data.value).toEqual(['item1', 'item2'])
|
|
216
216
|
expect(itemField.data.value).toBe('item2')
|
|
217
217
|
})
|
|
218
|
+
|
|
219
|
+
it('can handle late initialized fields', async () => {
|
|
220
|
+
const form = useForm({
|
|
221
|
+
initialData: {
|
|
222
|
+
name: 'John',
|
|
223
|
+
age: 30,
|
|
224
|
+
},
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
// No fields defined yet
|
|
228
|
+
expect(form.fields.value).toEqual([])
|
|
229
|
+
expect(form.isDirty.value).toBe(false)
|
|
230
|
+
|
|
231
|
+
const nameField = form.defineField({ path: 'name' })
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
expect(form.fields.value.length).toBe(1)
|
|
235
|
+
expect(form.isDirty.value).toBe(false)
|
|
236
|
+
|
|
237
|
+
nameField.setData('Bob')
|
|
238
|
+
|
|
239
|
+
expect(form.isDirty.value).toBe(true)
|
|
240
|
+
})
|
|
218
241
|
})
|