@teamnovu/kit-vue-forms 0.0.9 → 0.0.10
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/composables/useFieldRegistry.d.ts +2 -2
- package/dist/composables/useValidation.d.ts +1 -1
- package/dist/index.mjs +40 -40
- package/dist/types/form.d.ts +7 -3
- package/package.json +1 -1
- package/src/components/Field.vue +2 -2
- package/src/composables/useFieldRegistry.ts +3 -3
- package/src/composables/useForm.ts +4 -2
- package/src/composables/useFormState.ts +3 -3
- package/src/composables/useSubform.ts +4 -4
- package/src/composables/useValidation.ts +2 -2
- package/src/types/form.ts +13 -3
- package/tsconfig.json +3 -4
|
@@ -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;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FormDataDefault, FormField } from '../types/form';
|
|
1
|
+
import { FieldsTuple, FormDataDefault, FormField } from '../types/form';
|
|
2
2
|
import { Paths, PickProps } from '../types/util';
|
|
3
3
|
import { UseFieldOptions } from './useField';
|
|
4
4
|
type FieldRegistryCache<T> = Record<Paths<T>, FormField<any, string>>;
|
|
@@ -11,7 +11,7 @@ interface FormState<T extends FormDataDefault, TIn extends FormDataDefault = T>
|
|
|
11
11
|
export declare function useFieldRegistry<T extends FormDataDefault>(formState: FormState<T>): {
|
|
12
12
|
fields: FieldRegistryCache<T>;
|
|
13
13
|
getField: <K extends Paths<T>>(path: K) => ResolvedFormField<T, K>;
|
|
14
|
-
getFields: () =>
|
|
14
|
+
getFields: <TData extends T>() => FieldsTuple<TData>;
|
|
15
15
|
registerField: <K extends Paths<T>>(field: ResolvedFormField<T, K>) => void;
|
|
16
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>;
|
|
17
17
|
};
|
|
@@ -16,7 +16,7 @@ export declare function useValidation<T extends FormDataDefault>(formState: {
|
|
|
16
16
|
data: T;
|
|
17
17
|
}, options: ValidationOptions<T>): {
|
|
18
18
|
validateForm: () => Promise<ValidationResult>;
|
|
19
|
-
defineValidator: (options: ValidatorOptions<
|
|
19
|
+
defineValidator: <TData extends T>(options: ValidatorOptions<TData> | Ref<Validator<TData>>) => Ref<Validator<TData> | undefined, Validator<TData> | undefined>;
|
|
20
20
|
isValid: ComputedRef<boolean>;
|
|
21
21
|
validators: Ref<Ref<Validator<T> | undefined, Validator<T> | undefined>[], Ref<Validator<T> | undefined, Validator<T> | undefined>[]>;
|
|
22
22
|
isValidated: Ref<boolean, boolean>;
|
package/dist/index.mjs
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
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
|
-
var
|
|
4
|
-
import { toValue as W, toRaw as
|
|
3
|
+
var S = (e, r, t) => K(e, typeof r != "symbol" ? r + "" : r, t);
|
|
4
|
+
import { toValue as W, toRaw as I, computed as d, unref as c, 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
6
|
function y(e) {
|
|
7
|
-
const r = W(e), t =
|
|
7
|
+
const r = W(e), t = I(r);
|
|
8
8
|
return structuredClone(t);
|
|
9
9
|
}
|
|
10
10
|
function N(e) {
|
|
11
11
|
return e === "" ? [] : e.split(/\s*\.\s*/).filter(Boolean);
|
|
12
12
|
}
|
|
13
|
-
function
|
|
13
|
+
function w(e, r) {
|
|
14
14
|
return (Array.isArray(r) ? r : N(r)).reduce(
|
|
15
15
|
(a, s) => a == null ? void 0 : a[s],
|
|
16
16
|
e
|
|
17
17
|
);
|
|
18
18
|
}
|
|
19
|
-
function
|
|
19
|
+
function Z(e, r, t) {
|
|
20
20
|
const a = Array.isArray(r) ? r : N(r);
|
|
21
21
|
if (a.length === 0)
|
|
22
22
|
throw new Error("Path cannot be empty");
|
|
@@ -29,16 +29,16 @@ function U(e, r, t) {
|
|
|
29
29
|
}
|
|
30
30
|
const z = (e, r) => d({
|
|
31
31
|
get() {
|
|
32
|
-
return
|
|
32
|
+
return w(c(e), c(r));
|
|
33
33
|
},
|
|
34
34
|
set(t) {
|
|
35
|
-
|
|
35
|
+
Z(c(e), c(r), t);
|
|
36
36
|
}
|
|
37
37
|
});
|
|
38
38
|
function E(e, r) {
|
|
39
39
|
return !e && !r ? "" : !e && r ? r : !r && e ? e : `${e}.${r}`;
|
|
40
40
|
}
|
|
41
|
-
function
|
|
41
|
+
function k(e, r) {
|
|
42
42
|
if (!r)
|
|
43
43
|
return e;
|
|
44
44
|
const t = `${r}.`, a = Object.fromEntries(
|
|
@@ -52,8 +52,8 @@ function Z(e, r) {
|
|
|
52
52
|
propertyErrors: a
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
|
-
function
|
|
56
|
-
const r =
|
|
55
|
+
function q(e) {
|
|
56
|
+
const r = m({
|
|
57
57
|
value: e.value,
|
|
58
58
|
path: e.path,
|
|
59
59
|
initialValue: d(() => Object.freeze(y(e.initialValue))),
|
|
@@ -101,10 +101,10 @@ function H(e) {
|
|
|
101
101
|
getFields: () => Object.values(r),
|
|
102
102
|
registerField: t,
|
|
103
103
|
defineField: (u) => {
|
|
104
|
-
const v =
|
|
104
|
+
const v = q({
|
|
105
105
|
...u,
|
|
106
|
-
value: z(
|
|
107
|
-
initialValue: d(() =>
|
|
106
|
+
value: z(D(e, "data"), u.path),
|
|
107
|
+
initialValue: d(() => w(e.initialData, c(u.path)))
|
|
108
108
|
});
|
|
109
109
|
return t(v), v;
|
|
110
110
|
}
|
|
@@ -144,7 +144,7 @@ function Y(...e) {
|
|
|
144
144
|
};
|
|
145
145
|
}, {});
|
|
146
146
|
}
|
|
147
|
-
function
|
|
147
|
+
function P(...e) {
|
|
148
148
|
if (!e.length)
|
|
149
149
|
return {
|
|
150
150
|
general: [],
|
|
@@ -227,8 +227,8 @@ class tr {
|
|
|
227
227
|
}
|
|
228
228
|
class ar {
|
|
229
229
|
constructor(r, t) {
|
|
230
|
-
|
|
231
|
-
|
|
230
|
+
S(this, "schemaValidator");
|
|
231
|
+
S(this, "functionValidator");
|
|
232
232
|
this.schema = r, this.validateFn = t, this.schemaValidator = new er(this.schema), this.functionValidator = new tr(this.validateFn);
|
|
233
233
|
}
|
|
234
234
|
async validate(r) {
|
|
@@ -238,19 +238,19 @@ class ar {
|
|
|
238
238
|
]);
|
|
239
239
|
return {
|
|
240
240
|
isValid: t.isValid && a.isValid,
|
|
241
|
-
errors:
|
|
241
|
+
errors: P(t.errors, a.errors)
|
|
242
242
|
};
|
|
243
243
|
}
|
|
244
244
|
}
|
|
245
|
-
function
|
|
245
|
+
function b(e) {
|
|
246
246
|
return d(() => new ar(
|
|
247
247
|
c(e.schema),
|
|
248
248
|
c(e.validateFn)
|
|
249
249
|
));
|
|
250
250
|
}
|
|
251
251
|
function sr(e, r) {
|
|
252
|
-
const t =
|
|
253
|
-
validators: A([
|
|
252
|
+
const t = m({
|
|
253
|
+
validators: A([b(r)]),
|
|
254
254
|
isValidated: !1,
|
|
255
255
|
errors: c(r.errors) ?? V.errors
|
|
256
256
|
});
|
|
@@ -272,8 +272,8 @@ function sr(e, r) {
|
|
|
272
272
|
t.isValidated && u();
|
|
273
273
|
});
|
|
274
274
|
const a = (o) => {
|
|
275
|
-
const l = _(o) ? o :
|
|
276
|
-
return t.validators.push(l),
|
|
275
|
+
const l = _(o) ? o : b(o);
|
|
276
|
+
return t.validators.push(l), J() && T(() => {
|
|
277
277
|
t.validators = t.validators.filter(
|
|
278
278
|
(f) => f !== l
|
|
279
279
|
);
|
|
@@ -285,8 +285,8 @@ function sr(e, r) {
|
|
|
285
285
|
), l = o.every((p) => p.isValid);
|
|
286
286
|
let { errors: f } = V;
|
|
287
287
|
if (!l) {
|
|
288
|
-
const p = o.map((
|
|
289
|
-
f =
|
|
288
|
+
const p = o.map((R) => R.errors);
|
|
289
|
+
f = P(...p);
|
|
290
290
|
}
|
|
291
291
|
return {
|
|
292
292
|
errors: f,
|
|
@@ -294,7 +294,7 @@ function sr(e, r) {
|
|
|
294
294
|
};
|
|
295
295
|
}
|
|
296
296
|
const n = (o) => {
|
|
297
|
-
t.errors =
|
|
297
|
+
t.errors = P(c(r.errors) ?? V.errors, o);
|
|
298
298
|
}, u = async () => {
|
|
299
299
|
const o = await s();
|
|
300
300
|
return n(o.errors), t.isValidated = !0, {
|
|
@@ -314,7 +314,7 @@ class ir {
|
|
|
314
314
|
this.path = r, this.validator = t;
|
|
315
315
|
}
|
|
316
316
|
async validate(r) {
|
|
317
|
-
const t =
|
|
317
|
+
const t = w(r, this.path);
|
|
318
318
|
if (!this.validator)
|
|
319
319
|
return V;
|
|
320
320
|
const a = await this.validator.validate(t);
|
|
@@ -333,7 +333,7 @@ class ir {
|
|
|
333
333
|
}
|
|
334
334
|
}
|
|
335
335
|
function nr(e, r, t) {
|
|
336
|
-
const a = z(e.data, r), s = d(() =>
|
|
336
|
+
const a = z(e.data, r), s = d(() => w(e.initialData.value, r)), n = (i) => ({
|
|
337
337
|
...i,
|
|
338
338
|
path: d(() => c(i.path).replace(r + ".", "")),
|
|
339
339
|
setData: (h) => {
|
|
@@ -341,8 +341,7 @@ function nr(e, r, t) {
|
|
|
341
341
|
}
|
|
342
342
|
}), u = (i) => {
|
|
343
343
|
const h = E(r, i), g = e.getField(h);
|
|
344
|
-
|
|
345
|
-
return n(g);
|
|
344
|
+
return g ? n(g) : {};
|
|
346
345
|
}, v = (i) => {
|
|
347
346
|
const h = E(r, i.path), g = e.defineField({
|
|
348
347
|
...i,
|
|
@@ -355,7 +354,7 @@ function nr(e, r, t) {
|
|
|
355
354
|
}).map((i) => n(i)), l = () => e.getFields().filter((i) => {
|
|
356
355
|
const h = i.path.value;
|
|
357
356
|
return h.startsWith(r + ".") || h === r;
|
|
358
|
-
}), f = d(() => l().some((i) => i.dirty.value)), p = d(() => l().some((i) => i.touched.value)),
|
|
357
|
+
}), f = d(() => l().some((i) => i.dirty.value)), p = d(() => l().some((i) => i.touched.value)), R = d(() => e.isValid.value), M = d(() => e.isValidated.value), $ = d(() => k(c(e.errors), r));
|
|
359
358
|
return {
|
|
360
359
|
data: a,
|
|
361
360
|
initialData: s,
|
|
@@ -364,11 +363,11 @@ function nr(e, r, t) {
|
|
|
364
363
|
getFields: o,
|
|
365
364
|
isDirty: f,
|
|
366
365
|
isTouched: p,
|
|
367
|
-
isValid:
|
|
366
|
+
isValid: R,
|
|
368
367
|
isValidated: M,
|
|
369
368
|
errors: $,
|
|
370
369
|
defineValidator: (i) => {
|
|
371
|
-
const h = _(i) ? i :
|
|
370
|
+
const h = _(i) ? i : b(i), g = d(
|
|
372
371
|
() => new ir(r, c(h))
|
|
373
372
|
);
|
|
374
373
|
return e.defineValidator(g), h;
|
|
@@ -385,11 +384,13 @@ function nr(e, r, t) {
|
|
|
385
384
|
};
|
|
386
385
|
}
|
|
387
386
|
function vr(e) {
|
|
388
|
-
const r = d(() => Object.freeze(y(e.initialData))), t = A(y(r)), a =
|
|
387
|
+
const r = d(() => Object.freeze(y(e.initialData))), t = A(y(r)), a = m({
|
|
389
388
|
initialData: r,
|
|
390
389
|
data: t
|
|
391
390
|
}), s = H(a), n = sr(a, e), u = Q(s), v = () => {
|
|
392
|
-
t.value = y(r), s.getFields().forEach(
|
|
391
|
+
t.value = y(r), s.getFields().forEach(
|
|
392
|
+
(f) => f.reset()
|
|
393
|
+
);
|
|
393
394
|
};
|
|
394
395
|
function o(f, p) {
|
|
395
396
|
return nr(l, f);
|
|
@@ -400,12 +401,12 @@ function vr(e) {
|
|
|
400
401
|
...u,
|
|
401
402
|
reset: v,
|
|
402
403
|
getSubForm: o,
|
|
403
|
-
initialData:
|
|
404
|
-
data:
|
|
404
|
+
initialData: D(a, "initialData"),
|
|
405
|
+
data: D(a, "data")
|
|
405
406
|
};
|
|
406
407
|
return l;
|
|
407
408
|
}
|
|
408
|
-
const pr = /* @__PURE__ */
|
|
409
|
+
const pr = /* @__PURE__ */ B({
|
|
409
410
|
__name: "Field",
|
|
410
411
|
props: {
|
|
411
412
|
form: {},
|
|
@@ -416,10 +417,9 @@ const pr = /* @__PURE__ */ T({
|
|
|
416
417
|
},
|
|
417
418
|
setup(e) {
|
|
418
419
|
const r = e, t = r.form.defineField({
|
|
419
|
-
path: r.path
|
|
420
|
-
required: r.required
|
|
420
|
+
path: r.path
|
|
421
421
|
});
|
|
422
|
-
return (a, s) =>
|
|
422
|
+
return (a, s) => G(a.$slots, "default", L(U(m(c(t)))));
|
|
423
423
|
}
|
|
424
424
|
});
|
|
425
425
|
export {
|
package/dist/types/form.d.ts
CHANGED
|
@@ -19,18 +19,22 @@ export interface FormField<T, P extends string> {
|
|
|
19
19
|
setErrors: (newErrors: ValidationErrorMessage[]) => void;
|
|
20
20
|
clearErrors: () => void;
|
|
21
21
|
}
|
|
22
|
+
export type FieldsTuple<T, TPaths = Paths<T>> = [
|
|
23
|
+
...(TPaths extends infer P ? P extends string ? FormField<PickProps<T, P>, P> : never : never)[]
|
|
24
|
+
];
|
|
25
|
+
export type AnyField<T> = FormField<PickProps<T, Paths<T>>, Paths<T>>;
|
|
22
26
|
export interface Form<T extends FormDataDefault> {
|
|
23
27
|
data: Ref<T>;
|
|
24
28
|
initialData: Readonly<Ref<T>>;
|
|
25
29
|
defineField: <P extends Paths<T>>(options: DefineFieldOptions<PickProps<T, P>, P>) => FormField<PickProps<T, P>, P>;
|
|
26
|
-
getField: <P extends Paths<T>>(path: P) => FormField<PickProps<T, P>, P
|
|
27
|
-
getFields: () =>
|
|
30
|
+
getField: <P extends Paths<T>>(path: P) => FormField<PickProps<T, P>, P>;
|
|
31
|
+
getFields: <TData extends T>() => FieldsTuple<TData>;
|
|
28
32
|
isDirty: Ref<boolean>;
|
|
29
33
|
isTouched: Ref<boolean>;
|
|
30
34
|
isValid: Ref<boolean>;
|
|
31
35
|
isValidated: Ref<boolean>;
|
|
32
36
|
errors: Ref<ErrorBag>;
|
|
33
|
-
defineValidator: (options: ValidatorOptions<
|
|
37
|
+
defineValidator: <TData extends T>(options: ValidatorOptions<TData> | Ref<Validator<TData>>) => Ref<Validator<TData> | undefined>;
|
|
34
38
|
reset: () => void;
|
|
35
39
|
validateForm: () => Promise<ValidationResult>;
|
|
36
40
|
getSubForm: <P extends EntityPaths<T>>(path: P, options?: SubformOptions<PickEntity<T, P>>) => Form<PickEntity<T, P>>;
|
package/package.json
CHANGED
package/src/components/Field.vue
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<slot v-bind="field" />
|
|
2
|
+
<slot v-bind="reactive(field)" />
|
|
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'
|
|
@@ -18,6 +19,5 @@ const props = defineProps<FieldProps<TData, TPath>>()
|
|
|
18
19
|
|
|
19
20
|
const field = props.form.defineField({
|
|
20
21
|
path: props.path,
|
|
21
|
-
required: props.required,
|
|
22
22
|
})
|
|
23
23
|
</script>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { computed, toRef, unref } from 'vue'
|
|
2
|
-
import type { FormDataDefault, FormField } from '../types/form'
|
|
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'
|
|
5
5
|
import { useField, type UseFieldOptions } from './useField'
|
|
@@ -30,8 +30,8 @@ export function useFieldRegistry<T extends FormDataDefault>(
|
|
|
30
30
|
return (fields[path] ?? {}) as ResolvedFormField<T, K>
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
const getFields = () => {
|
|
34
|
-
return Object.values(fields) as
|
|
33
|
+
const getFields = <TData extends T>() => {
|
|
34
|
+
return Object.values(fields) as FieldsTuple<TData>
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
const defineField = <K extends Paths<T>>(options: DefineFieldOptions<PickProps<T, K>, K>) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { computed, reactive, ref, toRef, type MaybeRef, type MaybeRefOrGetter, type Ref } from 'vue'
|
|
2
|
-
import type { Form, FormDataDefault } from '../types/form'
|
|
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'
|
|
5
5
|
import { cloneRefValue } from '../utils/general'
|
|
@@ -32,7 +32,9 @@ export function useForm<T extends FormDataDefault>(options: UseFormOptions<T>) {
|
|
|
32
32
|
|
|
33
33
|
const reset = () => {
|
|
34
34
|
data.value = cloneRefValue(initialData)
|
|
35
|
-
fields.getFields().forEach(
|
|
35
|
+
fields.getFields().forEach(
|
|
36
|
+
(field: AnyField<T>) => field.reset(),
|
|
37
|
+
)
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
function getSubForm<K extends EntityPaths<T>>(
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { computed, unref } from 'vue'
|
|
2
|
-
import type { FormDataDefault } from '../types/form'
|
|
2
|
+
import type { AnyField, FormDataDefault } from '../types/form'
|
|
3
3
|
import type { FieldRegistry } from './useFieldRegistry'
|
|
4
4
|
|
|
5
5
|
export function useFormState<T extends FormDataDefault>(
|
|
6
6
|
formFieldRegistry: FieldRegistry<T>,
|
|
7
7
|
) {
|
|
8
8
|
const isDirty = computed(() => {
|
|
9
|
-
return formFieldRegistry.getFields().some(field => unref(field.dirty))
|
|
9
|
+
return formFieldRegistry.getFields().some((field: AnyField<T>) => unref(field.dirty))
|
|
10
10
|
})
|
|
11
11
|
|
|
12
12
|
const isTouched = computed(() => {
|
|
13
|
-
return formFieldRegistry.getFields().some(field => unref(field.touched))
|
|
13
|
+
return formFieldRegistry.getFields().some((field: AnyField<T>) => unref(field.touched))
|
|
14
14
|
})
|
|
15
15
|
|
|
16
16
|
return {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { computed, isRef, unref, type Ref } from 'vue'
|
|
2
|
-
import type { Form, FormDataDefault, FormField } from '../types/form'
|
|
2
|
+
import type { FieldsTuple, Form, FormDataDefault, FormField } from '../types/form'
|
|
3
3
|
import type { EntityPaths, Paths, PickEntity, PickProps } from '../types/util'
|
|
4
4
|
import type { ValidationResult, Validator } from '../types/validation'
|
|
5
5
|
import { filterErrorsForPath, getLens, getNestedValue, joinPath } from '../utils/path'
|
|
@@ -81,7 +81,7 @@ export function createSubformInterface<
|
|
|
81
81
|
const mainFormField = mainForm.getField(fullPath as ScopedMainPaths)
|
|
82
82
|
|
|
83
83
|
if (!mainFormField) {
|
|
84
|
-
return
|
|
84
|
+
return {} as FormField<PickProps<ST, P>, P>
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
return adaptMainFormField<P>(mainFormField)
|
|
@@ -99,13 +99,13 @@ export function createSubformInterface<
|
|
|
99
99
|
return adaptMainFormField<P>(mainField)
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
const getFields = <P extends SP>()
|
|
102
|
+
const getFields = <P extends SP>() => {
|
|
103
103
|
return (mainForm.getFields() as FormField<PickProps<T, ScopedMainPaths>, ScopedMainPaths>[])
|
|
104
104
|
.filter((field) => {
|
|
105
105
|
const fieldPath = field.path.value
|
|
106
106
|
return fieldPath.startsWith(path + '.') || fieldPath === path
|
|
107
107
|
})
|
|
108
|
-
.map(field => adaptMainFormField(field))
|
|
108
|
+
.map(field => adaptMainFormField(field)) as FieldsTuple<ST, P>
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
// Helper function to get all fields without type parameter
|
|
@@ -155,10 +155,10 @@ export function useValidation<T extends FormDataDefault>(
|
|
|
155
155
|
}
|
|
156
156
|
})
|
|
157
157
|
|
|
158
|
-
const defineValidator = (options: ValidatorOptions<
|
|
158
|
+
const defineValidator = <TData extends T>(options: ValidatorOptions<TData> | Ref<Validator<TData>>) => {
|
|
159
159
|
const validator = isRef(options) ? options : createValidator(options)
|
|
160
160
|
|
|
161
|
-
validationState.validators.push(validator)
|
|
161
|
+
validationState.validators.push(validator as Ref<Validator<T> | undefined>)
|
|
162
162
|
|
|
163
163
|
if (getCurrentScope()) {
|
|
164
164
|
onBeforeUnmount(() => {
|
package/src/types/form.ts
CHANGED
|
@@ -22,6 +22,16 @@ export interface FormField<T, P extends string> {
|
|
|
22
22
|
clearErrors: () => void
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
export type FieldsTuple<T, TPaths = Paths<T>> = [...(
|
|
26
|
+
TPaths extends infer P
|
|
27
|
+
? P extends string
|
|
28
|
+
? FormField<PickProps<T, P>, P>
|
|
29
|
+
: never
|
|
30
|
+
: never
|
|
31
|
+
)[]]
|
|
32
|
+
|
|
33
|
+
export type AnyField<T> = FormField<PickProps<T, Paths<T>>, Paths<T>>
|
|
34
|
+
|
|
25
35
|
export interface Form<T extends FormDataDefault> {
|
|
26
36
|
// Data properties
|
|
27
37
|
data: Ref<T>
|
|
@@ -29,8 +39,8 @@ export interface Form<T extends FormDataDefault> {
|
|
|
29
39
|
|
|
30
40
|
// Field operations
|
|
31
41
|
defineField: <P extends Paths<T>>(options: DefineFieldOptions<PickProps<T, P>, P>) => FormField<PickProps<T, P>, P>
|
|
32
|
-
getField: <P extends Paths<T>>(path: P) => FormField<PickProps<T, P>, P>
|
|
33
|
-
getFields: () =>
|
|
42
|
+
getField: <P extends Paths<T>>(path: P) => FormField<PickProps<T, P>, P>
|
|
43
|
+
getFields: <TData extends T>() => FieldsTuple<TData>
|
|
34
44
|
|
|
35
45
|
// State properties
|
|
36
46
|
isDirty: Ref<boolean>
|
|
@@ -39,7 +49,7 @@ export interface Form<T extends FormDataDefault> {
|
|
|
39
49
|
isValidated: Ref<boolean>
|
|
40
50
|
errors: Ref<ErrorBag>
|
|
41
51
|
|
|
42
|
-
defineValidator: (options: ValidatorOptions<
|
|
52
|
+
defineValidator: <TData extends T>(options: ValidatorOptions<TData> | Ref<Validator<TData>>) => Ref<Validator<TData> | undefined>
|
|
43
53
|
|
|
44
54
|
// Operations
|
|
45
55
|
reset: () => void
|