@teamnovu/kit-vue-forms 0.0.15 → 0.0.17

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.
@@ -0,0 +1,25 @@
1
+ import { Component, VNodeProps, AllowedComponentProps, ComponentCustomProps, PublicProps, ShallowUnwrapRef, VNode } from 'vue';
2
+ import { ComponentProps } from 'vue-component-type-helpers';
3
+ import { Paths } from '../types/util.ts';
4
+ import { Form } from '../types/form.ts';
5
+ export interface FormFieldWrapperProps<TData extends object, TPath extends string, TComponent> {
6
+ component: TComponent;
7
+ componentProps: Omit<ComponentProps<TComponent>, 'modelValue' | 'update:modelValue' | 'errors'>;
8
+ form: Form<TData>;
9
+ path: TPath;
10
+ }
11
+ declare const _default: <TData extends object, TPath extends Paths<TData>, TComponent extends Component>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
12
+ props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{} & VNodeProps & AllowedComponentProps & ComponentCustomProps, never>, never> & FormFieldWrapperProps<TData, TPath, TComponent> & Partial<{}>> & PublicProps;
13
+ expose(exposed: ShallowUnwrapRef<{}>): void;
14
+ attrs: any;
15
+ slots: {
16
+ default?(_: {}): any;
17
+ };
18
+ emit: {};
19
+ }>) => VNode & {
20
+ __ctx?: Awaited<typeof __VLS_setup>;
21
+ };
22
+ export default _default;
23
+ type __VLS_PrettifyLocal<T> = {
24
+ [K in keyof T]: T[K];
25
+ } & {};
@@ -0,0 +1,24 @@
1
+ import { Form } from '../types/form.ts';
2
+ import { EntityPaths, PickEntity } from '../types/util.ts';
3
+ import { VNodeProps, AllowedComponentProps, ComponentCustomProps, PublicProps, ShallowUnwrapRef, VNode } from 'vue';
4
+ export interface FormPartProps<TData extends object, TPath> {
5
+ form: Form<TData>;
6
+ path: TPath;
7
+ }
8
+ declare const _default: <TData extends object, TPath extends EntityPaths<TData>>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
9
+ props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{} & VNodeProps & AllowedComponentProps & ComponentCustomProps, never>, never> & FormPartProps<TData, TPath> & Partial<{}>> & PublicProps;
10
+ expose(exposed: ShallowUnwrapRef<{}>): void;
11
+ attrs: any;
12
+ slots: {
13
+ default?(_: {
14
+ subform: Form< PickEntity<TData, TPath>>;
15
+ }): any;
16
+ };
17
+ emit: {};
18
+ }>) => VNode & {
19
+ __ctx?: Awaited<typeof __VLS_setup>;
20
+ };
21
+ export default _default;
22
+ type __VLS_PrettifyLocal<T> = {
23
+ [K in keyof T]: T[K];
24
+ } & {};
package/dist/index.d.ts CHANGED
@@ -5,5 +5,10 @@ export type { ValidationStrategy, ValidationErrorMessage as ErrorMessage, Valida
5
5
  export type { DeepPartial } from './utils/type-helpers';
6
6
  export type { Form, FormField } from './types/form';
7
7
  export type { SplitPath, Paths, PickProps, ObjectOf, EntityPaths } from './types/util';
8
+ export type { FormComponentProps, ExcludedFieldProps } from './types/FormComponentProps';
8
9
  export { default as Field } from './components/Field.vue';
9
10
  export type { FieldProps } from './components/Field.vue';
11
+ export { default as FormFieldWrapper } from './components/FormFieldWrapper.vue';
12
+ export type { FormFieldWrapperProps } from './components/FormFieldWrapper.vue';
13
+ export { default as FormPart } from './components/FormPart.vue';
14
+ export type { FormPartProps } from './components/FormPart.vue';
package/dist/index.mjs CHANGED
@@ -1,45 +1,45 @@
1
- var x = Object.defineProperty;
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 D = (e, r, t) => K(e, typeof r != "symbol" ? r + "" : r, t);
4
- import { toValue as W, toRaw as I, computed as u, unref as d, reactive as m, toRefs as O, toRef as S, ref as A, watch as E, isRef as _, getCurrentScope as J, onBeforeUnmount as T, defineComponent as B, renderSlot as G, normalizeProps as L, guardReactiveProps as U } from "vue";
1
+ var T = Object.defineProperty;
2
+ var G = (e, r, t) => r in e ? T(e, r, { enumerable: !0, configurable: !0, writable: !0, value: t }) : e[r] = t;
3
+ var _ = (e, r, t) => G(e, typeof r != "symbol" ? r + "" : r, t);
4
+ import { toValue as L, toRaw as Z, computed as u, unref as d, reactive as E, toRefs as N, toRef as D, ref as W, watch as y, isRef as z, getCurrentScope as q, onBeforeUnmount as H, defineComponent as S, renderSlot as j, normalizeProps as M, guardReactiveProps as B, resolveComponent as Q, createBlock as O, openBlock as $, withCtx as A, resolveDynamicComponent as X, mergeProps as Y } from "vue";
5
5
  import "zod";
6
6
  import "@vueuse/core";
7
- function y(e) {
8
- const r = W(e), t = I(r);
7
+ function g(e) {
8
+ const r = L(e), t = Z(r);
9
9
  return structuredClone(t);
10
10
  }
11
- function N(e) {
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 : N(r)).reduce(
15
+ return (Array.isArray(r) ? r : K(r)).reduce(
16
16
  (s, a) => s == null ? void 0 : s[a],
17
17
  e
18
18
  );
19
19
  }
20
- function Z(e, r, t) {
21
- const s = Array.isArray(r) ? r : N(r);
20
+ function x(e, r, t) {
21
+ const s = Array.isArray(r) ? r : K(r);
22
22
  if (s.length === 0)
23
23
  throw new Error("Path cannot be empty");
24
24
  const a = s.at(-1), o = s.slice(0, -1).reduce(
25
- (v, c) => v[c],
25
+ (h, c) => h[c],
26
26
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
27
27
  e
28
28
  );
29
29
  o[a] = t;
30
30
  }
31
- const z = (e, r) => u({
31
+ const U = (e, r) => u({
32
32
  get() {
33
33
  return w(d(e), d(r));
34
34
  },
35
35
  set(t) {
36
- Z(d(e), d(r), t);
36
+ x(d(e), d(r), t);
37
37
  }
38
38
  });
39
39
  function F(e, r) {
40
40
  return !e && !r ? "" : !e && r ? r : !r && e ? e : `${e}.${r}`;
41
41
  }
42
- function k(e, r) {
42
+ function rr(e, r) {
43
43
  if (!r)
44
44
  return e;
45
45
  const t = `${r}.`, s = Object.fromEntries(
@@ -53,11 +53,11 @@ function k(e, r) {
53
53
  propertyErrors: s
54
54
  };
55
55
  }
56
- function q(e) {
57
- const r = m({
56
+ function er(e) {
57
+ const r = E({
58
58
  value: e.value,
59
59
  path: e.path,
60
- initialValue: u(() => Object.freeze(y(e.initialValue))),
60
+ initialValue: u(() => Object.freeze(g(e.initialValue))),
61
61
  errors: e.errors,
62
62
  touched: !1
63
63
  }), t = u(() => JSON.stringify(r.value) !== JSON.stringify(r.initialValue)), s = (f) => {
@@ -65,13 +65,13 @@ function q(e) {
65
65
  }, a = () => {
66
66
  r.touched = !0;
67
67
  }, o = () => {
68
- }, v = () => {
69
- r.value = y(r.initialValue), r.touched = !1, r.errors = [];
68
+ }, h = () => {
69
+ r.value = g(r.initialValue), r.touched = !1, r.errors = [];
70
70
  }, c = (f) => {
71
71
  r.errors = f;
72
- }, i = () => {
72
+ }, n = () => {
73
73
  r.errors = [];
74
- }, l = O(r);
74
+ }, l = N(r);
75
75
  return {
76
76
  data: l.value,
77
77
  path: l.path,
@@ -82,20 +82,20 @@ function q(e) {
82
82
  setData: s,
83
83
  onBlur: a,
84
84
  onFocus: o,
85
- reset: v,
85
+ reset: h,
86
86
  setErrors: c,
87
- clearErrors: i
87
+ clearErrors: n
88
88
  };
89
89
  }
90
- function H(e, r) {
90
+ function tr(e, r) {
91
91
  const t = {}, s = (c) => {
92
- const i = d(c.path);
93
- t[i] = c;
92
+ const n = d(c.path);
93
+ t[n] = c;
94
94
  }, a = (c) => {
95
95
  if (!t[c]) {
96
- const i = q({
96
+ const n = er({
97
97
  path: c,
98
- value: z(S(e, "data"), c),
98
+ value: U(D(e, "data"), c),
99
99
  initialValue: u(() => w(e.initialData, c)),
100
100
  errors: u({
101
101
  get() {
@@ -106,7 +106,7 @@ function H(e, r) {
106
106
  }
107
107
  })
108
108
  });
109
- return s(i), i;
109
+ return s(n), n;
110
110
  }
111
111
  return t[c];
112
112
  };
@@ -118,19 +118,19 @@ function H(e, r) {
118
118
  defineField: (c) => a(c.path)
119
119
  };
120
120
  }
121
- function Q(e) {
121
+ function sr(e) {
122
122
  const r = u(() => e.getFields().some((s) => d(s.dirty))), t = u(() => e.getFields().some((s) => d(s.touched)));
123
123
  return {
124
124
  isDirty: r,
125
125
  isTouched: t
126
126
  };
127
127
  }
128
- function X(e) {
128
+ function ar(e) {
129
129
  return e.filter(
130
130
  (r, t, s) => s.indexOf(r) === t
131
131
  );
132
132
  }
133
- function C(...e) {
133
+ function k(...e) {
134
134
  return e.slice(1).reduce((r, t) => {
135
135
  if (!r && !t)
136
136
  return;
@@ -140,19 +140,19 @@ function C(...e) {
140
140
  if (!s)
141
141
  return r;
142
142
  const a = (r ?? []).concat(t);
143
- return X(a);
143
+ return ar(a);
144
144
  }, e[0]);
145
145
  }
146
- function Y(...e) {
146
+ function or(...e) {
147
147
  return e.map((t) => Object.keys(t)).flat().reduce((t, s) => {
148
148
  const a = e.map((o) => o[s]).filter(Boolean);
149
149
  return {
150
150
  ...t,
151
- [s]: C(...a)
151
+ [s]: k(...a)
152
152
  };
153
153
  }, {});
154
154
  }
155
- function P(...e) {
155
+ function R(...e) {
156
156
  if (!e.length)
157
157
  return {
158
158
  general: [],
@@ -161,18 +161,18 @@ function P(...e) {
161
161
  const r = e[0];
162
162
  return e.length === 1 ? r : e.slice(1).reduce(
163
163
  (t, s) => ({
164
- general: C(t.general, s.general),
165
- propertyErrors: Y(t.propertyErrors ?? {}, s.propertyErrors ?? {})
164
+ general: k(t.general, s.general),
165
+ propertyErrors: or(t.propertyErrors ?? {}, s.propertyErrors ?? {})
166
166
  }),
167
167
  r
168
168
  );
169
169
  }
170
- function j(e) {
170
+ function C(e) {
171
171
  var s;
172
172
  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;
173
173
  return r || t;
174
174
  }
175
- function rr(e) {
175
+ function nr(e) {
176
176
  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) => {
177
177
  const o = a.path.join(".");
178
178
  return {
@@ -185,24 +185,24 @@ function rr(e) {
185
185
  propertyErrors: t
186
186
  };
187
187
  }
188
- const V = {
188
+ const m = {
189
189
  isValid: !0,
190
190
  errors: {
191
191
  general: [],
192
192
  propertyErrors: {}
193
193
  }
194
194
  };
195
- class er {
195
+ class ir {
196
196
  constructor(r) {
197
197
  this.schema = r;
198
198
  }
199
199
  async validate(r) {
200
200
  if (!this.schema)
201
- return V;
201
+ return m;
202
202
  const t = await this.schema.safeParseAsync(r);
203
203
  if (t.success)
204
- return V;
205
- const s = rr(t.error);
204
+ return m;
205
+ const s = nr(t.error);
206
206
  return {
207
207
  isValid: !1,
208
208
  errors: {
@@ -212,16 +212,16 @@ class er {
212
212
  };
213
213
  }
214
214
  }
215
- class tr {
215
+ class lr {
216
216
  constructor(r) {
217
217
  this.validateFn = r;
218
218
  }
219
219
  async validate(r) {
220
220
  if (!this.validateFn)
221
- return V;
221
+ return m;
222
222
  try {
223
223
  const t = await this.validateFn(r);
224
- return t.isValid ? V : t;
224
+ return t.isValid ? m : t;
225
225
  } catch (t) {
226
226
  return {
227
227
  isValid: !1,
@@ -233,11 +233,11 @@ class tr {
233
233
  }
234
234
  }
235
235
  }
236
- class sr {
236
+ class cr {
237
237
  constructor(r, t) {
238
- D(this, "schemaValidator");
239
- D(this, "functionValidator");
240
- this.schema = r, this.validateFn = t, this.schemaValidator = new er(this.schema), this.functionValidator = new tr(this.validateFn);
238
+ _(this, "schemaValidator");
239
+ _(this, "functionValidator");
240
+ this.schema = r, this.validateFn = t, this.schemaValidator = new ir(this.schema), this.functionValidator = new lr(this.validateFn);
241
241
  }
242
242
  async validate(r) {
243
243
  const [t, s] = await Promise.all([
@@ -246,85 +246,85 @@ class sr {
246
246
  ]);
247
247
  return {
248
248
  isValid: t.isValid && s.isValid,
249
- errors: P(t.errors, s.errors)
249
+ errors: R(t.errors, s.errors)
250
250
  };
251
251
  }
252
252
  }
253
253
  function b(e) {
254
- return u(() => new sr(
254
+ return u(() => new cr(
255
255
  d(e.schema),
256
256
  d(e.validateFn)
257
257
  ));
258
258
  }
259
- function ar(e, r) {
260
- const t = m({
261
- validators: A([b(r)]),
259
+ function ur(e, r) {
260
+ const t = E({
261
+ validators: W([b(r)]),
262
262
  isValidated: !1,
263
- errors: d(r.errors) ?? V.errors
263
+ errors: d(r.errors) ?? m.errors
264
264
  });
265
- E(() => d(r.errors), async () => {
266
- const i = await a();
267
- o(i.errors);
268
- }, { immediate: !0 }), E(
265
+ y(() => d(r.errors), async () => {
266
+ const n = await a();
267
+ o(n.errors);
268
+ }, { immediate: !0 }), y(
269
269
  [() => t.validators],
270
- async (i) => {
270
+ async (n) => {
271
271
  if (t.isValidated)
272
- if (i) {
272
+ if (n) {
273
273
  const l = await a();
274
274
  t.errors = l.errors;
275
275
  } else
276
- t.errors = V.errors;
276
+ t.errors = m.errors;
277
277
  },
278
278
  { immediate: !0 }
279
- ), E(() => e.data, () => {
280
- t.isValidated && v();
279
+ ), y(() => e.data, () => {
280
+ t.isValidated && h();
281
281
  });
282
- const s = (i) => {
283
- const l = _(i) ? i : b(i);
284
- return t.validators.push(l), J() && T(() => {
282
+ const s = (n) => {
283
+ const l = z(n) ? n : b(n);
284
+ return t.validators.push(l), q() && H(() => {
285
285
  t.validators = t.validators.filter(
286
286
  (f) => f !== l
287
287
  );
288
288
  }), l;
289
289
  };
290
290
  async function a() {
291
- const i = await Promise.all(
292
- t.validators.filter((p) => d(p) !== void 0).map((p) => d(p).validate(e.data))
293
- ), l = i.every((p) => p.isValid);
294
- let { errors: f } = V;
291
+ const n = await Promise.all(
292
+ t.validators.filter((v) => d(v) !== void 0).map((v) => d(v).validate(e.data))
293
+ ), l = n.every((v) => v.isValid);
294
+ let { errors: f } = m;
295
295
  if (!l) {
296
- const p = i.map((R) => R.errors);
297
- f = P(...p);
296
+ const v = n.map((P) => P.errors);
297
+ f = R(...v);
298
298
  }
299
299
  return {
300
300
  errors: f,
301
301
  isValid: l
302
302
  };
303
303
  }
304
- const o = (i) => {
305
- t.errors = P(d(r.errors) ?? V.errors, i);
306
- }, v = async () => {
307
- const i = await a();
308
- return o(i.errors), t.isValidated = !0, {
309
- isValid: !j(i.errors),
304
+ const o = (n) => {
305
+ t.errors = R(d(r.errors) ?? m.errors, n);
306
+ }, h = async () => {
307
+ const n = await a();
308
+ return o(n.errors), t.isValidated = !0, {
309
+ isValid: !C(n.errors),
310
310
  errors: t.errors
311
311
  };
312
- }, c = u(() => !j(t.errors));
312
+ }, c = u(() => !C(t.errors));
313
313
  return {
314
- ...O(t),
315
- validateForm: v,
314
+ ...N(t),
315
+ validateForm: h,
316
316
  defineValidator: s,
317
317
  isValid: c
318
318
  };
319
319
  }
320
- class ir {
320
+ class dr {
321
321
  constructor(r, t) {
322
322
  this.path = r, this.validator = t;
323
323
  }
324
324
  async validate(r) {
325
325
  const t = w(r, this.path);
326
326
  if (!this.validator)
327
- return V;
327
+ return m;
328
328
  const s = await this.validator.validate(t);
329
329
  return {
330
330
  isValid: s.isValid,
@@ -340,85 +340,85 @@ class ir {
340
340
  };
341
341
  }
342
342
  }
343
- function nr(e, r, t) {
344
- const s = z(e.data, r), a = u(() => w(e.initialData.value, r)), o = (n) => ({
345
- ...n,
346
- path: u(() => d(n.path).replace(r + ".", "")),
347
- setData: (h) => {
348
- n.setData(h);
343
+ function fr(e, r, t) {
344
+ const s = U(e.data, r), a = u(() => w(e.initialData.value, r)), o = (i) => ({
345
+ ...i,
346
+ path: u(() => d(i.path).replace(r + ".", "")),
347
+ setData: (p) => {
348
+ i.setData(p);
349
349
  }
350
- }), v = (n) => {
351
- const h = F(r, n), g = e.getField(h);
352
- return g ? o(g) : {};
353
- }, c = (n) => {
354
- const h = F(r, n.path), g = e.defineField({
355
- ...n,
356
- path: h
350
+ }), h = (i) => {
351
+ const p = F(r, i), V = e.getField(p);
352
+ return V ? o(V) : {};
353
+ }, c = (i) => {
354
+ const p = F(r, i.path), V = e.defineField({
355
+ ...i,
356
+ path: p
357
357
  });
358
- return o(g);
359
- }, i = () => e.getFields().filter((n) => {
360
- const h = n.path.value;
361
- return h.startsWith(r + ".") || h === r;
362
- }).map((n) => o(n)), l = () => e.getFields().filter((n) => {
363
- const h = n.path.value;
364
- return h.startsWith(r + ".") || h === r;
365
- }), f = u(() => l().some((n) => n.dirty.value)), p = u(() => l().some((n) => n.touched.value)), R = u(() => e.isValid.value), M = u(() => e.isValidated.value), $ = u(() => k(d(e.errors), r));
358
+ return o(V);
359
+ }, n = () => e.getFields().filter((i) => {
360
+ const p = i.path.value;
361
+ return p.startsWith(r + ".") || p === r;
362
+ }).map((i) => o(i)), l = () => e.getFields().filter((i) => {
363
+ const p = i.path.value;
364
+ return p.startsWith(r + ".") || p === r;
365
+ }), f = u(() => l().some((i) => i.dirty.value)), v = u(() => l().some((i) => i.touched.value)), P = u(() => e.isValid.value), I = u(() => e.isValidated.value), J = u(() => rr(d(e.errors), r));
366
366
  return {
367
367
  data: s,
368
368
  initialData: a,
369
369
  defineField: c,
370
- getField: v,
371
- getFields: i,
370
+ getField: h,
371
+ getFields: n,
372
372
  isDirty: f,
373
- isTouched: p,
374
- isValid: R,
375
- isValidated: M,
376
- errors: $,
377
- defineValidator: (n) => {
378
- const h = _(n) ? n : b(n), g = u(
379
- () => new ir(r, d(h))
373
+ isTouched: v,
374
+ isValid: P,
375
+ isValidated: I,
376
+ errors: J,
377
+ defineValidator: (i) => {
378
+ const p = z(i) ? i : b(i), V = u(
379
+ () => new dr(r, d(p))
380
380
  );
381
- return e.defineValidator(g), h;
381
+ return e.defineValidator(V), p;
382
382
  },
383
- reset: () => l().forEach((n) => n.reset()),
383
+ reset: () => l().forEach((i) => i.reset()),
384
384
  validateForm: () => e.validateForm(),
385
- getSubForm: (n, h) => {
386
- const g = F(r, n);
385
+ getSubForm: (i, p) => {
386
+ const V = F(r, i);
387
387
  return e.getSubForm(
388
- g,
389
- h
388
+ V,
389
+ p
390
390
  );
391
391
  }
392
392
  };
393
393
  }
394
- function pr(e) {
395
- const r = u(() => Object.freeze(y(e.initialData))), t = A(y(r)), s = m({
394
+ function Er(e) {
395
+ const r = u(() => Object.freeze(g(e.initialData))), t = W(g(r)), s = E({
396
396
  initialData: r,
397
397
  data: t
398
398
  });
399
- E(r, (f) => {
400
- s.data = y(f);
399
+ y(r, (f) => {
400
+ s.data = g(f);
401
401
  });
402
- const a = ar(s, e), o = H(s, a), v = Q(o), c = () => {
403
- t.value = y(r), o.getFields().forEach(
402
+ const a = ur(s, e), o = tr(s, a), h = sr(o), c = () => {
403
+ t.value = g(r), o.getFields().forEach(
404
404
  (f) => f.reset()
405
405
  );
406
406
  };
407
- function i(f, p) {
408
- return nr(l, f);
407
+ function n(f, v) {
408
+ return fr(l, f);
409
409
  }
410
410
  const l = {
411
411
  ...o,
412
412
  ...a,
413
- ...v,
413
+ ...h,
414
414
  reset: c,
415
- getSubForm: i,
416
- initialData: S(s, "initialData"),
417
- data: S(s, "data")
415
+ getSubForm: n,
416
+ initialData: D(s, "initialData"),
417
+ data: D(s, "data")
418
418
  };
419
419
  return l;
420
420
  }
421
- const Vr = /* @__PURE__ */ B({
421
+ const wr = /* @__PURE__ */ S({
422
422
  __name: "Field",
423
423
  props: {
424
424
  form: {},
@@ -430,11 +430,56 @@ const Vr = /* @__PURE__ */ B({
430
430
  setup(e) {
431
431
  const r = e, t = r.form.defineField({
432
432
  path: r.path
433
- }), s = m(t);
434
- return (a, o) => G(a.$slots, "default", L(U(s)));
433
+ }), s = E(t);
434
+ return (a, o) => j(a.$slots, "default", M(B(s)));
435
+ }
436
+ }), Pr = /* @__PURE__ */ S({
437
+ inheritAttrs: !1,
438
+ __name: "FormFieldWrapper",
439
+ props: {
440
+ component: {},
441
+ componentProps: {},
442
+ form: {},
443
+ path: {}
444
+ },
445
+ setup(e) {
446
+ return (r, t) => {
447
+ const s = Q("Field");
448
+ return $(), O(s, {
449
+ form: r.form,
450
+ path: r.path
451
+ }, {
452
+ default: A(({ errors: a, data: o, setData: h }) => [
453
+ ($(), O(X(r.component), Y({ ...r.componentProps, ...r.$attrs }, {
454
+ "model-value": o,
455
+ errors: a,
456
+ name: r.path,
457
+ "onUpdate:modelValue": h
458
+ }), {
459
+ default: A(() => [
460
+ j(r.$slots, "default")
461
+ ]),
462
+ _: 2
463
+ }, 1040, ["model-value", "errors", "name", "onUpdate:modelValue"]))
464
+ ]),
465
+ _: 3
466
+ }, 8, ["form", "path"]);
467
+ };
468
+ }
469
+ }), _r = /* @__PURE__ */ S({
470
+ __name: "FormPart",
471
+ props: {
472
+ form: {},
473
+ path: {}
474
+ },
475
+ setup(e) {
476
+ const r = e, t = u(() => r.form.getSubForm(r.path));
477
+ return (s, a) => j(s.$slots, "default", M(B({ subform: t.value })));
435
478
  }
436
479
  });
437
480
  export {
438
- Vr as Field,
439
- pr as useForm
481
+ wr as Field,
482
+ Pr as FormFieldWrapper,
483
+ _r as FormPart,
484
+ Er as useForm
440
485
  };
@@ -0,0 +1,8 @@
1
+ import { ObjectOf, Paths } from './util';
2
+ import { Form } from './form';
3
+ import { DeepPartial } from '../utils/type-helpers';
4
+ export interface FormComponentProps<TData extends object, TPath extends Paths<TData>, TModelValueType> {
5
+ form: Form<TData & DeepPartial<ObjectOf<TPath, TModelValueType>>>;
6
+ path: TPath;
7
+ }
8
+ export type ExcludedFieldProps = 'modelValue' | 'onUpdate:modelValue' | 'errors';
@@ -10,9 +10,12 @@ export type PickProps<Entity, PropertyKeys extends string> = Entity extends NonN
10
10
  /**
11
11
  * Resolves to a union of dot-connected paths of all nested properties of T.
12
12
  */
13
- export type Paths<T, Seen = never> = T extends Seen ? never : T extends Array<infer ArrayType> ? `${number}` | `${number}.${Paths<ArrayType, Seen | T>}` : T extends object ? {
14
- [K in keyof T]-?: `${Exclude<K, symbol>}${'' | `.${Paths<T[K], Seen | T>}`}`;
13
+ type AntiCollapse = '__anticollapse__';
14
+ type CleanupAntiCollapse<T extends string> = T extends `${infer Left}${AntiCollapse}${infer Right}` ? `${Left}${CleanupAntiCollapse<Right>}` : T;
15
+ type RecursePaths<T, Seen = never> = T extends Seen ? never : T extends Array<infer ArrayType> ? `${number}` | `${number}.${RecursePaths<ArrayType, Seen | T>}` : T extends object ? {
16
+ [K in keyof T]-?: `${AntiCollapse}${Exclude<K, symbol>}${'' | `.${RecursePaths<T[K], Seen | T>}`}`;
15
17
  }[keyof T] : never;
18
+ export type Paths<T, Seen = never> = CleanupAntiCollapse<RecursePaths<T, Seen>>;
16
19
  /**
17
20
  * Removes the last part of a dot-connected path.
18
21
  */
@@ -28,3 +31,4 @@ export type RootPath<P extends string> = P extends `${infer TRoot}.${string}` ?
28
31
  export type ObjectOf<TPath extends string, T> = {
29
32
  [K in RootPath<TPath>]: RestPath<K, TPath> extends never ? T : ObjectOf<RestPath<K, TPath>, T>;
30
33
  };
34
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teamnovu/kit-vue-forms",
3
- "version": "0.0.15",
3
+ "version": "0.0.17",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "exports": {
@@ -29,6 +29,7 @@
29
29
  },
30
30
  "dependencies": {
31
31
  "@vueuse/core": "^13.5.0",
32
+ "vue-component-type-helpers": "^3.0.5",
32
33
  "zod": "^4"
33
34
  },
34
35
  "scripts": {
@@ -0,0 +1,42 @@
1
+ <template>
2
+ <Field
3
+ v-slot="{ errors, data, setData }"
4
+ :form="form"
5
+ :path="path"
6
+ >
7
+ <component
8
+ :is="component"
9
+ v-bind="{...componentProps, ...$attrs}"
10
+ :model-value="data"
11
+ :errors="errors"
12
+ :name="path"
13
+ @update:model-value="setData"
14
+ >
15
+ <slot />
16
+ </component>
17
+ </Field>
18
+ </template>
19
+
20
+ <script
21
+ setup
22
+ lang="ts"
23
+ generic="TData extends object, TPath extends Paths<TData>, TComponent extends Component"
24
+ >
25
+ import { type Component } from 'vue'
26
+ import type { ComponentProps } from 'vue-component-type-helpers'
27
+ import type { Paths } from '../types/util.ts'
28
+ import type { Form } from '../types/form.ts'
29
+
30
+ export interface FormFieldWrapperProps<TData extends object, TPath extends string, TComponent> {
31
+ component: TComponent
32
+ componentProps: Omit<ComponentProps<TComponent>, 'modelValue' | 'update:modelValue' | 'errors'>
33
+ form: Form<TData>
34
+ path: TPath
35
+ }
36
+
37
+ defineOptions({
38
+ inheritAttrs: false,
39
+ })
40
+
41
+ defineProps<FormFieldWrapperProps<TData, TPath, TComponent>>()
42
+ </script>
@@ -0,0 +1,22 @@
1
+ <template>
2
+ <slot v-bind="{ subform }" />
3
+ </template>
4
+
5
+ <script
6
+ setup
7
+ lang="ts"
8
+ generic="TData extends object, TPath extends EntityPaths<TData>"
9
+ >
10
+ import { computed } from 'vue'
11
+ import type { Form } from '../types/form.ts'
12
+ import type { EntityPaths } from '../types/util.ts'
13
+
14
+ export interface FormPartProps<TData extends object, TPath> {
15
+ form: Form<TData>
16
+ path: TPath
17
+ }
18
+
19
+ const props = defineProps<FormPartProps<TData, TPath>>()
20
+
21
+ const subform = computed(() => props.form.getSubForm(props.path))
22
+ </script>
package/src/index.ts CHANGED
@@ -12,5 +12,14 @@ export type { DeepPartial } from './utils/type-helpers'
12
12
  export type { Form, FormField } from './types/form'
13
13
  export type { SplitPath, Paths, PickProps, ObjectOf, EntityPaths } from './types/util'
14
14
 
15
+ export type { FormComponentProps, ExcludedFieldProps } from './types/FormComponentProps'
16
+
17
+ // Vue Components
15
18
  export { default as Field } from './components/Field.vue'
16
19
  export type { FieldProps } from './components/Field.vue'
20
+
21
+ export { default as FormFieldWrapper } from './components/FormFieldWrapper.vue'
22
+ export type { FormFieldWrapperProps } from './components/FormFieldWrapper.vue'
23
+
24
+ export { default as FormPart } from './components/FormPart.vue'
25
+ export type { FormPartProps } from './components/FormPart.vue'
@@ -0,0 +1,14 @@
1
+ import type { ObjectOf, Paths } from './util'
2
+ import type { Form } from './form'
3
+ import type { DeepPartial } from '../utils/type-helpers'
4
+
5
+ export interface FormComponentProps<
6
+ TData extends object,
7
+ TPath extends Paths<TData>,
8
+ TModelValueType,
9
+ > {
10
+ form: Form<TData & DeepPartial<ObjectOf<TPath, TModelValueType>>>
11
+ path: TPath
12
+ }
13
+
14
+ export type ExcludedFieldProps = 'modelValue' | 'onUpdate:modelValue' | 'errors'
package/src/types/util.ts CHANGED
@@ -45,15 +45,22 @@ export type PickProps<Entity, PropertyKeys extends string> =
45
45
  /**
46
46
  * Resolves to a union of dot-connected paths of all nested properties of T.
47
47
  */
48
- export type Paths<T, Seen = never> =
48
+
49
+ type AntiCollapse = '__anticollapse__'
50
+ type CleanupAntiCollapse<T extends string> =
51
+ T extends `${infer Left}${AntiCollapse}${infer Right}` ? `${Left}${CleanupAntiCollapse<Right>}` : T
52
+
53
+ type RecursePaths<T, Seen = never> =
49
54
  T extends Seen ? never :
50
- T extends Array<infer ArrayType> ? `${number}` | `${number}.${Paths<ArrayType, Seen | T>}` :
55
+ T extends Array<infer ArrayType> ? `${number}` | `${number}.${RecursePaths<ArrayType, Seen | T>}` :
51
56
  T extends object
52
57
  ? {
53
- [K in keyof T]-?: `${Exclude<K, symbol>}${'' | `.${Paths<T[K], Seen | T>}`}`
58
+ [K in keyof T]-?: `${AntiCollapse}${Exclude<K, symbol>}${'' | `.${RecursePaths<T[K], Seen | T>}`}`
54
59
  }[keyof T]
55
60
  : never
56
61
 
62
+ export type Paths<T, Seen = never> = CleanupAntiCollapse<RecursePaths<T, Seen>>
63
+
57
64
  /**
58
65
  * Removes the last part of a dot-connected path.
59
66
  */