@tachui/forms 0.7.1-alpha → 0.8.0-alpha

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 (90) hide show
  1. package/README.md +87 -272
  2. package/dist/DatePicker-D5nRFTUm.js +475 -0
  3. package/dist/DatePicker-D5nRFTUm.js.map +1 -0
  4. package/dist/Select-yZyKooXk.js +945 -0
  5. package/dist/Select-yZyKooXk.js.map +1 -0
  6. package/dist/Slider-0-oal5YR.js +644 -0
  7. package/dist/Slider-0-oal5YR.js.map +1 -0
  8. package/dist/TextField-hX15dY3U.js +509 -0
  9. package/dist/TextField-hX15dY3U.js.map +1 -0
  10. package/dist/components/advanced/Slider.d.ts +190 -0
  11. package/dist/components/advanced/Slider.d.ts.map +1 -0
  12. package/dist/components/advanced/Stepper.d.ts +161 -0
  13. package/dist/components/advanced/Stepper.d.ts.map +1 -0
  14. package/dist/components/advanced/index.d.ts +15 -0
  15. package/dist/components/advanced/index.d.ts.map +1 -0
  16. package/dist/components/advanced/index.js +6 -0
  17. package/dist/components/advanced/index.js.map +1 -0
  18. package/dist/components/date-picker/DatePicker.d.ts +126 -0
  19. package/dist/components/date-picker/DatePicker.d.ts.map +1 -0
  20. package/dist/components/date-picker/index.d.ts +14 -0
  21. package/dist/components/date-picker/index.d.ts.map +1 -0
  22. package/dist/components/date-picker/index.js +5 -0
  23. package/dist/components/date-picker/index.js.map +1 -0
  24. package/dist/components/form-container/index.d.ts +58 -0
  25. package/dist/components/form-container/index.d.ts.map +1 -0
  26. package/dist/components/selection/Checkbox.d.ts.map +1 -0
  27. package/dist/components/selection/Radio.d.ts.map +1 -0
  28. package/dist/components/selection/Select.d.ts.map +1 -0
  29. package/dist/components/selection/index.d.ts +68 -0
  30. package/dist/components/selection/index.d.ts.map +1 -0
  31. package/dist/components/selection/index.js +12 -0
  32. package/dist/components/selection/index.js.map +1 -0
  33. package/dist/components/text-input/TextField.d.ts.map +1 -0
  34. package/dist/components/text-input/index.d.ts +8 -0
  35. package/dist/components/text-input/index.d.ts.map +1 -0
  36. package/dist/components/text-input/index.js +18 -0
  37. package/dist/components/text-input/index.js.map +1 -0
  38. package/dist/{state/index.js → index-D3WfkqVv.js} +15 -8
  39. package/dist/index-D3WfkqVv.js.map +1 -0
  40. package/dist/index.d.ts +10 -15
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +198 -376
  43. package/dist/index.js.map +1 -0
  44. package/dist/state/index.d.ts.map +1 -1
  45. package/dist/types/index.d.ts.map +1 -1
  46. package/dist/utils/index.d.ts +19 -0
  47. package/dist/utils/index.d.ts.map +1 -0
  48. package/dist/validation/component-validation.d.ts +11 -2
  49. package/dist/validation/component-validation.d.ts.map +1 -1
  50. package/dist/validation/index.d.ts.map +1 -1
  51. package/dist/validation/index.js +282 -191
  52. package/dist/validation/index.js.map +1 -0
  53. package/package.json +53 -39
  54. package/src/components/advanced/Slider.ts +722 -0
  55. package/src/components/advanced/Stepper.ts +715 -0
  56. package/src/components/advanced/index.ts +20 -0
  57. package/src/components/date-picker/DatePicker.ts +925 -0
  58. package/src/components/date-picker/index.ts +20 -0
  59. package/src/components/form-container/index.ts +266 -0
  60. package/src/components/selection/Checkbox.ts +478 -0
  61. package/src/components/selection/Radio.ts +470 -0
  62. package/src/components/selection/Select.ts +620 -0
  63. package/src/components/selection/index.ts +81 -0
  64. package/src/components/text-input/TextField.ts +728 -0
  65. package/src/components/text-input/index.ts +35 -0
  66. package/src/index.ts +48 -0
  67. package/src/state/index.ts +544 -0
  68. package/src/types/index.ts +579 -0
  69. package/src/utils/formatters.ts +184 -0
  70. package/src/utils/index.ts +57 -0
  71. package/src/validation/component-validation.ts +429 -0
  72. package/src/validation/index.ts +641 -0
  73. package/dist/TextField-CGBM3x7K.js +0 -1799
  74. package/dist/components/Form.d.ts +0 -76
  75. package/dist/components/Form.d.ts.map +0 -1
  76. package/dist/components/index.d.ts +0 -9
  77. package/dist/components/index.d.ts.map +0 -1
  78. package/dist/components/index.js +0 -28
  79. package/dist/components/input/Checkbox.d.ts.map +0 -1
  80. package/dist/components/input/Radio.d.ts.map +0 -1
  81. package/dist/components/input/Select.d.ts.map +0 -1
  82. package/dist/components/input/TextField.d.ts.map +0 -1
  83. package/dist/components/input/index.d.ts +0 -11
  84. package/dist/components/input/index.d.ts.map +0 -1
  85. package/dist/utils/validators.d.ts +0 -101
  86. package/dist/utils/validators.d.ts.map +0 -1
  87. /package/dist/components/{input → selection}/Checkbox.d.ts +0 -0
  88. /package/dist/components/{input → selection}/Radio.d.ts +0 -0
  89. /package/dist/components/{input → selection}/Select.d.ts +0 -0
  90. /package/dist/components/{input → text-input}/TextField.d.ts +0 -0
