@tachui/forms 0.7.0-alpha1

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 (62) hide show
  1. package/LICENSE +363 -0
  2. package/dist/Form-ueYEcSg1.cjs +2 -0
  3. package/dist/Form-ueYEcSg1.cjs.map +1 -0
  4. package/dist/Form-ylAr3o_e.js +376 -0
  5. package/dist/Form-ylAr3o_e.js.map +1 -0
  6. package/dist/components/Form.d.ts +76 -0
  7. package/dist/components/Form.d.ts.map +1 -0
  8. package/dist/components/index.cjs +2 -0
  9. package/dist/components/index.cjs.map +1 -0
  10. package/dist/components/index.d.ts +9 -0
  11. package/dist/components/index.d.ts.map +1 -0
  12. package/dist/components/index.js +31 -0
  13. package/dist/components/index.js.map +1 -0
  14. package/dist/components/input/Checkbox.d.ts +42 -0
  15. package/dist/components/input/Checkbox.d.ts.map +1 -0
  16. package/dist/components/input/Radio.d.ts +36 -0
  17. package/dist/components/input/Radio.d.ts.map +1 -0
  18. package/dist/components/input/Select.d.ts +21 -0
  19. package/dist/components/input/Select.d.ts.map +1 -0
  20. package/dist/components/input/TextField.d.ts +58 -0
  21. package/dist/components/input/TextField.d.ts.map +1 -0
  22. package/dist/components/input/index.d.ts +11 -0
  23. package/dist/components/input/index.d.ts.map +1 -0
  24. package/dist/forms-complex-BiQsZZlT.js +361 -0
  25. package/dist/forms-complex-BiQsZZlT.js.map +1 -0
  26. package/dist/forms-complex-DLEnXXJ5.cjs +2 -0
  27. package/dist/forms-complex-DLEnXXJ5.cjs.map +1 -0
  28. package/dist/forms-core-B1bx1drO.js +839 -0
  29. package/dist/forms-core-B1bx1drO.js.map +1 -0
  30. package/dist/forms-core-W_JGVLAI.cjs +9 -0
  31. package/dist/forms-core-W_JGVLAI.cjs.map +1 -0
  32. package/dist/forms-inputs-6QdeMWFk.js +1075 -0
  33. package/dist/forms-inputs-6QdeMWFk.js.map +1 -0
  34. package/dist/forms-inputs-DQ5QI_SU.cjs +2 -0
  35. package/dist/forms-inputs-DQ5QI_SU.cjs.map +1 -0
  36. package/dist/index.cjs +2 -0
  37. package/dist/index.cjs.map +1 -0
  38. package/dist/index.d.ts +21 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +383 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/state/index.cjs +2 -0
  43. package/dist/state/index.cjs.map +1 -0
  44. package/dist/state/index.d.ts +46 -0
  45. package/dist/state/index.d.ts.map +1 -0
  46. package/dist/state/index.js +9 -0
  47. package/dist/state/index.js.map +1 -0
  48. package/dist/types/index.d.ts +452 -0
  49. package/dist/types/index.d.ts.map +1 -0
  50. package/dist/utils/formatters.d.ts +98 -0
  51. package/dist/utils/formatters.d.ts.map +1 -0
  52. package/dist/utils/validators.d.ts +101 -0
  53. package/dist/utils/validators.d.ts.map +1 -0
  54. package/dist/validation/component-validation.d.ts +52 -0
  55. package/dist/validation/component-validation.d.ts.map +1 -0
  56. package/dist/validation/index.cjs +2 -0
  57. package/dist/validation/index.cjs.map +1 -0
  58. package/dist/validation/index.d.ts +141 -0
  59. package/dist/validation/index.d.ts.map +1 -0
  60. package/dist/validation/index.js +21 -0
  61. package/dist/validation/index.js.map +1 -0
  62. package/package.json +65 -0
