@macrulez/vue-form-schema 0.1.7 → 0.1.9

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.
Files changed (46) hide show
  1. package/LICENSE +21 -0
  2. package/dist/MaskEngine-DAKSNIHQ.cjs +1 -0
  3. package/dist/MaskEngine-mLoXKd4d.js +251 -0
  4. package/dist/core/ValidationEngine.d.ts +6 -0
  5. package/dist/core/ValidationEngine.d.ts.map +1 -1
  6. package/dist/core/types.d.ts +10 -2
  7. package/dist/core/types.d.ts.map +1 -1
  8. package/dist/core/useForm.d.ts.map +1 -1
  9. package/dist/index.cjs +1 -1
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +159 -151
  13. package/dist/ui/index.d.ts +1 -0
  14. package/dist/ui/index.d.ts.map +1 -1
  15. package/dist/ui/tailwind/index.d.ts +11 -0
  16. package/dist/ui/tailwind/index.d.ts.map +1 -0
  17. package/dist/ui-tailwind.cjs +1 -0
  18. package/dist/ui-tailwind.d.ts +397 -0
  19. package/dist/ui-tailwind.js +650 -0
  20. package/dist/ui.cjs +1 -1
  21. package/dist/ui.d.ts +47 -10
  22. package/dist/ui.js +436 -300
  23. package/dist/valibot.d.ts +10 -2
  24. package/dist/yup.d.ts +10 -2
  25. package/dist/zod.d.ts +10 -2
  26. package/package.json +38 -24
  27. package/dist/MaskEngine-BqJQYybS.js +0 -233
  28. package/dist/MaskEngine-BwAs2Zb0.cjs +0 -1
  29. package/dist/__tests__/ConditionEvaluator.test.d.ts +0 -2
  30. package/dist/__tests__/ConditionEvaluator.test.d.ts.map +0 -1
  31. package/dist/__tests__/MaskEngine.test.d.ts +0 -2
  32. package/dist/__tests__/MaskEngine.test.d.ts.map +0 -1
  33. package/dist/__tests__/ValidationEngine.test.d.ts +0 -2
  34. package/dist/__tests__/ValidationEngine.test.d.ts.map +0 -1
  35. package/dist/__tests__/parsers.test.d.ts +0 -2
  36. package/dist/__tests__/parsers.test.d.ts.map +0 -1
  37. package/dist/__tests__/phase3.test.d.ts +0 -2
  38. package/dist/__tests__/phase3.test.d.ts.map +0 -1
  39. package/dist/__tests__/phase4.test.d.ts +0 -2
  40. package/dist/__tests__/phase4.test.d.ts.map +0 -1
  41. package/dist/__tests__/useFieldArray.test.d.ts +0 -2
  42. package/dist/__tests__/useFieldArray.test.d.ts.map +0 -1
  43. package/dist/__tests__/useForm.test.d.ts +0 -2
  44. package/dist/__tests__/useForm.test.d.ts.map +0 -1
  45. package/dist/__tests__/useMultiStepForm.test.d.ts +0 -2
  46. package/dist/__tests__/useMultiStepForm.test.d.ts.map +0 -1
