@teamnovu/kit-vue-forms 0.1.0 → 0.1.2
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.
|
@@ -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;
|
|
@@ -13,6 +13,7 @@ export declare function useFieldRegistry<T extends FormDataDefault>(formState: F
|
|
|
13
13
|
fields: ComputedRef<FieldsTuple<T>>;
|
|
14
14
|
getField: <K extends Paths<T>>(path: K) => ResolvedFormField<T, K>;
|
|
15
15
|
registerField: <K extends Paths<T>>(field: ResolvedFormField<T, K>) => void;
|
|
16
|
+
deregisterField: (path: Paths<T>) => void;
|
|
16
17
|
defineField: <K extends Paths<T>>(options: DefineFieldOptions<PickProps<T, K>, K>) => ResolvedFormField<T, K>;
|
|
17
18
|
};
|
|
18
19
|
export type FieldRegistry<T extends FormDataDefault> = ReturnType<typeof useFieldRegistry<T>>;
|
package/dist/index.js
CHANGED
|
@@ -1,45 +1,45 @@
|
|
|
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
|
|
5
|
-
import { cloneDeep as
|
|
4
|
+
import { toValue as L, toRaw as Z, computed as u, unref as d, reactive as g, toRefs as N, onUnmounted as q, markRaw as H, toRef as D, ref as W, watch as E, isRef as z, getCurrentScope as Q, onBeforeUnmount as X, defineComponent as S, renderSlot as j, normalizeProps as M, guardReactiveProps as U, resolveComponent as Y, createBlock as O, openBlock as $, withCtx as A, resolveDynamicComponent as x, mergeProps as rr } from "vue";
|
|
5
|
+
import { cloneDeep as er } from "lodash-es";
|
|
6
6
|
import "zod";
|
|
7
7
|
function y(e) {
|
|
8
8
|
const r = L(e), t = Z(r);
|
|
9
|
-
return
|
|
9
|
+
return er(t);
|
|
10
10
|
}
|
|
11
|
-
function
|
|
11
|
+
function k(e) {
|
|
12
12
|
return e === "" ? [] : e.split(/\s*\.\s*/).filter(Boolean);
|
|
13
13
|
}
|
|
14
14
|
function w(e, r) {
|
|
15
|
-
return (Array.isArray(r) ? r :
|
|
15
|
+
return (Array.isArray(r) ? r : k(r)).reduce(
|
|
16
16
|
(a, s) => a == null ? void 0 : a[s],
|
|
17
17
|
e
|
|
18
18
|
);
|
|
19
19
|
}
|
|
20
|
-
function
|
|
21
|
-
const a = Array.isArray(r) ? r :
|
|
20
|
+
function tr(e, r, t) {
|
|
21
|
+
const a = Array.isArray(r) ? r : k(r);
|
|
22
22
|
if (a.length === 0)
|
|
23
23
|
throw new Error("Path cannot be empty");
|
|
24
24
|
const s = a.at(-1), o = a.slice(0, -1).reduce(
|
|
25
|
-
(
|
|
25
|
+
(h, l) => h[l],
|
|
26
26
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
27
27
|
e
|
|
28
28
|
);
|
|
29
29
|
o[s] = t;
|
|
30
30
|
}
|
|
31
|
-
const
|
|
31
|
+
const B = (e, r) => u({
|
|
32
32
|
get() {
|
|
33
33
|
return w(d(e), d(r));
|
|
34
34
|
},
|
|
35
35
|
set(t) {
|
|
36
|
-
|
|
36
|
+
tr(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
|
-
function
|
|
42
|
+
function ar(e, r) {
|
|
43
43
|
if (!r)
|
|
44
44
|
return e;
|
|
45
45
|
const t = `${r}.`, a = Object.fromEntries(
|
|
@@ -53,83 +53,91 @@ function tr(e, r) {
|
|
|
53
53
|
propertyErrors: a
|
|
54
54
|
};
|
|
55
55
|
}
|
|
56
|
-
function
|
|
57
|
-
const r =
|
|
56
|
+
function sr(e) {
|
|
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;
|
|
67
67
|
}, o = () => {
|
|
68
|
-
},
|
|
68
|
+
}, h = () => {
|
|
69
69
|
r.value = y(r.initialValue), r.touched = !1, r.errors = [];
|
|
70
|
-
},
|
|
70
|
+
}, l = (f) => {
|
|
71
71
|
r.errors = f;
|
|
72
|
-
},
|
|
72
|
+
}, n = () => {
|
|
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,
|
|
84
84
|
onFocus: o,
|
|
85
|
-
reset:
|
|
86
|
-
setErrors:
|
|
87
|
-
clearErrors:
|
|
85
|
+
reset: h,
|
|
86
|
+
setErrors: l,
|
|
87
|
+
clearErrors: n
|
|
88
88
|
};
|
|
89
89
|
}
|
|
90
|
-
function
|
|
91
|
-
const t =
|
|
92
|
-
const
|
|
93
|
-
t[
|
|
94
|
-
}, s = (
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
90
|
+
function or(e, r) {
|
|
91
|
+
const t = g({}), a = (l) => {
|
|
92
|
+
const n = d(l.path);
|
|
93
|
+
t[n] = H(l);
|
|
94
|
+
}, s = (l) => {
|
|
95
|
+
delete t[l];
|
|
96
|
+
}, o = (l) => {
|
|
97
|
+
if (!t[l]) {
|
|
98
|
+
const n = sr({
|
|
99
|
+
path: l,
|
|
100
|
+
value: B(D(e, "data"), l),
|
|
101
|
+
initialValue: u(() => w(e.initialData, l)),
|
|
102
|
+
errors: u({
|
|
101
103
|
get() {
|
|
102
|
-
return r.errors.value.propertyErrors[
|
|
104
|
+
return r.errors.value.propertyErrors[l] || [];
|
|
103
105
|
},
|
|
104
|
-
set(
|
|
105
|
-
r.errors.value.propertyErrors[
|
|
106
|
+
set(c) {
|
|
107
|
+
r.errors.value.propertyErrors[l] = c;
|
|
106
108
|
}
|
|
107
109
|
})
|
|
108
110
|
});
|
|
109
|
-
return a(
|
|
111
|
+
return a(n), n;
|
|
110
112
|
}
|
|
111
|
-
return t[
|
|
112
|
-
},
|
|
113
|
+
return t[l];
|
|
114
|
+
}, h = (l) => {
|
|
115
|
+
const n = o(l.path);
|
|
116
|
+
return q(() => {
|
|
117
|
+
s(d(n.path));
|
|
118
|
+
}), n;
|
|
119
|
+
};
|
|
113
120
|
return {
|
|
114
|
-
fields:
|
|
115
|
-
getField:
|
|
121
|
+
fields: u(() => Object.values(t)),
|
|
122
|
+
getField: o,
|
|
116
123
|
registerField: a,
|
|
117
|
-
|
|
124
|
+
deregisterField: s,
|
|
125
|
+
defineField: h
|
|
118
126
|
};
|
|
119
127
|
}
|
|
120
|
-
function
|
|
121
|
-
const r =
|
|
128
|
+
function nr(e) {
|
|
129
|
+
const r = u(() => e.fields.value.some((a) => d(a.dirty))), t = u(() => e.fields.value.some((a) => d(a.touched)));
|
|
122
130
|
return {
|
|
123
131
|
isDirty: r,
|
|
124
132
|
isTouched: t
|
|
125
133
|
};
|
|
126
134
|
}
|
|
127
|
-
function
|
|
135
|
+
function ir(e) {
|
|
128
136
|
return e.filter(
|
|
129
137
|
(r, t, a) => a.indexOf(r) === t
|
|
130
138
|
);
|
|
131
139
|
}
|
|
132
|
-
function
|
|
140
|
+
function K(...e) {
|
|
133
141
|
return e.slice(1).reduce((r, t) => {
|
|
134
142
|
if (!r && !t)
|
|
135
143
|
return;
|
|
@@ -139,19 +147,19 @@ function U(...e) {
|
|
|
139
147
|
if (!a)
|
|
140
148
|
return r;
|
|
141
149
|
const s = (r ?? []).concat(t);
|
|
142
|
-
return
|
|
150
|
+
return ir(s);
|
|
143
151
|
}, e[0]);
|
|
144
152
|
}
|
|
145
|
-
function
|
|
153
|
+
function lr(...e) {
|
|
146
154
|
return e.map((t) => Object.keys(t)).flat().reduce((t, a) => {
|
|
147
155
|
const s = e.map((o) => o[a]).filter(Boolean);
|
|
148
156
|
return {
|
|
149
157
|
...t,
|
|
150
|
-
[a]:
|
|
158
|
+
[a]: K(...s)
|
|
151
159
|
};
|
|
152
160
|
}, {});
|
|
153
161
|
}
|
|
154
|
-
function
|
|
162
|
+
function _(...e) {
|
|
155
163
|
if (!e.length)
|
|
156
164
|
return {
|
|
157
165
|
general: [],
|
|
@@ -160,8 +168,8 @@ function D(...e) {
|
|
|
160
168
|
const r = e[0];
|
|
161
169
|
return e.length === 1 ? r : e.slice(1).reduce(
|
|
162
170
|
(t, a) => ({
|
|
163
|
-
general:
|
|
164
|
-
propertyErrors:
|
|
171
|
+
general: K(t.general, a.general),
|
|
172
|
+
propertyErrors: lr(t.propertyErrors ?? {}, a.propertyErrors ?? {})
|
|
165
173
|
}),
|
|
166
174
|
r
|
|
167
175
|
);
|
|
@@ -171,7 +179,7 @@ function C(e) {
|
|
|
171
179
|
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;
|
|
172
180
|
return r || t;
|
|
173
181
|
}
|
|
174
|
-
function
|
|
182
|
+
function cr(e) {
|
|
175
183
|
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) => {
|
|
176
184
|
const o = s.path.join(".");
|
|
177
185
|
return {
|
|
@@ -201,7 +209,7 @@ class ur {
|
|
|
201
209
|
const t = await this.schema.safeParseAsync(r);
|
|
202
210
|
if (t.success)
|
|
203
211
|
return m;
|
|
204
|
-
const a =
|
|
212
|
+
const a = cr(t.error);
|
|
205
213
|
return {
|
|
206
214
|
isValid: !1,
|
|
207
215
|
errors: {
|
|
@@ -211,7 +219,7 @@ class ur {
|
|
|
211
219
|
};
|
|
212
220
|
}
|
|
213
221
|
}
|
|
214
|
-
class
|
|
222
|
+
class dr {
|
|
215
223
|
constructor(r) {
|
|
216
224
|
this.validateFn = r;
|
|
217
225
|
}
|
|
@@ -232,11 +240,11 @@ class cr {
|
|
|
232
240
|
}
|
|
233
241
|
}
|
|
234
242
|
}
|
|
235
|
-
class
|
|
243
|
+
class fr {
|
|
236
244
|
constructor(r, t) {
|
|
237
245
|
R(this, "schemaValidator");
|
|
238
246
|
R(this, "functionValidator");
|
|
239
|
-
this.schema = r, this.validateFn = t, this.schemaValidator = new ur(this.schema), this.functionValidator = new
|
|
247
|
+
this.schema = r, this.validateFn = t, this.schemaValidator = new ur(this.schema), this.functionValidator = new dr(this.validateFn);
|
|
240
248
|
}
|
|
241
249
|
async validate(r) {
|
|
242
250
|
const [t, a] = await Promise.all([
|
|
@@ -245,78 +253,78 @@ class dr {
|
|
|
245
253
|
]);
|
|
246
254
|
return {
|
|
247
255
|
isValid: t.isValid && a.isValid,
|
|
248
|
-
errors:
|
|
256
|
+
errors: _(t.errors, a.errors)
|
|
249
257
|
};
|
|
250
258
|
}
|
|
251
259
|
}
|
|
252
260
|
function b(e) {
|
|
253
|
-
return
|
|
261
|
+
return u(() => new fr(
|
|
254
262
|
d(e.schema),
|
|
255
263
|
d(e.validateFn)
|
|
256
264
|
));
|
|
257
265
|
}
|
|
258
|
-
function
|
|
259
|
-
const t =
|
|
266
|
+
function pr(e, r) {
|
|
267
|
+
const t = g({
|
|
260
268
|
validators: W([b(r)]),
|
|
261
269
|
isValidated: !1,
|
|
262
270
|
errors: d(r.errors) ?? m.errors
|
|
263
271
|
});
|
|
264
|
-
|
|
265
|
-
const
|
|
266
|
-
o(
|
|
267
|
-
}, { immediate: !0 }),
|
|
272
|
+
E(() => d(r.errors), async () => {
|
|
273
|
+
const n = await s();
|
|
274
|
+
o(n.errors);
|
|
275
|
+
}, { immediate: !0 }), E(
|
|
268
276
|
[() => t.validators],
|
|
269
|
-
async (
|
|
277
|
+
async (n) => {
|
|
270
278
|
if (t.isValidated)
|
|
271
|
-
if (
|
|
272
|
-
const
|
|
273
|
-
t.errors =
|
|
279
|
+
if (n) {
|
|
280
|
+
const c = await s();
|
|
281
|
+
t.errors = c.errors;
|
|
274
282
|
} else
|
|
275
283
|
t.errors = m.errors;
|
|
276
284
|
},
|
|
277
285
|
{ immediate: !0 }
|
|
278
|
-
),
|
|
279
|
-
t.isValidated &&
|
|
286
|
+
), E(() => e.data, () => {
|
|
287
|
+
t.isValidated && h();
|
|
280
288
|
});
|
|
281
|
-
const a = (
|
|
282
|
-
const
|
|
283
|
-
return t.validators.push(
|
|
289
|
+
const a = (n) => {
|
|
290
|
+
const c = z(n) ? n : b(n);
|
|
291
|
+
return t.validators.push(c), Q() && X(() => {
|
|
284
292
|
t.validators = t.validators.filter(
|
|
285
|
-
(f) => f !==
|
|
293
|
+
(f) => f !== c
|
|
286
294
|
);
|
|
287
|
-
}),
|
|
295
|
+
}), c;
|
|
288
296
|
};
|
|
289
297
|
async function s() {
|
|
290
|
-
const
|
|
298
|
+
const n = await Promise.all(
|
|
291
299
|
t.validators.filter((v) => d(v) !== void 0).map((v) => d(v).validate(e.data))
|
|
292
|
-
),
|
|
300
|
+
), c = n.every((v) => v.isValid);
|
|
293
301
|
let { errors: f } = m;
|
|
294
|
-
if (!
|
|
295
|
-
const v =
|
|
296
|
-
f =
|
|
302
|
+
if (!c) {
|
|
303
|
+
const v = n.map((P) => P.errors);
|
|
304
|
+
f = _(...v);
|
|
297
305
|
}
|
|
298
306
|
return {
|
|
299
307
|
errors: f,
|
|
300
|
-
isValid:
|
|
308
|
+
isValid: c
|
|
301
309
|
};
|
|
302
310
|
}
|
|
303
|
-
const o = (
|
|
304
|
-
t.errors =
|
|
305
|
-
},
|
|
306
|
-
const
|
|
307
|
-
return o(
|
|
308
|
-
isValid: !C(
|
|
311
|
+
const o = (n) => {
|
|
312
|
+
t.errors = _(d(r.errors) ?? m.errors, n);
|
|
313
|
+
}, h = async () => {
|
|
314
|
+
const n = await s();
|
|
315
|
+
return o(n.errors), t.isValidated = !0, {
|
|
316
|
+
isValid: !C(n.errors),
|
|
309
317
|
errors: t.errors
|
|
310
318
|
};
|
|
311
|
-
},
|
|
319
|
+
}, l = u(() => !C(t.errors));
|
|
312
320
|
return {
|
|
313
321
|
...N(t),
|
|
314
|
-
validateForm:
|
|
322
|
+
validateForm: h,
|
|
315
323
|
defineValidator: a,
|
|
316
|
-
isValid:
|
|
324
|
+
isValid: l
|
|
317
325
|
};
|
|
318
326
|
}
|
|
319
|
-
class
|
|
327
|
+
class hr {
|
|
320
328
|
constructor(r, t) {
|
|
321
329
|
this.path = r, this.validator = t;
|
|
322
330
|
}
|
|
@@ -331,7 +339,7 @@ class pr {
|
|
|
331
339
|
general: a.errors.general || [],
|
|
332
340
|
propertyErrors: a.errors.propertyErrors ? Object.fromEntries(
|
|
333
341
|
Object.entries(a.errors.propertyErrors).map(([s, o]) => [
|
|
334
|
-
|
|
342
|
+
F(this.path, s),
|
|
335
343
|
o
|
|
336
344
|
])
|
|
337
345
|
) : {}
|
|
@@ -339,50 +347,50 @@ class pr {
|
|
|
339
347
|
};
|
|
340
348
|
}
|
|
341
349
|
}
|
|
342
|
-
function
|
|
343
|
-
const a =
|
|
344
|
-
...
|
|
345
|
-
path:
|
|
350
|
+
function vr(e, r, t) {
|
|
351
|
+
const a = B(e.data, r), s = u(() => w(e.initialData.value, r)), o = (i) => ({
|
|
352
|
+
...i,
|
|
353
|
+
path: u(() => d(i.path).replace(r + ".", "")),
|
|
346
354
|
setData: (p) => {
|
|
347
|
-
|
|
355
|
+
i.setData(p);
|
|
348
356
|
}
|
|
349
|
-
}),
|
|
350
|
-
const p =
|
|
357
|
+
}), h = (i) => {
|
|
358
|
+
const p = F(r, i), V = e.getField(p);
|
|
351
359
|
return V ? o(V) : {};
|
|
352
|
-
},
|
|
353
|
-
const p =
|
|
354
|
-
...
|
|
360
|
+
}, l = (i) => {
|
|
361
|
+
const p = F(r, i.path), V = e.defineField({
|
|
362
|
+
...i,
|
|
355
363
|
path: p
|
|
356
364
|
});
|
|
357
365
|
return o(V);
|
|
358
|
-
},
|
|
359
|
-
const p =
|
|
366
|
+
}, n = u(() => e.fields.value.filter((i) => {
|
|
367
|
+
const p = i.path.value;
|
|
360
368
|
return p.startsWith(r + ".") || p === r;
|
|
361
|
-
}).map((
|
|
362
|
-
const p =
|
|
369
|
+
}).map((i) => o(i))), c = () => e.fields.value.filter((i) => {
|
|
370
|
+
const p = i.path.value;
|
|
363
371
|
return p.startsWith(r + ".") || p === r;
|
|
364
|
-
}), f =
|
|
372
|
+
}), f = u(() => c().some((i) => i.dirty.value)), v = u(() => c().some((i) => i.touched.value)), P = u(() => e.isValid.value), I = u(() => e.isValidated.value), J = u(() => ar(d(e.errors), r));
|
|
365
373
|
return {
|
|
366
374
|
data: a,
|
|
367
|
-
fields:
|
|
375
|
+
fields: n,
|
|
368
376
|
initialData: s,
|
|
369
|
-
defineField:
|
|
370
|
-
getField:
|
|
377
|
+
defineField: l,
|
|
378
|
+
getField: h,
|
|
371
379
|
isDirty: f,
|
|
372
380
|
isTouched: v,
|
|
373
381
|
isValid: P,
|
|
374
382
|
isValidated: I,
|
|
375
383
|
errors: J,
|
|
376
|
-
defineValidator: (
|
|
377
|
-
const p = z(
|
|
378
|
-
() => new
|
|
384
|
+
defineValidator: (i) => {
|
|
385
|
+
const p = z(i) ? i : b(i), V = u(
|
|
386
|
+
() => new hr(r, d(p))
|
|
379
387
|
);
|
|
380
388
|
return e.defineValidator(V), p;
|
|
381
389
|
},
|
|
382
|
-
reset: () =>
|
|
390
|
+
reset: () => c().forEach((i) => i.reset()),
|
|
383
391
|
validateForm: () => e.validateForm(),
|
|
384
|
-
getSubForm: (
|
|
385
|
-
const V =
|
|
392
|
+
getSubForm: (i, p) => {
|
|
393
|
+
const V = F(r, i);
|
|
386
394
|
return e.getSubForm(
|
|
387
395
|
V,
|
|
388
396
|
p
|
|
@@ -390,34 +398,34 @@ function hr(e, r, t) {
|
|
|
390
398
|
}
|
|
391
399
|
};
|
|
392
400
|
}
|
|
393
|
-
function
|
|
394
|
-
const r =
|
|
401
|
+
function Rr(e) {
|
|
402
|
+
const r = u(() => Object.freeze(y(e.initialData))), t = W(y(r)), a = g({
|
|
395
403
|
initialData: r,
|
|
396
404
|
data: t
|
|
397
405
|
});
|
|
398
|
-
|
|
406
|
+
E(r, (f) => {
|
|
399
407
|
a.data = y(f);
|
|
400
408
|
});
|
|
401
|
-
const s =
|
|
409
|
+
const s = pr(a, e), o = or(a, s), h = nr(o), l = () => {
|
|
402
410
|
t.value = y(r), o.fields.value.forEach(
|
|
403
411
|
(f) => f.reset()
|
|
404
412
|
);
|
|
405
413
|
};
|
|
406
|
-
function
|
|
407
|
-
return
|
|
414
|
+
function n(f, v) {
|
|
415
|
+
return vr(c, f);
|
|
408
416
|
}
|
|
409
|
-
const
|
|
417
|
+
const c = {
|
|
410
418
|
...o,
|
|
411
419
|
...s,
|
|
412
|
-
...
|
|
413
|
-
reset:
|
|
414
|
-
getSubForm:
|
|
415
|
-
initialData:
|
|
416
|
-
data:
|
|
420
|
+
...h,
|
|
421
|
+
reset: l,
|
|
422
|
+
getSubForm: n,
|
|
423
|
+
initialData: D(a, "initialData"),
|
|
424
|
+
data: D(a, "data")
|
|
417
425
|
};
|
|
418
|
-
return
|
|
426
|
+
return c;
|
|
419
427
|
}
|
|
420
|
-
const
|
|
428
|
+
const Dr = /* @__PURE__ */ S({
|
|
421
429
|
__name: "Field",
|
|
422
430
|
props: {
|
|
423
431
|
form: {},
|
|
@@ -429,8 +437,8 @@ const Rr = /* @__PURE__ */ S({
|
|
|
429
437
|
setup(e) {
|
|
430
438
|
const r = e, t = r.form.defineField({
|
|
431
439
|
path: r.path
|
|
432
|
-
});
|
|
433
|
-
return (
|
|
440
|
+
}), a = g(t);
|
|
441
|
+
return (s, o) => j(s.$slots, "default", M(U(a)));
|
|
434
442
|
}
|
|
435
443
|
}), _r = /* @__PURE__ */ S({
|
|
436
444
|
inheritAttrs: !1,
|
|
@@ -443,17 +451,17 @@ const Rr = /* @__PURE__ */ S({
|
|
|
443
451
|
},
|
|
444
452
|
setup(e) {
|
|
445
453
|
return (r, t) => {
|
|
446
|
-
const a =
|
|
454
|
+
const a = Y("Field");
|
|
447
455
|
return $(), O(a, {
|
|
448
456
|
form: r.form,
|
|
449
457
|
path: r.path
|
|
450
458
|
}, {
|
|
451
|
-
default: A(({ errors: s, data: o, setData:
|
|
452
|
-
($(), O(
|
|
459
|
+
default: A(({ errors: s, data: o, setData: h }) => [
|
|
460
|
+
($(), O(x(r.component), rr({ ...r.componentProps, ...r.$attrs }, {
|
|
453
461
|
"model-value": o,
|
|
454
462
|
errors: s,
|
|
455
463
|
name: r.path,
|
|
456
|
-
"onUpdate:modelValue":
|
|
464
|
+
"onUpdate:modelValue": h
|
|
457
465
|
}), {
|
|
458
466
|
default: A(() => [
|
|
459
467
|
j(r.$slots, "default")
|
|
@@ -465,20 +473,20 @@ const Rr = /* @__PURE__ */ S({
|
|
|
465
473
|
}, 8, ["form", "path"]);
|
|
466
474
|
};
|
|
467
475
|
}
|
|
468
|
-
}),
|
|
476
|
+
}), br = /* @__PURE__ */ S({
|
|
469
477
|
__name: "FormPart",
|
|
470
478
|
props: {
|
|
471
479
|
form: {},
|
|
472
480
|
path: {}
|
|
473
481
|
},
|
|
474
482
|
setup(e) {
|
|
475
|
-
const r = e, t =
|
|
476
|
-
return (a, s) => j(a.$slots, "default", M(
|
|
483
|
+
const r = e, t = u(() => r.form.getSubForm(r.path));
|
|
484
|
+
return (a, s) => j(a.$slots, "default", M(U({ subform: t.value })));
|
|
477
485
|
}
|
|
478
486
|
});
|
|
479
487
|
export {
|
|
480
|
-
|
|
488
|
+
Dr as Field,
|
|
481
489
|
_r as FormFieldWrapper,
|
|
482
|
-
|
|
483
|
-
|
|
490
|
+
br as FormPart,
|
|
491
|
+
Rr as useForm
|
|
484
492
|
};
|
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>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { computed, markRaw, reactive, toRef, unref, watch } from 'vue'
|
|
1
|
+
import { computed, markRaw, onUnmounted, reactive, toRef, unref, watch } 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'
|
|
@@ -28,6 +28,10 @@ export function useFieldRegistry<T extends FormDataDefault>(
|
|
|
28
28
|
fields[path] = markRaw(field)
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
const deregisterField = (path: Paths<T>) => {
|
|
32
|
+
delete fields[path]
|
|
33
|
+
}
|
|
34
|
+
|
|
31
35
|
const getField = <K extends Paths<T>>(path: K): ResolvedFormField<T, K> => {
|
|
32
36
|
if (!fields[path]) {
|
|
33
37
|
const field = useField({
|
|
@@ -57,6 +61,11 @@ export function useFieldRegistry<T extends FormDataDefault>(
|
|
|
57
61
|
|
|
58
62
|
// TODO: If more options are ever needed than only the path we have to update the field
|
|
59
63
|
// here with the new options
|
|
64
|
+
|
|
65
|
+
onUnmounted(() => {
|
|
66
|
+
// Clean up field on unmount
|
|
67
|
+
deregisterField(unref(field.path))
|
|
68
|
+
})
|
|
60
69
|
|
|
61
70
|
return field
|
|
62
71
|
}
|
|
@@ -65,6 +74,7 @@ export function useFieldRegistry<T extends FormDataDefault>(
|
|
|
65
74
|
fields: computed(() => Object.values(fields) as FieldsTuple<T>),
|
|
66
75
|
getField,
|
|
67
76
|
registerField,
|
|
77
|
+
deregisterField,
|
|
68
78
|
defineField,
|
|
69
79
|
}
|
|
70
80
|
}
|
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
|
})
|