@@ -0,0 +1,1075 @@
1
+ import { createSignal as B, createEffect as E, h as t, text as f, isSignal as Fe } from "@tachui/core";
2
+ import { c as z } from "./forms-core-B1bx1drO.js";
3
+ const le = (e) => {
4
+ const {
5
+ name: a,
6
+ label: r,
7
+ disabled: n = !1,
8
+ required: d = !1,
9
+ checked: c,
10
+ defaultChecked: h = !1,
11
+ indeterminate: k = !1,
12
+ validation: g,
13
+ onChange: $,
14
+ onBlur: F,
15
+ onFocus: V,
16
+ error: P,
17
+ helperText: C,
18
+ ...b
19
+ } = e, s = e._formContext, l = z(a, c ?? h, g);
20
+ s && s.register(a, g);
21
+ const [u, y] = B(!1);
22
+ c !== void 0 && E(() => {
23
+ l.value() !== c && l.setValue(c);
24
+ });
25
+ const L = (D) => {
26
+ const x = D.target.checked;
27
+ l.setValue(x), s && s.setValue(a, x), $ && $(a, x, l);
28
+ }, i = (D) => {
29
+ y(!0), l.onFocus(), V && V(a, l.value());
30
+ }, v = (D) => {
31
+ y(!1), l.onBlur(), F && F(a, l.value());
32
+ }, o = P || l.error() || s?.getError(a), w = (D) => {
33
+ if (D.key === " " || D.key === "Enter") {
34
+ D.preventDefault();
35
+ const _ = D.target;
36
+ _.checked = !_.checked, L(D);
37
+ }
38
+ };
39
+ return {
40
+ type: "component",
41
+ id: b.id || `checkbox-${a}`,
42
+ render: () => t(
43
+ "div",
44
+ {
45
+ ...b,
46
+ class: `tachui-checkbox ${b.class || ""}`.trim(),
47
+ "data-tachui-checkbox-container": !0,
48
+ "data-field-state": o ? "error" : l.validating() ? "validating" : "valid",
49
+ "data-checked": l.value(),
50
+ "data-indeterminate": k,
51
+ "data-disabled": n
52
+ },
53
+ // Checkbox input and label wrapper
54
+ t(
55
+ "label",
56
+ {
57
+ "data-tachui-checkbox-label": !0,
58
+ "data-focused": u(),
59
+ "data-disabled": n
60
+ },
61
+ // Hidden native checkbox for accessibility
62
+ t("input", {
63
+ type: "checkbox",
64
+ id: b.id || a,
65
+ name: a,
66
+ checked: l.value(),
67
+ disabled: n,
68
+ required: d,
69
+ onchange: L,
70
+ onfocus: i,
71
+ onblur: v,
72
+ onkeydown: w,
73
+ "aria-invalid": !!o,
74
+ "aria-describedby": [o ? `${a}-error` : null, C ? `${a}-helper` : null].filter(Boolean).join(" ") || void 0,
75
+ "data-tachui-checkbox-input": !0,
76
+ style: {
77
+ position: "absolute",
78
+ opacity: "0",
79
+ width: "1px",
80
+ height: "1px",
81
+ margin: "-1px",
82
+ padding: "0",
83
+ border: "0",
84
+ clip: "rect(0,0,0,0)"
85
+ }
86
+ }),
87
+ // Custom checkbox visual
88
+ t(
89
+ "div",
90
+ {
91
+ "data-tachui-checkbox-visual": !0,
92
+ "data-checked": l.value(),
93
+ "data-indeterminate": k,
94
+ "data-focused": u(),
95
+ "data-disabled": n,
96
+ "data-error": !!o,
97
+ "aria-hidden": "true",
98
+ role: "presentation"
99
+ },
100
+ ...l.value() || k ? [
101
+ t(
102
+ "div",
103
+ {
104
+ "data-tachui-checkbox-indicator": !0,
105
+ "data-type": k ? "indeterminate" : "checked"
106
+ },
107
+ f(k ? "−" : "✓")
108
+ )
109
+ ] : []
110
+ ),
111
+ ...r ? [
112
+ t(
113
+ "span",
114
+ {
115
+ "data-tachui-checkbox-text": !0,
116
+ "data-disabled": n
117
+ },
118
+ f(r),
119
+ ...d ? [
120
+ t(
121
+ "span",
122
+ {
123
+ "aria-label": "required",
124
+ "data-required-indicator": !0
125
+ },
126
+ f(" *")
127
+ )
128
+ ] : []
129
+ )
130
+ ] : []
131
+ ),
132
+ ...o ? [
133
+ t(
134
+ "div",
135
+ {
136
+ id: `${a}-error`,
137
+ role: "alert",
138
+ "aria-live": "polite",
139
+ "data-tachui-error": !0
140
+ },
141
+ f(o)
142
+ )
143
+ ] : [],
144
+ ...C && !o ? [
145
+ t(
146
+ "div",
147
+ {
148
+ id: `${a}-helper`,
149
+ "data-tachui-helper": !0
150
+ },
151
+ f(C)
152
+ )
153
+ ] : [],
154
+ ...l.validating() ? [
155
+ t(
156
+ "div",
157
+ {
158
+ "data-tachui-validation-spinner": !0,
159
+ "aria-label": "Validating..."
160
+ },
161
+ f("⏳")
162
+ )
163
+ ] : []
164
+ ),
165
+ props: e,
166
+ cleanup: [
167
+ () => {
168
+ s && s.unregister(a);
169
+ }
170
+ ]
171
+ };
172
+ }, Pe = (e) => {
173
+ const { size: a = "medium", ...r } = e, n = {
174
+ ...r,
175
+ class: `tachui-switch tachui-switch-${a} ${r.class || ""}`.trim()
176
+ }, d = le(n);
177
+ return {
178
+ ...d,
179
+ render: () => {
180
+ const c = d.render();
181
+ return Array.isArray(c) ? c.map((h) => ({
182
+ ...h,
183
+ props: {
184
+ ...h.props,
185
+ "data-tachui-switch": !0,
186
+ "data-switch-size": a
187
+ }
188
+ })) : {
189
+ ...c,
190
+ props: {
191
+ ...c.props,
192
+ "data-tachui-switch": !0,
193
+ "data-switch-size": a
194
+ }
195
+ };
196
+ }
197
+ };
198
+ }, Se = (e) => {
199
+ const {
200
+ name: a,
201
+ label: r,
202
+ options: n,
203
+ value: d,
204
+ defaultValue: c = [],
205
+ onChange: h,
206
+ validation: k,
207
+ error: g,
208
+ helperText: $,
209
+ disabled: F = !1,
210
+ required: V = !1,
211
+ direction: P = "vertical",
212
+ ...C
213
+ } = e, b = z(a, d ?? c, k), s = (u, y) => {
214
+ const L = b.value() || [];
215
+ let i;
216
+ y ? i = [...L, u] : i = L.filter((v) => v !== u), b.setValue(i), h && h(a, i, u);
217
+ };
218
+ return {
219
+ type: "component",
220
+ id: C.id || `checkbox-group-${a}`,
221
+ render: () => t(
222
+ "fieldset",
223
+ {
224
+ ...C,
225
+ "data-tachui-checkbox-group": !0,
226
+ "data-direction": P,
227
+ "data-disabled": F
228
+ },
229
+ ...r ? [
230
+ t(
231
+ "legend",
232
+ {
233
+ "data-tachui-group-label": !0
234
+ },
235
+ f(r),
236
+ ...V ? [
237
+ t(
238
+ "span",
239
+ {
240
+ "aria-label": "required",
241
+ "data-required-indicator": !0
242
+ },
243
+ f(" *")
244
+ )
245
+ ] : []
246
+ )
247
+ ] : [],
248
+ // Checkbox options
249
+ t(
250
+ "div",
251
+ {
252
+ "data-tachui-checkbox-options": !0,
253
+ "data-direction": P
254
+ },
255
+ ...n.flatMap((u, y) => {
256
+ const i = le({
257
+ name: `${a}-${y}`,
258
+ label: u.label,
259
+ checked: (b.value() || []).includes(u.value),
260
+ disabled: F || u.disabled,
261
+ onChange: (v, o) => s(u.value, o)
262
+ }).render();
263
+ return Array.isArray(i) ? i : [i];
264
+ })
265
+ ),
266
+ ...g ? [
267
+ t(
268
+ "div",
269
+ {
270
+ id: `${a}-error`,
271
+ role: "alert",
272
+ "aria-live": "polite",
273
+ "data-tachui-error": !0
274
+ },
275
+ f(g)
276
+ )
277
+ ] : [],
278
+ ...$ && !g ? [
279
+ t(
280
+ "div",
281
+ {
282
+ id: `${a}-helper`,
283
+ "data-tachui-helper": !0
284
+ },
285
+ f($)
286
+ )
287
+ ] : []
288
+ ),
289
+ props: e
290
+ };
291
+ }, Le = (e) => {
292
+ const {
293
+ name: a,
294
+ value: r,
295
+ label: n,
296
+ checked: d,
297
+ groupName: c,
298
+ disabled: h = !1,
299
+ required: k = !1,
300
+ validation: g,
301
+ onChange: $,
302
+ onBlur: F,
303
+ onFocus: V,
304
+ error: P,
305
+ helperText: C,
306
+ ...b
307
+ } = e, s = e._formContext, l = c || a, u = z(l, d ? r : void 0, g);
308
+ s && s.register(l, g);
309
+ const [y, L] = B(!1), i = () => u.value() === r, v = (x) => {
310
+ x.target.checked && (u.setValue(r), s && s.setValue(l, r), $ && $(l, r, u));
311
+ }, o = (x) => {
312
+ L(!0), u.onFocus(), V && V(l, u.value());
313
+ }, w = (x) => {
314
+ L(!1), u.onBlur(), F && F(l, u.value());
315
+ }, I = P || u.error() || s?.getError(l), D = (x) => {
316
+ (x.key === " " || x.key === "Enter") && (x.preventDefault(), v(x));
317
+ };
318
+ return {
319
+ type: "component",
320
+ id: b.id || `radio-${l}-${r}`,
321
+ render: () => t(
322
+ "div",
323
+ {
324
+ ...b,
325
+ class: `tachui-radio ${b.class || ""}`.trim(),
326
+ "data-tachui-radio-container": !0,
327
+ "data-field-state": I ? "error" : u.validating() ? "validating" : "valid",
328
+ "data-checked": i(),
329
+ "data-disabled": h
330
+ },
331
+ // Radio input and label wrapper
332
+ t(
333
+ "label",
334
+ {
335
+ "data-tachui-radio-label": !0,
336
+ "data-focused": y(),
337
+ "data-disabled": h
338
+ },
339
+ // Hidden native radio for accessibility
340
+ t("input", {
341
+ type: "radio",
342
+ id: b.id || `${l}-${r}`,
343
+ name: l,
344
+ value: r,
345
+ checked: i(),
346
+ disabled: h,
347
+ required: k,
348
+ onchange: v,
349
+ onfocus: o,
350
+ onblur: w,
351
+ onkeydown: D,
352
+ "aria-invalid": !!I,
353
+ "aria-describedby": [
354
+ I ? `${l}-error` : null,
355
+ C ? `${l}-helper` : null
356
+ ].filter(Boolean).join(" ") || void 0,
357
+ "data-tachui-radio-input": !0,
358
+ style: {
359
+ position: "absolute",
360
+ opacity: "0",
361
+ width: "1px",
362
+ height: "1px",
363
+ margin: "-1px",
364
+ padding: "0",
365
+ border: "0",
366
+ clip: "rect(0,0,0,0)"
367
+ }
368
+ }),
369
+ // Custom radio visual
370
+ t(
371
+ "div",
372
+ {
373
+ "data-tachui-radio-visual": !0,
374
+ "data-checked": i(),
375
+ "data-focused": y(),
376
+ "data-disabled": h,
377
+ "data-error": !!I,
378
+ "aria-hidden": "true",
379
+ role: "presentation"
380
+ },
381
+ ...i() ? [
382
+ t("div", {
383
+ "data-tachui-radio-dot": !0
384
+ })
385
+ ] : []
386
+ ),
387
+ ...n ? [
388
+ t(
389
+ "span",
390
+ {
391
+ "data-tachui-radio-text": !0,
392
+ "data-disabled": h
393
+ },
394
+ f(n),
395
+ ...k ? [
396
+ t(
397
+ "span",
398
+ {
399
+ "aria-label": "required",
400
+ "data-required-indicator": !0
401
+ },
402
+ f(" *")
403
+ )
404
+ ] : []
405
+ )
406
+ ] : []
407
+ )
408
+ ),
409
+ props: e,
410
+ cleanup: [
411
+ () => {
412
+ }
413
+ ]
414
+ };
415
+ }, qe = (e) => {
416
+ const {
417
+ name: a,
418
+ label: r,
419
+ options: n,
420
+ value: d,
421
+ defaultValue: c,
422
+ onChange: h,
423
+ validation: k,
424
+ error: g,
425
+ helperText: $,
426
+ disabled: F = !1,
427
+ required: V = !1,
428
+ direction: P = "vertical",
429
+ ...C
430
+ } = e, b = e._formContext, s = z(a, d ?? c, k);
431
+ b && b.register(a, k), d !== void 0 && E(() => {
432
+ s.value() !== d && s.setValue(d);
433
+ });
434
+ const l = (i) => {
435
+ s.setValue(i), b && b.setValue(a, i), h && h(a, i);
436
+ }, u = (i) => {
437
+ const v = n.findIndex((w) => w.value === s.value());
438
+ let o = v;
439
+ switch (i.key) {
440
+ case "ArrowDown":
441
+ case "ArrowRight":
442
+ i.preventDefault(), o = (v + 1) % n.length;
443
+ break;
444
+ case "ArrowUp":
445
+ case "ArrowLeft":
446
+ i.preventDefault(), o = v === 0 ? n.length - 1 : v - 1;
447
+ break;
448
+ case "Home":
449
+ i.preventDefault(), o = 0;
450
+ break;
451
+ case "End":
452
+ i.preventDefault(), o = n.length - 1;
453
+ break;
454
+ default:
455
+ return;
456
+ }
457
+ for (; n[o]?.disabled && (i.key === "ArrowDown" || i.key === "ArrowRight" ? o = (o + 1) % n.length : o = o === 0 ? n.length - 1 : o - 1, o !== v); )
458
+ ;
459
+ n[o]?.disabled || (l(n[o].value), setTimeout(() => {
460
+ const w = document.querySelector(
461
+ `input[name="${a}"][value="${n[o].value}"]`
462
+ );
463
+ w && w.focus();
464
+ }, 0));
465
+ }, y = g || s.error();
466
+ return {
467
+ type: "component",
468
+ id: C.id || `radio-group-${a}`,
469
+ render: () => t(
470
+ "fieldset",
471
+ {
472
+ ...C,
473
+ "data-tachui-radio-group": !0,
474
+ "data-direction": P,
475
+ "data-disabled": F,
476
+ role: "radiogroup",
477
+ "aria-invalid": !!y,
478
+ "aria-describedby": [y ? `${a}-error` : null, $ ? `${a}-helper` : null].filter(Boolean).join(" ") || void 0,
479
+ onkeydown: u
480
+ },
481
+ ...r ? [
482
+ t(
483
+ "legend",
484
+ {
485
+ "data-tachui-group-label": !0
486
+ },
487
+ f(r),
488
+ ...V ? [
489
+ t(
490
+ "span",
491
+ {
492
+ "aria-label": "required",
493
+ "data-required-indicator": !0
494
+ },
495
+ f(" *")
496
+ )
497
+ ] : []
498
+ )
499
+ ] : [],
500
+ // Radio options
501
+ t(
502
+ "div",
503
+ {
504
+ "data-tachui-radio-options": !0,
505
+ "data-direction": P
506
+ },
507
+ ...n.flatMap((i, v) => {
508
+ const w = Le({
509
+ name: `${a}-${v}`,
510
+ groupName: a,
511
+ value: i.value,
512
+ label: i.label,
513
+ checked: s.value() === i.value,
514
+ disabled: F || i.disabled,
515
+ required: V,
516
+ onChange: () => l(i.value),
517
+ _formContext: b
518
+ }).render();
519
+ return Array.isArray(w) ? w : [w];
520
+ })
521
+ ),
522
+ ...y ? [
523
+ t(
524
+ "div",
525
+ {
526
+ id: `${a}-error`,
527
+ role: "alert",
528
+ "aria-live": "polite",
529
+ "data-tachui-error": !0
530
+ },
531
+ f(y)
532
+ )
533
+ ] : [],
534
+ ...$ && !y ? [
535
+ t(
536
+ "div",
537
+ {
538
+ id: `${a}-helper`,
539
+ "data-tachui-helper": !0
540
+ },
541
+ f($)
542
+ )
543
+ ] : []
544
+ ),
545
+ props: e,
546
+ cleanup: [
547
+ () => {
548
+ b && b.unregister(a);
549
+ }
550
+ ]
551
+ };
552
+ }, O = {
553
+ /**
554
+ * Phone number formatter (US format)
555
+ */
556
+ phone: (e) => {
557
+ const a = e.replace(/\D/g, "");
558
+ return a.length <= 3 ? a : a.length <= 6 ? `(${a.slice(0, 3)}) ${a.slice(3)}` : `(${a.slice(0, 3)}) ${a.slice(3, 6)}-${a.slice(6, 10)}`;
559
+ },
560
+ /**
561
+ * Credit card formatter
562
+ */
563
+ creditCard: (e) => e.replace(/\D/g, "").replace(/(\d{4})(?=\d)/g, "$1 "),
564
+ /**
565
+ * Currency formatter
566
+ */
567
+ currency: (e) => {
568
+ const a = parseFloat(e.replace(/[^\d.]/g, ""));
569
+ return Number.isNaN(a) ? "" : new Intl.NumberFormat("en-US", {
570
+ style: "currency",
571
+ currency: "USD"
572
+ }).format(a);
573
+ },
574
+ /**
575
+ * Uppercase formatter
576
+ */
577
+ uppercase: (e) => e.toUpperCase(),
578
+ /**
579
+ * Lowercase formatter
580
+ */
581
+ lowercase: (e) => e.toLowerCase(),
582
+ /**
583
+ * Title case formatter
584
+ */
585
+ titleCase: (e) => e.replace(
586
+ /\w\S*/g,
587
+ (a) => a.charAt(0).toUpperCase() + a.substr(1).toLowerCase()
588
+ ),
589
+ /**
590
+ * Social Security Number formatter
591
+ */
592
+ ssn: (e) => {
593
+ const a = e.replace(/\D/g, "");
594
+ return a.length <= 3 ? a : a.length <= 5 ? `${a.slice(0, 3)}-${a.slice(3)}` : `${a.slice(0, 3)}-${a.slice(3, 5)}-${a.slice(5, 9)}`;
595
+ },
596
+ /**
597
+ * Postal code formatter (US ZIP)
598
+ */
599
+ postalCode: (e) => {
600
+ const a = e.replace(/\D/g, "");
601
+ return a.length <= 5 ? a : `${a.slice(0, 5)}-${a.slice(5, 9)}`;
602
+ },
603
+ /**
604
+ * Decimal number formatter
605
+ */
606
+ decimal: (e = 2) => (a) => {
607
+ const r = parseFloat(a.replace(/[^\d.-]/g, ""));
608
+ return Number.isNaN(r) ? "" : r.toFixed(e);
609
+ },
610
+ /**
611
+ * Percentage formatter
612
+ */
613
+ percentage: (e) => {
614
+ const a = parseFloat(e.replace(/[^\d.-]/g, ""));
615
+ return Number.isNaN(a) ? "" : `${a}%`;
616
+ },
617
+ /**
618
+ * Custom formatter factory
619
+ */
620
+ custom: (e) => e
621
+ }, R = {
622
+ /**
623
+ * Phone number parser - extracts digits only
624
+ */
625
+ phone: (e) => e.replace(/\D/g, ""),
626
+ /**
627
+ * Credit card parser - extracts digits only
628
+ */
629
+ creditCard: (e) => e.replace(/\D/g, ""),
630
+ /**
631
+ * Currency parser - extracts numeric value
632
+ */
633
+ currency: (e) => {
634
+ const a = e.match(/[\d.-]+/);
635
+ return a ? a[0] : "";
636
+ },
637
+ /**
638
+ * SSN parser - extracts digits only
639
+ */
640
+ ssn: (e) => e.replace(/\D/g, ""),
641
+ /**
642
+ * Postal code parser - extracts digits only
643
+ */
644
+ postalCode: (e) => e.replace(/\D/g, ""),
645
+ /**
646
+ * Decimal parser - extracts number
647
+ */
648
+ decimal: (e) => {
649
+ const a = e.match(/^-?\d*\.?\d*/);
650
+ return a ? a[0] : "";
651
+ },
652
+ /**
653
+ * Percentage parser - extracts number without %
654
+ */
655
+ percentage: (e) => e.replace(/[^\d.-]/g, ""),
656
+ /**
657
+ * No-op parser (returns value unchanged)
658
+ */
659
+ none: (e) => e,
660
+ /**
661
+ * Custom parser factory
662
+ */
663
+ custom: (e) => e
664
+ }, Q = (e, a) => e === void 0 ? a : typeof e == "function" || Fe(e) ? e() : e, T = (e) => {
665
+ const {
666
+ name: a,
667
+ label: r,
668
+ placeholder: n,
669
+ type: d = "text",
670
+ multiline: c = !1,
671
+ rows: h = 3,
672
+ minLength: k,
673
+ maxLength: g,
674
+ pattern: $,
675
+ autocomplete: F,
676
+ spellcheck: V = !0,
677
+ disabled: P = !1,
678
+ required: C = !1,
679
+ validation: b,
680
+ value: s,
681
+ defaultValue: l = "",
682
+ onChange: u,
683
+ onBlur: y,
684
+ onFocus: L,
685
+ error: i,
686
+ helperText: v,
687
+ // New enhanced features
688
+ keyboardType: o = "default",
689
+ returnKeyType: w,
690
+ autoCapitalize: I,
691
+ autoFocus: D = !1,
692
+ accessibilityLabel: _,
693
+ accessibilityHint: x,
694
+ accessibilityRole: X = "textbox",
695
+ formatter: K,
696
+ parser: j,
697
+ validateOnChange: ne = !1,
698
+ validateOnBlur: oe = !0,
699
+ font: S,
700
+ textAlign: Y,
701
+ text: H,
702
+ placeholderSignal: G,
703
+ disabledSignal: W,
704
+ ...U
705
+ } = e, q = e._formContext, p = z(a, s ?? l, b);
706
+ q && q.register(a, b);
707
+ const [de, Z] = B(!1), [ee, ce] = B(0), [se, ue] = B(""), [he, be] = B(""), [fe, pe] = B(!1);
708
+ E(() => {
709
+ if (H) {
710
+ const m = Q(H, "");
711
+ ue(m), m !== p.value() && p.setValue(m);
712
+ }
713
+ }), E(() => {
714
+ G && be(Q(G, ""));
715
+ }), E(() => {
716
+ W && pe(Q(W, !1));
717
+ }), s !== void 0 && E(() => {
718
+ p.value() !== s && p.setValue(s);
719
+ }), E(() => {
720
+ const m = p.value() || "";
721
+ ce(String(m).length);
722
+ });
723
+ const ae = (m) => {
724
+ if (K)
725
+ try {
726
+ return K(m);
727
+ } catch (N) {
728
+ return console.warn("TextField formatter error:", N), m;
729
+ }
730
+ return m;
731
+ }, me = (m) => {
732
+ if (j)
733
+ try {
734
+ return j(m);
735
+ } catch (N) {
736
+ return console.warn("TextField parser error:", N), m;
737
+ }
738
+ return m;
739
+ }, ve = (m) => {
740
+ const N = m.target, te = N.value, M = me(te), re = ae(M);
741
+ if (p.setValue(M), re !== te && N) {
742
+ const ie = N.selectionStart || 0;
743
+ N.value = re, N.setSelectionRange(ie, ie);
744
+ }
745
+ q && q.setValue(a, M), ne && p.validate(), u && u(a, M, p);
746
+ }, ye = (m) => {
747
+ Z(!0), p.onFocus(), L && L(a, p.value());
748
+ }, ge = (m) => {
749
+ Z(!1), p.onBlur(), oe && p.validate(), y && y(a, p.value());
750
+ }, xe = (m) => {
751
+ m.key === "Enter" && !c && (m.preventDefault(), q?.submitForm && q.submitForm());
752
+ }, A = i || p.error() || q?.getError(a), ke = G ? he() : n, Ce = W ? fe() : P, $e = H ? se() : p.value() || "", we = ae($e), J = {
753
+ id: U.id || a,
754
+ name: a,
755
+ value: we,
756
+ placeholder: ke,
757
+ disabled: Ce,
758
+ required: C,
759
+ minlength: k,
760
+ maxlength: g,
761
+ pattern: $,
762
+ autocomplete: F,
763
+ spellcheck: V,
764
+ oninput: ve,
765
+ onfocus: ye,
766
+ onblur: ge,
767
+ onkeydown: xe,
768
+ // Enhanced accessibility
769
+ "aria-invalid": !!A,
770
+ "aria-describedby": [
771
+ A ? `${a}-error` : null,
772
+ v ? `${a}-helper` : null,
773
+ g ? `${a}-counter` : null,
774
+ x ? `${a}-hint` : null
775
+ ].filter(Boolean).join(" ") || void 0,
776
+ "aria-label": _,
777
+ role: X,
778
+ // Mobile features
779
+ inputMode: o !== "default" ? o : void 0,
780
+ enterKeyHint: w,
781
+ autoCapitalize: I,
782
+ autoFocus: D,
783
+ // Data attributes for styling and debugging
784
+ "data-tachui-textfield": !0,
785
+ "data-field-name": a,
786
+ "data-field-type": d,
787
+ "data-field-valid": !A,
788
+ "data-field-touched": p.touched(),
789
+ "data-field-dirty": p.dirty(),
790
+ "data-field-focused": de(),
791
+ "data-field-validating": p.validating(),
792
+ "data-field-has-formatter": !!K,
793
+ "data-field-has-parser": !!j,
794
+ // Typography styling
795
+ style: {
796
+ ...S?.family && { fontFamily: S.family },
797
+ ...S?.size && { fontSize: typeof S.size == "number" ? `${S.size}px` : S.size },
798
+ ...S?.weight && { fontWeight: S.weight },
799
+ ...S?.style && { fontStyle: S.style },
800
+ ...Y && { textAlign: Y }
801
+ // Additional styling can be applied via modifiers
802
+ }
803
+ };
804
+ return d && !c && (J.type = d), {
805
+ type: "component",
806
+ id: U.id || `textfield-${a}`,
807
+ render: () => t(
808
+ "div",
809
+ {
810
+ ...U,
811
+ class: `tachui-textfield ${U.class || ""}`.trim(),
812
+ "data-tachui-textfield-container": !0,
813
+ "data-field-state": A ? "error" : p.validating() ? "validating" : "valid"
814
+ },
815
+ ...r ? [
816
+ t(
817
+ "label",
818
+ {
819
+ for: J.id,
820
+ "data-tachui-label": !0,
821
+ "data-required": C
822
+ },
823
+ f(r),
824
+ ...C ? [
825
+ t(
826
+ "span",
827
+ {
828
+ "aria-label": "required",
829
+ "data-required-indicator": !0
830
+ },
831
+ f(" *")
832
+ )
833
+ ] : []
834
+ )
835
+ ] : [],
836
+ // Input field
837
+ t(c ? "textarea" : "input", {
838
+ ...J,
839
+ ...c ? { rows: h } : {}
840
+ }),
841
+ ...g ? [
842
+ t(
843
+ "div",
844
+ {
845
+ id: `${a}-counter`,
846
+ "data-tachui-character-counter": !0,
847
+ "data-over-limit": ee() > g
848
+ },
849
+ f(`${ee()}/${g}`)
850
+ )
851
+ ] : [],
852
+ ...A ? [
853
+ t(
854
+ "div",
855
+ {
856
+ id: `${a}-error`,
857
+ role: "alert",
858
+ "aria-live": "polite",
859
+ "data-tachui-error": !0
860
+ },
861
+ f(A)
862
+ )
863
+ ] : [],
864
+ ...v && !A ? [
865
+ t(
866
+ "div",
867
+ {
868
+ id: `${a}-helper`,
869
+ "data-tachui-helper": !0
870
+ },
871
+ f(v)
872
+ )
873
+ ] : [],
874
+ ...x ? [
875
+ t(
876
+ "div",
877
+ {
878
+ id: `${a}-hint`,
879
+ "data-tachui-accessibility-hint": !0,
880
+ "aria-hidden": "true"
881
+ },
882
+ f(x)
883
+ )
884
+ ] : [],
885
+ ...p.validating() ? [
886
+ t(
887
+ "div",
888
+ {
889
+ "data-tachui-validation-spinner": !0,
890
+ "aria-label": "Validating...",
891
+ "aria-live": "polite"
892
+ },
893
+ f("⏳")
894
+ )
895
+ ] : []
896
+ ),
897
+ props: e,
898
+ cleanup: [
899
+ () => {
900
+ q && q.unregister(a);
901
+ }
902
+ ]
903
+ };
904
+ }, Ne = (e) => T({
905
+ ...e,
906
+ type: "email",
907
+ keyboardType: "email",
908
+ validation: {
909
+ rules: ["required", "email"],
910
+ validateOn: "blur",
911
+ ...e.validation
912
+ },
913
+ accessibilityRole: "textbox",
914
+ accessibilityLabel: e.accessibilityLabel || "Email address"
915
+ }), Ie = (e) => {
916
+ const {
917
+ showStrengthIndicator: a = !1,
918
+ strongValidation: r = !1,
919
+ minLength: n,
920
+ ...d
921
+ } = e, c = ["required"];
922
+ return r ? c.push("strongPassword") : (c.push("minLength"), c.push({ name: "minLength", options: { minLength: n || 6 } })), T({
923
+ ...d,
924
+ type: "password",
925
+ validation: {
926
+ rules: c,
927
+ validateOn: "change",
928
+ ...e.validation
929
+ },
930
+ accessibilityLabel: e.accessibilityLabel || "Password"
931
+ });
932
+ }, Ae = (e) => T({
933
+ ...e,
934
+ type: "search",
935
+ keyboardType: "search",
936
+ placeholder: e.placeholder || "Search...",
937
+ accessibilityRole: "searchbox",
938
+ accessibilityLabel: e.accessibilityLabel || "Search"
939
+ }), Be = (e) => T({
940
+ ...e,
941
+ type: "url",
942
+ keyboardType: "url",
943
+ validation: {
944
+ rules: ["url"],
945
+ validateOn: "blur",
946
+ ...e.validation
947
+ },
948
+ accessibilityLabel: e.accessibilityLabel || "Website URL"
949
+ }), Ee = (e) => {
950
+ const { format: a = "us", ...r } = e;
951
+ return T({
952
+ ...r,
953
+ type: "tel",
954
+ keyboardType: "phone",
955
+ formatter: O.phone,
956
+ parser: R.phone,
957
+ validation: {
958
+ rules: ["phone"],
959
+ validateOn: "blur",
960
+ ...e.validation
961
+ },
962
+ accessibilityLabel: e.accessibilityLabel || "Phone number"
963
+ });
964
+ }, _e = (e) => {
965
+ const { min: a, max: r, precision: n = 0, currency: d = !1, ...c } = e, h = ["numeric"];
966
+ return a !== void 0 && (h.push("min"), h.push({ name: "min", options: { min: a } })), r !== void 0 && (h.push("max"), h.push({ name: "max", options: { max: r } })), T({
967
+ ...c,
968
+ type: "number",
969
+ keyboardType: "numeric",
970
+ formatter: d ? O.currency : n > 0 ? O.decimal(n) : void 0,
971
+ parser: d ? R.currency : R.decimal,
972
+ validation: {
973
+ rules: h,
974
+ validateOn: "blur",
975
+ ...e.validation
976
+ },
977
+ accessibilityLabel: e.accessibilityLabel || "Number"
978
+ });
979
+ }, Oe = (e) => T({
980
+ ...e,
981
+ type: "text",
982
+ keyboardType: "numeric",
983
+ formatter: O.creditCard,
984
+ parser: R.creditCard,
985
+ maxLength: 19,
986
+ // 16 digits + 3 spaces
987
+ validation: {
988
+ rules: ["creditCard"],
989
+ validateOn: "blur",
990
+ ...e.validation
991
+ },
992
+ accessibilityLabel: e.accessibilityLabel || "Credit card number"
993
+ }), Re = (e) => T({
994
+ ...e,
995
+ type: "text",
996
+ keyboardType: "numeric",
997
+ formatter: O.ssn,
998
+ parser: R.ssn,
999
+ maxLength: 11,
1000
+ // 9 digits + 2 hyphens
1001
+ validation: {
1002
+ rules: ["ssn"],
1003
+ validateOn: "blur",
1004
+ ...e.validation
1005
+ },
1006
+ accessibilityLabel: e.accessibilityLabel || "Social Security Number"
1007
+ }), ze = (e) => T({
1008
+ ...e,
1009
+ type: "text",
1010
+ keyboardType: "numeric",
1011
+ formatter: O.postalCode,
1012
+ parser: R.postalCode,
1013
+ maxLength: 10,
1014
+ // 5 or 9 digits + hyphen
1015
+ validation: {
1016
+ rules: ["zipCode"],
1017
+ // Use zipCode to match test expectation
1018
+ validateOn: "blur",
1019
+ ...e.validation
1020
+ },
1021
+ accessibilityLabel: e.accessibilityLabel || "Postal code"
1022
+ }), Ue = (e) => T({
1023
+ ...e,
1024
+ multiline: !0,
1025
+ accessibilityLabel: e.accessibilityLabel || "Text area"
1026
+ }), Me = (e) => {
1027
+ const { min: a, max: r, ...n } = e, d = ["date"];
1028
+ return a && d.push({ name: "min", options: { min: new Date(a) } }), r && d.push({ name: "max", options: { max: new Date(r) } }), T({
1029
+ ...n,
1030
+ type: "date",
1031
+ validation: {
1032
+ rules: d,
1033
+ validateOn: "blur",
1034
+ ...e.validation
1035
+ },
1036
+ accessibilityLabel: e.accessibilityLabel || "Date"
1037
+ });
1038
+ }, Ke = (e) => T({
1039
+ ...e,
1040
+ type: "time",
1041
+ validation: {
1042
+ rules: ["time"],
1043
+ validateOn: "blur",
1044
+ ...e.validation
1045
+ },
1046
+ accessibilityLabel: e.accessibilityLabel || "Time"
1047
+ }), je = (e) => T({
1048
+ ...e,
1049
+ type: "color",
1050
+ accessibilityLabel: e.accessibilityLabel || "Color picker"
1051
+ });
1052
+ export {
1053
+ le as C,
1054
+ Me as D,
1055
+ Ne as E,
1056
+ _e as N,
1057
+ Ie as P,
1058
+ Le as R,
1059
+ Pe as S,
1060
+ Ue as T,
1061
+ Be as U,
1062
+ Se as a,
1063
+ qe as b,
1064
+ je as c,
1065
+ Oe as d,
1066
+ Ee as e,
1067
+ ze as f,
1068
+ Ae as g,
1069
+ Re as h,
1070
+ T as i,
1071
+ Ke as j,
1072
+ O as k,
1073
+ R as l
1074
+ };
1075
+ //# sourceMappingURL=forms-inputs-6QdeMWFk.js.map