@@ -0,0 +1,650 @@
1
+ import { defineComponent as V, computed as $, openBlock as l, createElementBlock as u, createTextVNode as N, toDisplayString as x, createCommentVNode as p, renderSlot as E, normalizeProps as J, guardReactiveProps as O, Fragment as w, renderList as F, ref as I, onMounted as Q, onUnmounted as W, createBlock as k, withCtx as B, createElementVNode as g, mergeProps as C, withModifiers as X, normalizeClass as Y, unref as D, resolveDynamicComponent as z, resolveComponent as Z } from "vue";
2
+ import { b as _, t as U, q as ee, h as M } from "./MaskEngine-mLoXKd4d.js";
3
+ const te = { class: "mb-4" }, re = ["for"], le = {
4
+ key: 0,
5
+ class: "text-red-400 ml-0.5",
6
+ "aria-hidden": "true"
7
+ }, oe = ["id"], T = /* @__PURE__ */ V({
8
+ __name: "BaseField",
9
+ props: {
10
+ field: {},
11
+ error: {},
12
+ touched: { type: Boolean }
13
+ },
14
+ setup(e) {
15
+ const m = e, r = $(() => {
16
+ var n;
17
+ return !!(m.touched && ((n = m.error) != null && n.length));
18
+ }), c = $(() => `${m.field.name}-error`), a = $(() => ({
19
+ "aria-required": m.field.required ? "true" : void 0,
20
+ "aria-invalid": r.value ? "true" : "false",
21
+ "aria-describedby": r.value ? c.value : void 0
22
+ }));
23
+ return (n, d) => (l(), u("div", te, [
24
+ e.field.label ? (l(), u("label", {
25
+ key: 0,
26
+ for: e.field.name,
27
+ class: "block text-xs font-semibold uppercase tracking-wider text-gray-400 mb-1.5"
28
+ }, [
29
+ N(x(e.field.label) + " ", 1),
30
+ e.field.required ? (l(), u("span", le, "*")) : p("", !0)
31
+ ], 8, re)) : p("", !0),
32
+ E(n.$slots, "default", J(O(a.value))),
33
+ r.value ? (l(), u("ul", {
34
+ key: 1,
35
+ id: c.value,
36
+ class: "mt-1 space-y-0.5",
37
+ role: "alert",
38
+ "aria-live": "polite"
39
+ }, [
40
+ (l(!0), u(w, null, F(e.error, (i, f) => (l(), u("li", {
41
+ key: f,
42
+ class: "text-red-400 text-xs"
43
+ }, x(i), 1))), 128))
44
+ ], 8, oe)) : p("", !0)
45
+ ]));
46
+ }
47
+ }), ae = ["id", "type", "name", "value", "placeholder", "disabled", "required"], A = /* @__PURE__ */ V({
48
+ __name: "TextField",
49
+ props: {
50
+ field: {},
51
+ modelValue: {},
52
+ error: {},
53
+ touched: { type: Boolean }
54
+ },
55
+ emits: ["update:modelValue", "blur"],
56
+ setup(e, { emit: m }) {
57
+ const r = e, c = m, a = I(null);
58
+ let n = null;
59
+ const d = $(() => {
60
+ var i;
61
+ return !!(r.touched && ((i = r.error) != null && i.length));
62
+ });
63
+ return Q(() => {
64
+ a.value && r.field.mask && (n = _(a.value, r.field.mask));
65
+ }), W(() => n == null ? void 0 : n()), (i, f) => (l(), k(T, {
66
+ field: e.field,
67
+ error: e.error,
68
+ touched: e.touched
69
+ }, {
70
+ default: B((b) => [
71
+ g("input", C({
72
+ id: e.field.name,
73
+ ref_key: "inputRef",
74
+ ref: a,
75
+ type: e.field.type === "email" ? "email" : "text",
76
+ name: e.field.name,
77
+ value: e.modelValue ?? "",
78
+ placeholder: e.field.placeholder,
79
+ disabled: e.field.disabled === !0,
80
+ required: e.field.required
81
+ }, b, {
82
+ class: ["w-full rounded-lg border bg-gray-900 px-3 py-2 text-sm text-gray-100 placeholder-gray-500 outline-none transition focus:ring-2 disabled:cursor-not-allowed disabled:opacity-50", d.value ? "border-red-500 focus:ring-red-500" : "border-gray-700 focus:ring-indigo-500 focus:border-indigo-500"],
83
+ onInput: f[0] || (f[0] = (y) => c("update:modelValue", y.target.value)),
84
+ onBlur: f[1] || (f[1] = (y) => c("blur"))
85
+ }), null, 16, ae)
86
+ ]),
87
+ _: 1
88
+ }, 8, ["field", "error", "touched"]));
89
+ }
90
+ }), ne = ["id", "name", "value", "placeholder", "disabled", "required"], P = /* @__PURE__ */ V({
91
+ __name: "NumberField",
92
+ props: {
93
+ field: {},
94
+ modelValue: {},
95
+ error: {},
96
+ touched: { type: Boolean }
97
+ },
98
+ emits: ["update:modelValue", "blur"],
99
+ setup(e, { emit: m }) {
100
+ const r = e, c = m, a = $(() => {
101
+ var d;
102
+ return !!(r.touched && ((d = r.error) != null && d.length));
103
+ });
104
+ function n(d) {
105
+ const i = d.target.value;
106
+ c("update:modelValue", i === "" ? null : Number(i));
107
+ }
108
+ return (d, i) => (l(), k(T, {
109
+ field: e.field,
110
+ error: e.error,
111
+ touched: e.touched
112
+ }, {
113
+ default: B((f) => [
114
+ g("input", C({
115
+ id: e.field.name,
116
+ type: "number",
117
+ name: e.field.name,
118
+ value: e.modelValue ?? "",
119
+ placeholder: e.field.placeholder,
120
+ disabled: e.field.disabled === !0,
121
+ required: e.field.required
122
+ }, f, {
123
+ class: ["w-full rounded-lg border bg-gray-900 px-3 py-2 text-sm text-gray-100 placeholder-gray-500 outline-none transition focus:ring-2 disabled:cursor-not-allowed disabled:opacity-50", a.value ? "border-red-500 focus:ring-red-500" : "border-gray-700 focus:ring-indigo-500 focus:border-indigo-500"],
124
+ onInput: n,
125
+ onBlur: i[0] || (i[0] = (b) => c("blur"))
126
+ }), null, 16, ne)
127
+ ]),
128
+ _: 1
129
+ }, 8, ["field", "error", "touched"]));
130
+ }
131
+ }), de = ["id", "name", "value", "placeholder", "disabled", "required"], L = /* @__PURE__ */ V({
132
+ __name: "TextareaField",
133
+ props: {
134
+ field: {},
135
+ modelValue: {},
136
+ error: {},
137
+ touched: { type: Boolean }
138
+ },
139
+ emits: ["update:modelValue", "blur"],
140
+ setup(e, { emit: m }) {
141
+ const r = e, c = m, a = $(() => {
142
+ var n;
143
+ return !!(r.touched && ((n = r.error) != null && n.length));
144
+ });
145
+ return (n, d) => (l(), k(T, {
146
+ field: e.field,
147
+ error: e.error,
148
+ touched: e.touched
149
+ }, {
150
+ default: B((i) => [
151
+ g("textarea", C({
152
+ id: e.field.name,
153
+ name: e.field.name,
154
+ value: e.modelValue ?? "",
155
+ placeholder: e.field.placeholder,
156
+ disabled: e.field.disabled === !0,
157
+ required: e.field.required
158
+ }, i, {
159
+ class: ["w-full resize-y rounded-lg border bg-gray-900 px-3 py-2 text-sm text-gray-100 placeholder-gray-500 outline-none transition focus:ring-2 disabled:cursor-not-allowed disabled:opacity-50", a.value ? "border-red-500 focus:ring-red-500" : "border-gray-700 focus:ring-indigo-500 focus:border-indigo-500"],
160
+ style: { "min-height": "80px" },
161
+ onInput: d[0] || (d[0] = (f) => c("update:modelValue", f.target.value)),
162
+ onBlur: d[1] || (d[1] = (f) => c("blur"))
163
+ }), null, 16, de)
164
+ ]),
165
+ _: 1
166
+ }, 8, ["field", "error", "touched"]));
167
+ }
168
+ }), ie = {
169
+ key: 0,
170
+ class: "py-2 text-sm text-gray-400"
171
+ }, ue = ["id", "name", "disabled", "required"], se = ["selected"], ce = ["value", "selected"], j = /* @__PURE__ */ V({
172
+ __name: "SelectField",
173
+ props: {
174
+ field: {},
175
+ modelValue: {},
176
+ error: {},
177
+ touched: { type: Boolean }
178
+ },
179
+ emits: ["update:modelValue", "blur"],
180
+ setup(e, { emit: m }) {
181
+ const r = e, c = m, a = $(
182
+ () => Array.isArray(r.field.options) ? r.field.options : []
183
+ ), n = $(() => {
184
+ var i;
185
+ return !!(r.touched && ((i = r.error) != null && i.length));
186
+ });
187
+ function d(i) {
188
+ const f = i.target, b = a.value.find((y) => String(y.value) === f.value);
189
+ c("update:modelValue", (b == null ? void 0 : b.value) ?? f.value);
190
+ }
191
+ return (i, f) => (l(), k(T, {
192
+ field: e.field,
193
+ error: e.error,
194
+ touched: e.touched
195
+ }, {
196
+ default: B((b) => [
197
+ e.field.optionsLoading ? (l(), u("div", ie, "Loading…")) : (l(), u("select", C({
198
+ key: 1,
199
+ id: e.field.name,
200
+ name: e.field.name,
201
+ disabled: e.field.disabled === !0 || e.field.optionsLoading,
202
+ required: e.field.required
203
+ }, b, {
204
+ class: ["w-full rounded-lg border bg-gray-900 px-3 py-2 text-sm text-gray-100 outline-none transition focus:ring-2 disabled:cursor-not-allowed disabled:opacity-50", n.value ? "border-red-500 focus:ring-red-500" : "border-gray-700 focus:ring-indigo-500 focus:border-indigo-500"],
205
+ onChange: d,
206
+ onBlur: f[0] || (f[0] = (y) => c("blur"))
207
+ }), [
208
+ g("option", {
209
+ value: "",
210
+ disabled: "",
211
+ selected: e.modelValue === null || e.modelValue === void 0 || e.modelValue === "",
212
+ class: "bg-gray-800"
213
+ }, x(e.field.placeholder ?? "Select an option"), 9, se),
214
+ (l(!0), u(w, null, F(a.value, (y) => (l(), u("option", {
215
+ key: String(y.value),
216
+ value: String(y.value),
217
+ selected: e.modelValue === y.value,
218
+ class: "bg-gray-800"
219
+ }, x(y.label), 9, ce))), 128))
220
+ ], 16, ue))
221
+ ]),
222
+ _: 1
223
+ }, 8, ["field", "error", "touched"]));
224
+ }
225
+ }), me = { class: "flex cursor-pointer items-center gap-2.5" }, fe = ["id", "name", "checked", "disabled", "required", "aria-checked"], be = {
226
+ key: 0,
227
+ class: "text-sm text-gray-200"
228
+ }, K = /* @__PURE__ */ V({
229
+ __name: "CheckboxField",
230
+ props: {
231
+ field: {},
232
+ modelValue: { type: [Boolean, null] },
233
+ error: {},
234
+ touched: { type: Boolean }
235
+ },
236
+ emits: ["update:modelValue", "blur"],
237
+ setup(e, { emit: m }) {
238
+ const r = m;
239
+ return (c, a) => (l(), k(T, {
240
+ field: { ...e.field, label: void 0 },
241
+ error: e.error,
242
+ touched: e.touched
243
+ }, {
244
+ default: B((n) => [
245
+ g("label", me, [
246
+ g("input", C({
247
+ id: e.field.name,
248
+ type: "checkbox",
249
+ name: e.field.name,
250
+ checked: !!e.modelValue,
251
+ disabled: e.field.disabled === !0,
252
+ required: e.field.required,
253
+ "aria-checked": e.modelValue ? "true" : "false"
254
+ }, n, {
255
+ class: "h-4 w-4 cursor-pointer rounded border-gray-600 bg-gray-900 text-indigo-500 accent-indigo-500 disabled:cursor-not-allowed disabled:opacity-50",
256
+ onChange: a[0] || (a[0] = (d) => r("update:modelValue", d.target.checked)),
257
+ onBlur: a[1] || (a[1] = (d) => r("blur"))
258
+ }), null, 16, fe),
259
+ e.field.label ? (l(), u("span", be, x(e.field.label), 1)) : p("", !0)
260
+ ])
261
+ ]),
262
+ _: 1
263
+ }, 8, ["field", "error", "touched"]));
264
+ }
265
+ }), ge = ["aria-required", "aria-invalid", "aria-describedby"], ye = {
266
+ key: 0,
267
+ class: "block text-xs font-semibold uppercase tracking-wider text-gray-400 mb-2"
268
+ }, he = {
269
+ key: 0,
270
+ class: "text-red-400 ml-0.5",
271
+ "aria-hidden": "true"
272
+ }, ve = { class: "space-y-2" }, xe = ["name", "value", "checked", "disabled", "onChange"], $e = { class: "text-sm text-gray-200" }, pe = ["id"], G = /* @__PURE__ */ V({
273
+ __name: "RadioField",
274
+ props: {
275
+ field: {},
276
+ modelValue: {},
277
+ error: {},
278
+ touched: { type: Boolean }
279
+ },
280
+ emits: ["update:modelValue", "blur"],
281
+ setup(e, { emit: m }) {
282
+ const r = e, c = m, a = $(() => {
283
+ var i;
284
+ return !!(r.touched && ((i = r.error) != null && i.length));
285
+ }), n = $(() => `${r.field.name}-error`), d = $(
286
+ () => Array.isArray(r.field.options) ? r.field.options : []
287
+ );
288
+ return (i, f) => (l(), u("fieldset", {
289
+ class: "mb-4",
290
+ "aria-required": e.field.required ? "true" : void 0,
291
+ "aria-invalid": a.value ? "true" : "false",
292
+ "aria-describedby": a.value ? n.value : void 0
293
+ }, [
294
+ e.field.label ? (l(), u("legend", ye, [
295
+ N(x(e.field.label) + " ", 1),
296
+ e.field.required ? (l(), u("span", he, "*")) : p("", !0)
297
+ ])) : p("", !0),
298
+ g("div", ve, [
299
+ (l(!0), u(w, null, F(d.value, (b) => (l(), u("label", {
300
+ key: String(b.value),
301
+ class: "flex cursor-pointer items-center gap-2.5"
302
+ }, [
303
+ g("input", {
304
+ type: "radio",
305
+ name: e.field.name,
306
+ value: String(b.value),
307
+ checked: e.modelValue === b.value,
308
+ disabled: e.field.disabled === !0,
309
+ class: "h-4 w-4 cursor-pointer border-gray-600 bg-gray-900 text-indigo-500 accent-indigo-500 disabled:cursor-not-allowed disabled:opacity-50",
310
+ onChange: (y) => c("update:modelValue", b.value),
311
+ onBlur: f[0] || (f[0] = (y) => c("blur"))
312
+ }, null, 40, xe),
313
+ g("span", $e, x(b.label), 1)
314
+ ]))), 128))
315
+ ]),
316
+ a.value ? (l(), u("ul", {
317
+ key: 1,
318
+ id: n.value,
319
+ class: "mt-1 space-y-0.5",
320
+ role: "alert",
321
+ "aria-live": "polite"
322
+ }, [
323
+ (l(!0), u(w, null, F(e.error, (b, y) => (l(), u("li", {
324
+ key: y,
325
+ class: "text-red-400 text-xs"
326
+ }, x(b), 1))), 128))
327
+ ], 8, pe)) : p("", !0)
328
+ ], 8, ge));
329
+ }
330
+ }), ke = ["id", "name", "value", "disabled", "required"], H = /* @__PURE__ */ V({
331
+ __name: "DateField",
332
+ props: {
333
+ field: {},
334
+ modelValue: {},
335
+ error: {},
336
+ touched: { type: Boolean }
337
+ },
338
+ emits: ["update:modelValue", "blur"],
339
+ setup(e, { emit: m }) {
340
+ const r = e, c = m, a = $(() => {
341
+ var n;
342
+ return !!(r.touched && ((n = r.error) != null && n.length));
343
+ });
344
+ return (n, d) => (l(), k(T, {
345
+ field: e.field,
346
+ error: e.error,
347
+ touched: e.touched
348
+ }, {
349
+ default: B((i) => [
350
+ g("input", C({
351
+ id: e.field.name,
352
+ type: "date",
353
+ name: e.field.name,
354
+ value: e.modelValue ?? "",
355
+ disabled: e.field.disabled === !0,
356
+ required: e.field.required
357
+ }, i, {
358
+ class: ["w-full rounded-lg border bg-gray-900 px-3 py-2 text-sm text-gray-100 outline-none transition focus:ring-2 disabled:cursor-not-allowed disabled:opacity-50", a.value ? "border-red-500 focus:ring-red-500" : "border-gray-700 focus:ring-indigo-500 focus:border-indigo-500"],
359
+ onInput: d[0] || (d[0] = (f) => c("update:modelValue", f.target.value)),
360
+ onBlur: d[1] || (d[1] = (f) => c("blur"))
361
+ }), null, 16, ke)
362
+ ]),
363
+ _: 1
364
+ }, 8, ["field", "error", "touched"]));
365
+ }
366
+ }), Ve = ["id", "name", "accept", "multiple", "disabled", "required"], we = { class: "pointer-events-none space-y-1" }, Fe = { class: "text-sm text-gray-300" }, qe = {
367
+ key: 0,
368
+ class: "text-xs text-gray-500"
369
+ }, Be = {
370
+ key: 0,
371
+ class: "mt-2 space-y-1"
372
+ }, Ce = { class: "truncate text-gray-200" }, Te = { class: "ml-2 shrink-0 text-xs text-gray-500" }, Se = ["aria-label", "onClick"], Re = /* @__PURE__ */ V({
373
+ __name: "FileField",
374
+ props: {
375
+ field: {},
376
+ modelValue: {},
377
+ error: {},
378
+ touched: { type: Boolean }
379
+ },
380
+ emits: ["update:modelValue", "blur"],
381
+ setup(e, { emit: m }) {
382
+ const r = e, c = m, a = I(!1), n = I(null), d = $(() => r.modelValue ? Array.isArray(r.modelValue) ? r.modelValue : [r.modelValue] : []), i = $(() => r.field.multiple ?? !1);
383
+ function f(o) {
384
+ if (!o || o.length === 0) {
385
+ c("update:modelValue", null);
386
+ return;
387
+ }
388
+ c("update:modelValue", i.value ? Array.from(o) : o[0]);
389
+ }
390
+ function b(o) {
391
+ f(o.target.files), c("blur");
392
+ }
393
+ function y(o) {
394
+ var t;
395
+ a.value = !1, o.preventDefault(), f(((t = o.dataTransfer) == null ? void 0 : t.files) ?? null), c("blur");
396
+ }
397
+ function S(o) {
398
+ const t = d.value.filter((h, v) => v !== o);
399
+ t.length === 0 ? (c("update:modelValue", null), n.value && (n.value.value = "")) : c("update:modelValue", i.value ? t : t[0]);
400
+ }
401
+ function R(o) {
402
+ return o < 1024 ? `${o} B` : o < 1024 * 1024 ? `${(o / 1024).toFixed(1)} KB` : `${(o / (1024 * 1024)).toFixed(1)} MB`;
403
+ }
404
+ return (o, t) => (l(), k(T, {
405
+ field: e.field,
406
+ error: e.error,
407
+ touched: e.touched
408
+ }, {
409
+ default: B((h) => {
410
+ var v;
411
+ return [
412
+ g("div", {
413
+ class: Y(["relative rounded-lg border-2 border-dashed p-6 text-center transition", a.value ? "border-indigo-500 bg-indigo-500/10" : e.touched && ((v = e.error) != null && v.length) ? "border-red-500 bg-red-500/5" : "border-gray-700 bg-gray-900 hover:border-gray-500"]),
414
+ onDragover: t[0] || (t[0] = X((s) => a.value = !0, ["prevent"])),
415
+ onDragleave: t[1] || (t[1] = (s) => a.value = !1),
416
+ onDrop: y
417
+ }, [
418
+ g("input", C({
419
+ id: e.field.name,
420
+ ref_key: "inputRef",
421
+ ref: n,
422
+ type: "file",
423
+ name: e.field.name,
424
+ accept: e.field.accept,
425
+ multiple: i.value,
426
+ disabled: e.field.disabled === !0,
427
+ required: e.field.required
428
+ }, h, {
429
+ class: "absolute inset-0 h-full w-full cursor-pointer opacity-0 disabled:cursor-not-allowed",
430
+ onChange: b
431
+ }), null, 16, Ve),
432
+ g("div", we, [
433
+ t[2] || (t[2] = g("div", { class: "text-2xl" }, "📁", -1)),
434
+ g("p", Fe, x(a.value ? "Drop files here" : "Click to upload or drag & drop"), 1),
435
+ e.field.accept ? (l(), u("p", qe, x(e.field.accept), 1)) : p("", !0)
436
+ ])
437
+ ], 34),
438
+ d.value.length ? (l(), u("ul", Be, [
439
+ (l(!0), u(w, null, F(d.value, (s, q) => (l(), u("li", {
440
+ key: `${s.name}-${q}`,
441
+ class: "flex items-center justify-between rounded-lg border border-gray-700 bg-gray-900 px-3 py-2 text-sm"
442
+ }, [
443
+ g("span", Ce, x(s.name), 1),
444
+ g("span", Te, x(R(s.size)), 1),
445
+ g("button", {
446
+ type: "button",
447
+ "aria-label": `Remove ${s.name}`,
448
+ class: "ml-2 shrink-0 text-gray-500 hover:text-red-400 transition",
449
+ onClick: (Pe) => S(q)
450
+ }, " × ", 8, Se)
451
+ ]))), 128))
452
+ ])) : p("", !0)
453
+ ];
454
+ }),
455
+ _: 1
456
+ }, 8, ["field", "error", "touched"]));
457
+ }
458
+ }), Ae = { class: "mb-4" }, De = {
459
+ key: 0,
460
+ class: "block text-xs font-semibold uppercase tracking-wider text-gray-400 mb-2"
461
+ }, Ee = { class: "flex-1 space-y-0" }, Ie = ["onClick"], Ne = /* @__PURE__ */ V({
462
+ __name: "ArrayField",
463
+ props: {
464
+ field: {},
465
+ form: {},
466
+ components: {}
467
+ },
468
+ setup(e) {
469
+ const m = e, r = U(), c = {
470
+ text: A,
471
+ email: A,
472
+ number: P,
473
+ textarea: L,
474
+ select: j,
475
+ checkbox: K,
476
+ radio: G,
477
+ date: H
478
+ };
479
+ function a(o) {
480
+ var t;
481
+ return o.component ? o.component : ((t = m.components) == null ? void 0 : t[o.type]) ?? r[o.type] ?? c[o.type] ?? null;
482
+ }
483
+ const { rows: n, append: d, remove: i } = ee(m.form, m.field.name);
484
+ function f(o) {
485
+ return M(m.form.values.value, o.name);
486
+ }
487
+ function b(o, t) {
488
+ m.form.setField(o.name, t);
489
+ }
490
+ function y(o) {
491
+ var h;
492
+ const t = m.form;
493
+ (h = t.touchField) == null || h.call(t, o.name);
494
+ }
495
+ function S(o) {
496
+ return m.form.errors.value[o.name] ?? [];
497
+ }
498
+ function R(o) {
499
+ return m.form.touched.value[o.name] ?? !1;
500
+ }
501
+ return (o, t) => (l(), u("div", Ae, [
502
+ e.field.label ? (l(), u("div", De, x(e.field.label), 1)) : p("", !0),
503
+ (l(!0), u(w, null, F(D(n), (h) => (l(), u("div", {
504
+ key: h.key,
505
+ class: "mb-2 flex items-start gap-2 rounded-lg border border-gray-700 bg-gray-900 p-3"
506
+ }, [
507
+ g("div", Ee, [
508
+ (l(!0), u(w, null, F(h.fields, (v) => (l(), u(w, {
509
+ key: v.name
510
+ }, [
511
+ a(v) ? (l(), k(z(a(v)), {
512
+ key: 0,
513
+ field: v,
514
+ "model-value": f(v),
515
+ error: S(v),
516
+ touched: R(v),
517
+ "onUpdate:modelValue": (s) => b(v, s),
518
+ onBlur: (s) => y(v)
519
+ }, null, 40, ["field", "model-value", "error", "touched", "onUpdate:modelValue", "onBlur"])) : p("", !0)
520
+ ], 64))), 128))
521
+ ]),
522
+ g("button", {
523
+ type: "button",
524
+ class: "mt-7 shrink-0 rounded px-2 py-1 text-xs text-gray-500 hover:bg-red-500/10 hover:text-red-400 transition",
525
+ onClick: (v) => D(i)(h.index)
526
+ }, " Remove ", 8, Ie)
527
+ ]))), 128)),
528
+ g("button", {
529
+ type: "button",
530
+ class: "mt-1 rounded-lg border border-dashed border-gray-600 px-4 py-2 text-sm text-gray-400 hover:border-indigo-500 hover:text-indigo-400 transition",
531
+ onClick: t[0] || (t[0] = (h) => D(d)())
532
+ }, " + Add row ")
533
+ ]));
534
+ }
535
+ }), ze = {
536
+ key: 1,
537
+ class: "mb-4 rounded-lg border border-gray-700 p-4"
538
+ }, Ue = {
539
+ key: 0,
540
+ class: "px-1 text-xs font-semibold uppercase tracking-wider text-gray-400"
541
+ }, Me = ["disabled"], Ke = /* @__PURE__ */ V({
542
+ __name: "TailwindFormRenderer",
543
+ props: {
544
+ form: {},
545
+ components: {},
546
+ submitLabel: {}
547
+ },
548
+ emits: ["submit"],
549
+ setup(e, { emit: m }) {
550
+ const r = e, c = U(), a = m, n = {
551
+ text: A,
552
+ email: A,
553
+ number: P,
554
+ textarea: L,
555
+ select: j,
556
+ checkbox: K,
557
+ radio: G,
558
+ date: H,
559
+ file: Re
560
+ };
561
+ function d(t) {
562
+ var h;
563
+ return t.component ? t.component : ((h = r.components) == null ? void 0 : h[t.type]) ?? c[t.type] ?? n[t.type] ?? null;
564
+ }
565
+ function i(t) {
566
+ return M(r.form.values.value, t.name);
567
+ }
568
+ function f(t, h) {
569
+ r.form.setField(t.name, h);
570
+ }
571
+ function b(t) {
572
+ var v;
573
+ const h = r.form;
574
+ (v = h.touchField) == null || v.call(h, t.name);
575
+ }
576
+ function y(t) {
577
+ return r.form.errors.value[t.name] ?? [];
578
+ }
579
+ function S(t) {
580
+ return r.form.touched.value[t.name] ?? !1;
581
+ }
582
+ const R = $(() => r.form.fields.value.filter((t) => t.visible !== !1));
583
+ async function o(t) {
584
+ t.preventDefault(), await r.form.submit(), a("submit");
585
+ }
586
+ return (t, h) => {
587
+ const v = Z("TailwindFormRenderer", !0);
588
+ return l(), u("form", {
589
+ novalidate: "",
590
+ onSubmit: o
591
+ }, [
592
+ (l(!0), u(w, null, F(R.value, (s) => (l(), u(w, {
593
+ key: s.name
594
+ }, [
595
+ t.$slots[`field-${s.name}`] ? E(t.$slots, `field-${s.name}`, {
596
+ key: 0,
597
+ field: s,
598
+ value: i(s),
599
+ error: y(s),
600
+ touched: S(s),
601
+ setValue: (q) => f(s, q),
602
+ touch: () => b(s)
603
+ }) : s.type === "group" ? (l(), u("fieldset", ze, [
604
+ s.label ? (l(), u("legend", Ue, x(s.label), 1)) : p("", !0),
605
+ s.fields ? (l(), k(v, {
606
+ key: 1,
607
+ form: e.form,
608
+ components: e.components
609
+ }, null, 8, ["form", "components"])) : p("", !0)
610
+ ])) : s.type === "array" ? (l(), k(Ne, {
611
+ key: 2,
612
+ field: s,
613
+ form: e.form,
614
+ components: e.components
615
+ }, null, 8, ["field", "form", "components"])) : d(s) ? (l(), k(z(d(s)), {
616
+ key: 3,
617
+ field: s,
618
+ "model-value": i(s),
619
+ error: y(s),
620
+ touched: S(s),
621
+ "onUpdate:modelValue": (q) => f(s, q),
622
+ onBlur: (q) => b(s)
623
+ }, null, 40, ["field", "model-value", "error", "touched", "onUpdate:modelValue", "onBlur"])) : p("", !0)
624
+ ], 64))), 128)),
625
+ E(t.$slots, "submit", {
626
+ isSubmitting: e.form.isSubmitting.value,
627
+ isValid: e.form.isValid.value
628
+ }, () => [
629
+ g("button", {
630
+ type: "submit",
631
+ disabled: e.form.isSubmitting.value,
632
+ class: "mt-2 rounded-lg bg-indigo-600 px-5 py-2 text-sm font-medium text-white transition hover:bg-indigo-500 disabled:cursor-not-allowed disabled:opacity-40"
633
+ }, x(e.submitLabel ?? "Submit"), 9, Me)
634
+ ])
635
+ ], 32);
636
+ };
637
+ }
638
+ });
639
+ export {
640
+ Ke as TailwindFormRenderer,
641
+ Ne as TwArrayField,
642
+ K as TwCheckboxField,
643
+ H as TwDateField,
644
+ Re as TwFileField,
645
+ P as TwNumberField,
646
+ G as TwRadioField,
647
+ j as TwSelectField,
648
+ A as TwTextField,
649
+ L as TwTextareaField
650
+ };