@@ -0,0 +1,184 @@
1
+ /**
2
+ * TextField Formatters
3
+ *
4
+ * Pre-built formatting functions for common input types.
5
+ * Migrated from core TextField to forms plugin.
6
+ */
7
+
8
+ import type { TextFieldFormatter } from '../types'
9
+
10
+ /**
11
+ * Common text formatters
12
+ */
13
+ export const TextFieldFormatters = {
14
+ /**
15
+ * Phone number formatter (US format)
16
+ */
17
+ phone: (value: string): string => {
18
+ const digits = value.replace(/\D/g, '')
19
+ if (digits.length <= 3) {
20
+ return digits
21
+ } else if (digits.length <= 6) {
22
+ return `(${digits.slice(0, 3)}) ${digits.slice(3)}`
23
+ } else {
24
+ return `(${digits.slice(0, 3)}) ${digits.slice(3, 6)}-${digits.slice(6, 10)}`
25
+ }
26
+ },
27
+
28
+ /**
29
+ * Credit card formatter
30
+ */
31
+ creditCard: (value: string): string => {
32
+ const digits = value.replace(/\D/g, '')
33
+ return digits.replace(/(\d{4})(?=\d)/g, '$1 ')
34
+ },
35
+
36
+ /**
37
+ * Currency formatter
38
+ */
39
+ currency: (value: string): string => {
40
+ const number = parseFloat(value.replace(/[^\d.]/g, ''))
41
+ if (Number.isNaN(number)) return ''
42
+ return new Intl.NumberFormat('en-US', {
43
+ style: 'currency',
44
+ currency: 'USD',
45
+ }).format(number)
46
+ },
47
+
48
+ /**
49
+ * Uppercase formatter
50
+ */
51
+ uppercase: (value: string): string => value.toUpperCase(),
52
+
53
+ /**
54
+ * Lowercase formatter
55
+ */
56
+ lowercase: (value: string): string => value.toLowerCase(),
57
+
58
+ /**
59
+ * Title case formatter
60
+ */
61
+ titleCase: (value: string): string => {
62
+ return value.replace(
63
+ /\w\S*/g,
64
+ txt => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()
65
+ )
66
+ },
67
+
68
+ /**
69
+ * Social Security Number formatter
70
+ */
71
+ ssn: (value: string): string => {
72
+ const digits = value.replace(/\D/g, '')
73
+ if (digits.length <= 3) {
74
+ return digits
75
+ } else if (digits.length <= 5) {
76
+ return `${digits.slice(0, 3)}-${digits.slice(3)}`
77
+ } else {
78
+ return `${digits.slice(0, 3)}-${digits.slice(3, 5)}-${digits.slice(5, 9)}`
79
+ }
80
+ },
81
+
82
+ /**
83
+ * Postal code formatter (US ZIP)
84
+ */
85
+ postalCode: (value: string): string => {
86
+ const digits = value.replace(/\D/g, '')
87
+ if (digits.length <= 5) {
88
+ return digits
89
+ } else {
90
+ return `${digits.slice(0, 5)}-${digits.slice(5, 9)}`
91
+ }
92
+ },
93
+
94
+ /**
95
+ * Decimal number formatter
96
+ */
97
+ decimal:
98
+ (places: number = 2) =>
99
+ (value: string): string => {
100
+ const number = parseFloat(value.replace(/[^\d.-]/g, ''))
101
+ if (Number.isNaN(number)) return ''
102
+ return number.toFixed(places)
103
+ },
104
+
105
+ /**
106
+ * Percentage formatter
107
+ */
108
+ percentage: (value: string): string => {
109
+ const number = parseFloat(value.replace(/[^\d.-]/g, ''))
110
+ if (Number.isNaN(number)) return ''
111
+ return `${number}%`
112
+ },
113
+
114
+ /**
115
+ * Custom formatter factory
116
+ */
117
+ custom: (formatFn: (value: string) => string): TextFieldFormatter => formatFn,
118
+ }
119
+
120
+ /**
121
+ * Common text parsers (reverse of formatters)
122
+ */
123
+ export const TextFieldParsers = {
124
+ /**
125
+ * Phone number parser - extracts digits only
126
+ */
127
+ phone: (value: string): string => {
128
+ return value.replace(/\D/g, '')
129
+ },
130
+
131
+ /**
132
+ * Credit card parser - extracts digits only
133
+ */
134
+ creditCard: (value: string): string => {
135
+ return value.replace(/\D/g, '')
136
+ },
137
+
138
+ /**
139
+ * Currency parser - extracts numeric value
140
+ */
141
+ currency: (value: string): string => {
142
+ const matches = value.match(/[\d.-]+/)
143
+ return matches ? matches[0] : ''
144
+ },
145
+
146
+ /**
147
+ * SSN parser - extracts digits only
148
+ */
149
+ ssn: (value: string): string => {
150
+ return value.replace(/\D/g, '')
151
+ },
152
+
153
+ /**
154
+ * Postal code parser - extracts digits only
155
+ */
156
+ postalCode: (value: string): string => {
157
+ return value.replace(/\D/g, '')
158
+ },
159
+
160
+ /**
161
+ * Decimal parser - extracts number
162
+ */
163
+ decimal: (value: string): string => {
164
+ const matches = value.match(/^-?\d*\.?\d*/)
165
+ return matches ? matches[0] : ''
166
+ },
167
+
168
+ /**
169
+ * Percentage parser - extracts number without %
170
+ */
171
+ percentage: (value: string): string => {
172
+ return value.replace(/[^\d.-]/g, '')
173
+ },
174
+
175
+ /**
176
+ * No-op parser (returns value unchanged)
177
+ */
178
+ none: (value: string): string => value,
179
+
180
+ /**
181
+ * Custom parser factory
182
+ */
183
+ custom: (parseFn: (value: string) => string) => parseFn,
184
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Form Utilities
3
+ *
4
+ * Shared utilities for form handling, formatting, and validation
5
+ */
6
+
7
+ // TODO: Migrate actual utilities from @tachui/forms
8
+ // Placeholder implementation for unified package structure
9
+
10
+ // Form state utilities (stubs)
11
+ export function useFormState() {
12
+ return {
13
+ /* TODO: Implement form state hook */
14
+ }
15
+ }
16
+
17
+ export function useFormValidation() {
18
+ return {
19
+ /* TODO: Implement form validation hook */
20
+ }
21
+ }
22
+
23
+ // Formatting utilities (stubs)
24
+ export function formatCreditCard(value: string): string {
25
+ return value.replace(/\D/g, '').replace(/(\d{4})(?=\d)/g, '$1 ')
26
+ }
27
+
28
+ export function formatPhoneNumber(value: string): string {
29
+ return value.replace(/\D/g, '').replace(/(\d{3})(\d{3})(\d{4})/, '($1) $2-$3')
30
+ }
31
+
32
+ export function formatSSN(value: string): string {
33
+ return value.replace(/\D/g, '').replace(/(\d{3})(\d{2})(\d{4})/, '$1-$2-$3')
34
+ }
35
+
36
+ export function formatPostalCode(value: string): string {
37
+ return value.toUpperCase().replace(/[^A-Z0-9]/g, '')
38
+ }
39
+
40
+ // Date utilities (stubs)
41
+ export function formatDate(date: Date, _format: string = 'yyyy-MM-dd'): string {
42
+ return date.toISOString().split('T')[0]
43
+ }
44
+
45
+ export function parseDate(value: string): Date {
46
+ return new Date(value)
47
+ }
48
+
49
+ export function isValidDate(date: Date): boolean {
50
+ return date instanceof Date && !isNaN(date.getTime())
51
+ }
52
+
53
+ // Type aliases
54
+ export type FormStateManager = any
55
+ export type FormatterFunction = (value: string) => string
56
+ export type DateFormat = string
57
+ export type FormUtilOptions = any
@@ -0,0 +1,429 @@
1
+ /**
2
+ * Forms Package Component Validation
3
+ *
4
+ * Validation for @tachui/advanced-forms components that registers with the Core
5
+ * validation system, following proper plugin architecture.
6
+ */
7
+
8
+ // Import from core to register with the validation system
9
+ // ComponentValidator type is defined locally since it's not exported from core
10
+
11
+ /**
12
+ * Component validator interface (matches core's internal interface)
13
+ */
14
+ interface ComponentValidator {
15
+ packageName: string
16
+ componentName: string
17
+ validate: (args: unknown[]) => void
18
+ }
19
+
20
+ /**
21
+ * TachUI Forms validation error class
22
+ */
23
+ export class FormsValidationError extends Error {
24
+ constructor(
25
+ message: string,
26
+ public context: {
27
+ component: string
28
+ property?: string
29
+ suggestion?: string
30
+ documentation?: string
31
+ example?: {
32
+ wrong: string
33
+ correct: string
34
+ }
35
+ }
36
+ ) {
37
+ super(message)
38
+ this.name = 'FormsValidationError'
39
+ }
40
+
41
+ getFormattedMessage(): string {
42
+ const { component, suggestion, example, documentation } = this.context
43
+
44
+ let formatted = `❌ [@tachui/advanced-forms] ${component} Component Error: ${this.message}\n`
45
+
46
+ if (suggestion) {
47
+ formatted += `\n💡 Suggestion: ${suggestion}\n`
48
+ }
49
+
50
+ if (example) {
51
+ formatted += `\n❌ Wrong: ${example.wrong}`
52
+ formatted += `\n✅ Correct: ${example.correct}\n`
53
+ }
54
+
55
+ if (documentation) {
56
+ formatted += `\n📚 Documentation: ${documentation}`
57
+ }
58
+
59
+ return formatted
60
+ }
61
+ }
62
+
63
+ /**
64
+ * Forms Components Validation
65
+ */
66
+ export const FormsComponentValidation = {
67
+ // TextField Component
68
+ validateTextField(args: unknown[]): void {
69
+ if (args.length === 0) {
70
+ throw new FormsValidationError(
71
+ 'TextField component requires a props object with name',
72
+ {
73
+ component: 'TextField',
74
+ suggestion: 'Add name property: TextField({ name: "fieldName" })',
75
+ documentation:
76
+ 'https://docs.tachui.dev/advanced-forms/components/textfield',
77
+ example: {
78
+ wrong: 'TextField()',
79
+ correct: 'TextField({ name: "email", value: emailSignal })',
80
+ },
81
+ }
82
+ )
83
+ }
84
+
85
+ const [props] = args
86
+ if (!props || typeof props !== 'object') {
87
+ throw new FormsValidationError('TextField requires a props object', {
88
+ component: 'TextField',
89
+ suggestion: 'Pass a props object with name property',
90
+ example: {
91
+ wrong: 'TextField("email")',
92
+ correct: 'TextField({ name: "email" })',
93
+ },
94
+ })
95
+ }
96
+
97
+ const propsObj = props as any
98
+ if (!propsObj.name || typeof propsObj.name !== 'string') {
99
+ throw new FormsValidationError(
100
+ 'TextField name property is required and must be a string',
101
+ {
102
+ component: 'TextField',
103
+ suggestion: 'Provide a unique name for the field',
104
+ example: {
105
+ wrong: 'TextField({ placeholder: "Email" })',
106
+ correct: 'TextField({ name: "email", placeholder: "Email" })',
107
+ },
108
+ }
109
+ )
110
+ }
111
+ },
112
+
113
+ // EmailField Component
114
+ validateEmailField(args: unknown[]): void {
115
+ if (args.length === 0) {
116
+ throw new FormsValidationError(
117
+ 'EmailField component requires a props object with name',
118
+ {
119
+ component: 'EmailField',
120
+ suggestion: 'Add name property: EmailField({ name: "email" })',
121
+ documentation:
122
+ 'https://docs.tachui.dev/advanced-forms/components/emailfield',
123
+ example: {
124
+ wrong: 'EmailField()',
125
+ correct: 'EmailField({ name: "email", value: emailSignal })',
126
+ },
127
+ }
128
+ )
129
+ }
130
+
131
+ const [props] = args
132
+ if (!props || typeof props !== 'object') {
133
+ throw new FormsValidationError('EmailField requires a props object', {
134
+ component: 'EmailField',
135
+ suggestion: 'Pass a props object with name property',
136
+ example: {
137
+ wrong: 'EmailField("email@example.com")',
138
+ correct: 'EmailField({ name: "email", value: "email@example.com" })',
139
+ },
140
+ })
141
+ }
142
+
143
+ const propsObj = props as any
144
+ if (!propsObj.name || typeof propsObj.name !== 'string') {
145
+ throw new FormsValidationError(
146
+ 'EmailField name property is required and must be a string',
147
+ {
148
+ component: 'EmailField',
149
+ suggestion: 'Provide a unique name for the email field',
150
+ example: {
151
+ wrong: 'EmailField({ placeholder: "Email" })',
152
+ correct: 'EmailField({ name: "email", placeholder: "Email" })',
153
+ },
154
+ }
155
+ )
156
+ }
157
+ },
158
+
159
+ // PasswordField Component
160
+ validatePasswordField(args: unknown[]): void {
161
+ if (args.length === 0) {
162
+ throw new FormsValidationError(
163
+ 'PasswordField component requires a props object with name',
164
+ {
165
+ component: 'PasswordField',
166
+ suggestion: 'Add name property: PasswordField({ name: "password" })',
167
+ documentation:
168
+ 'https://docs.tachui.dev/advanced-forms/components/passwordfield',
169
+ example: {
170
+ wrong: 'PasswordField()',
171
+ correct:
172
+ 'PasswordField({ name: "password", value: passwordSignal })',
173
+ },
174
+ }
175
+ )
176
+ }
177
+
178
+ const [props] = args
179
+ if (!props || typeof props !== 'object') {
180
+ throw new FormsValidationError('PasswordField requires a props object', {
181
+ component: 'PasswordField',
182
+ suggestion: 'Pass a props object with name property',
183
+ example: {
184
+ wrong: 'PasswordField("password")',
185
+ correct: 'PasswordField({ name: "password", value: passwordSignal })',
186
+ },
187
+ })
188
+ }
189
+
190
+ const propsObj = props as any
191
+ if (!propsObj.name || typeof propsObj.name !== 'string') {
192
+ throw new FormsValidationError(
193
+ 'PasswordField name property is required and must be a string',
194
+ {
195
+ component: 'PasswordField',
196
+ suggestion: 'Provide a unique name for the password field',
197
+ example: {
198
+ wrong: 'PasswordField({ placeholder: "Password" })',
199
+ correct:
200
+ 'PasswordField({ name: "password", placeholder: "Password" })',
201
+ },
202
+ }
203
+ )
204
+ }
205
+ },
206
+
207
+ // PhoneField Component
208
+ validatePhoneField(args: unknown[]): void {
209
+ if (args.length === 0) {
210
+ throw new FormsValidationError(
211
+ 'PhoneField component requires a props object with name',
212
+ {
213
+ component: 'PhoneField',
214
+ suggestion: 'Add name property: PhoneField({ name: "phone" })',
215
+ documentation:
216
+ 'https://docs.tachui.dev/advanced-forms/components/phonefield',
217
+ example: {
218
+ wrong: 'PhoneField()',
219
+ correct: 'PhoneField({ name: "phone", format: "US" })',
220
+ },
221
+ }
222
+ )
223
+ }
224
+
225
+ const [props] = args
226
+ if (!props || typeof props !== 'object') {
227
+ throw new FormsValidationError('PhoneField requires a props object', {
228
+ component: 'PhoneField',
229
+ suggestion: 'Pass a props object with name property',
230
+ example: {
231
+ wrong: 'PhoneField("(555) 123-4567")',
232
+ correct: 'PhoneField({ name: "phone", value: phoneSignal })',
233
+ },
234
+ })
235
+ }
236
+
237
+ const propsObj = props as any
238
+ if (!propsObj.name || typeof propsObj.name !== 'string') {
239
+ throw new FormsValidationError(
240
+ 'PhoneField name property is required and must be a string',
241
+ {
242
+ component: 'PhoneField',
243
+ suggestion: 'Provide a unique name for the phone field',
244
+ example: {
245
+ wrong: 'PhoneField({ format: "US" })',
246
+ correct: 'PhoneField({ name: "phone", format: "US" })',
247
+ },
248
+ }
249
+ )
250
+ }
251
+ },
252
+
253
+ // NumberField Component
254
+ validateNumberField(args: unknown[]): void {
255
+ if (args.length === 0) {
256
+ throw new FormsValidationError(
257
+ 'NumberField component requires a props object with name',
258
+ {
259
+ component: 'NumberField',
260
+ suggestion: 'Add name property: NumberField({ name: "amount" })',
261
+ documentation:
262
+ 'https://docs.tachui.dev/advanced-forms/components/numberfield',
263
+ example: {
264
+ wrong: 'NumberField()',
265
+ correct: 'NumberField({ name: "amount", min: 0, max: 100 })',
266
+ },
267
+ }
268
+ )
269
+ }
270
+
271
+ const [props] = args
272
+ if (!props || typeof props !== 'object') {
273
+ throw new FormsValidationError('NumberField requires a props object', {
274
+ component: 'NumberField',
275
+ suggestion: 'Pass a props object with name property',
276
+ example: {
277
+ wrong: 'NumberField(42)',
278
+ correct: 'NumberField({ name: "amount", value: 42 })',
279
+ },
280
+ })
281
+ }
282
+
283
+ const propsObj = props as any
284
+ if (!propsObj.name || typeof propsObj.name !== 'string') {
285
+ throw new FormsValidationError(
286
+ 'NumberField name property is required and must be a string',
287
+ {
288
+ component: 'NumberField',
289
+ suggestion: 'Provide a unique name for the number field',
290
+ example: {
291
+ wrong: 'NumberField({ min: 0, max: 100 })',
292
+ correct: 'NumberField({ name: "amount", min: 0, max: 100 })',
293
+ },
294
+ }
295
+ )
296
+ }
297
+ },
298
+
299
+ // CreditCardField Component
300
+ validateCreditCardField(args: unknown[]): void {
301
+ if (args.length === 0) {
302
+ throw new FormsValidationError(
303
+ 'CreditCardField component requires a props object with name',
304
+ {
305
+ component: 'CreditCardField',
306
+ suggestion:
307
+ 'Add name property: CreditCardField({ name: "cardNumber" })',
308
+ documentation:
309
+ 'https://docs.tachui.dev/advanced-forms/components/creditcardfield',
310
+ example: {
311
+ wrong: 'CreditCardField()',
312
+ correct:
313
+ 'CreditCardField({ name: "cardNumber", onChange: handleChange })',
314
+ },
315
+ }
316
+ )
317
+ }
318
+
319
+ const [props] = args
320
+ if (!props || typeof props !== 'object') {
321
+ throw new FormsValidationError(
322
+ 'CreditCardField requires a props object',
323
+ {
324
+ component: 'CreditCardField',
325
+ suggestion: 'Pass a props object with name property',
326
+ example: {
327
+ wrong: 'CreditCardField("4111111111111111")',
328
+ correct:
329
+ 'CreditCardField({ name: "cardNumber", value: cardSignal })',
330
+ },
331
+ }
332
+ )
333
+ }
334
+
335
+ const propsObj = props as any
336
+ if (!propsObj.name || typeof propsObj.name !== 'string') {
337
+ throw new FormsValidationError(
338
+ 'CreditCardField name property is required and must be a string',
339
+ {
340
+ component: 'CreditCardField',
341
+ suggestion: 'Provide a unique name for the credit card field',
342
+ example: {
343
+ wrong: 'CreditCardField({ placeholder: "Card Number" })',
344
+ correct:
345
+ 'CreditCardField({ name: "cardNumber", placeholder: "Card Number" })',
346
+ },
347
+ }
348
+ )
349
+ }
350
+ },
351
+
352
+ // Additional Forms components would go here...
353
+ // (SearchField, URLField, TextArea, ColorField, etc.)
354
+ }
355
+
356
+ /**
357
+ * Create Forms component validators for registration
358
+ */
359
+ export function createFormsValidators(): ComponentValidator[] {
360
+ return [
361
+ {
362
+ packageName: 'advanced-forms',
363
+ componentName: 'TextField',
364
+ validate: FormsComponentValidation.validateTextField,
365
+ },
366
+ {
367
+ packageName: 'advanced-forms',
368
+ componentName: 'EmailField',
369
+ validate: FormsComponentValidation.validateEmailField,
370
+ },
371
+ {
372
+ packageName: 'advanced-forms',
373
+ componentName: 'PasswordField',
374
+ validate: FormsComponentValidation.validatePasswordField,
375
+ },
376
+ {
377
+ packageName: 'advanced-forms',
378
+ componentName: 'PhoneField',
379
+ validate: FormsComponentValidation.validatePhoneField,
380
+ },
381
+ {
382
+ packageName: 'advanced-forms',
383
+ componentName: 'NumberField',
384
+ validate: FormsComponentValidation.validateNumberField,
385
+ },
386
+ {
387
+ packageName: 'advanced-forms',
388
+ componentName: 'CreditCardField',
389
+ validate: FormsComponentValidation.validateCreditCardField,
390
+ },
391
+ // Additional validators would be added here for remaining Forms components
392
+ ]
393
+ }
394
+
395
+ /**
396
+ * Register Forms validators with Core validation system
397
+ */
398
+ export async function registerFormsValidators(): Promise<void> {
399
+ try {
400
+ // Dynamic import to avoid circular dependency
401
+ const { registerComponentValidator } = await import(
402
+ '@tachui/core/validation'
403
+ )
404
+
405
+ const validators = createFormsValidators()
406
+
407
+ for (const validator of validators) {
408
+ registerComponentValidator(validator)
409
+ }
410
+
411
+ if (process.env.NODE_ENV !== 'production') {
412
+ console.info(
413
+ `🔍 [@tachui/advanced-forms] Registered ${validators.length} component validators`
414
+ )
415
+ }
416
+ } catch (error) {
417
+ if (process.env.NODE_ENV !== 'production') {
418
+ console.warn(
419
+ '⚠️ [@tachui/advanced-forms] Could not register validators with Core:',
420
+ error
421
+ )
422
+ }
423
+ }
424
+ }
425
+
426
+ // Auto-register when Forms package loads
427
+ if (typeof window !== 'undefined' && process.env.NODE_ENV !== 'production') {
428
+ setTimeout(registerFormsValidators, 10)
429
+ }