ywana-core8 0.1.103 → 0.2.2

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 (172) hide show
  1. package/dist/index.css +4941 -324
  2. package/dist/index.js +42339 -0
  3. package/dist/index.js.map +1 -0
  4. package/dist/index.modern.js +37459 -31678
  5. package/dist/index.modern.js.map +1 -1
  6. package/dist/index.umd.js +39635 -34010
  7. package/dist/index.umd.js.map +1 -1
  8. package/package.json +26 -29
  9. package/src/Test.stories.jsx +28 -0
  10. package/src/desktop/Desktop.stories.jsx +110 -0
  11. package/src/desktop/WindowContext.js +135 -0
  12. package/src/desktop/WindowManager.js +355 -0
  13. package/src/desktop/desktop.css +55 -4
  14. package/src/desktop/desktop.js +312 -6
  15. package/src/desktop/index.js +7 -0
  16. package/src/desktop/window.css +229 -36
  17. package/src/desktop/window.js +255 -20
  18. package/src/desktop.backup/desktop.css +6 -0
  19. package/src/desktop.backup/desktop.js +13 -0
  20. package/src/desktop.backup/window.css +58 -0
  21. package/src/desktop.backup/window.js +27 -0
  22. package/src/html/Accordion.stories.jsx +178 -0
  23. package/src/html/Button.stories.jsx +175 -0
  24. package/src/html/Checkbox.stories.jsx +131 -0
  25. package/src/html/Chip.stories.jsx +189 -0
  26. package/src/html/Color.stories.jsx +234 -0
  27. package/src/html/Form.stories.jsx +271 -0
  28. package/src/html/Icon.stories.jsx +233 -0
  29. package/src/html/Progress.stories.jsx +247 -0
  30. package/src/html/Radio.stories.jsx +289 -0
  31. package/src/html/StyleTest.stories.jsx +81 -0
  32. package/src/html/Switch.stories.jsx +329 -0
  33. package/src/html/Tab.stories.jsx +239 -0
  34. package/src/html/Table.stories.jsx +188 -0
  35. package/src/html/Table2.stories.jsx +238 -0
  36. package/src/html/TextField2.stories.jsx +337 -0
  37. package/src/html/Tree.stories.jsx +285 -0
  38. package/src/html/accordion.example.js +0 -74
  39. package/src/html/accordion.js +1 -6
  40. package/src/html/button.js +2 -13
  41. package/src/html/checkbox.js +1 -9
  42. package/src/html/chip.js +2 -19
  43. package/src/html/color.js +1 -14
  44. package/src/html/form.js +4 -15
  45. package/src/html/header2.js +1 -12
  46. package/src/html/icon.js +1 -7
  47. package/src/html/index.js +1 -1
  48. package/src/html/list.js +1 -19
  49. package/src/html/menu.js +9 -5
  50. package/src/html/progress.js +5 -53
  51. package/src/html/property.js +9 -25
  52. package/src/html/radio.js +2 -16
  53. package/src/html/section.js +1 -6
  54. package/src/html/selector.js +2 -19
  55. package/src/html/switch.css +134 -100
  56. package/src/html/switch.example.js +46 -36
  57. package/src/html/switch.js +43 -192
  58. package/src/html/tab.js +3 -24
  59. package/src/html/text.js +1 -12
  60. package/src/html/textfield2.js +5 -42
  61. package/src/html/thumbnail.js +1 -12
  62. package/src/html/tokenfield.js +2 -21
  63. package/src/html/tree.js +3 -35
  64. package/src/index.js +1 -0
  65. package/__previewjs__/Wrapper.tsx +0 -14
  66. package/build-doc.sh +0 -10
  67. package/db/db.json +0 -89
  68. package/db/routes.json +0 -0
  69. package/dist/index.cjs +0 -36722
  70. package/dist/index.cjs.map +0 -1
  71. package/dist/index.css.map +0 -1
  72. package/doc/README.md +0 -196
  73. package/doc/evalulations/ACCORDION_EVALUATION.md +0 -583
  74. package/doc/evalulations/CHECKBOX_EVALUATION.md +0 -273
  75. package/doc/evalulations/CHIP_EVALUATION.md +0 -542
  76. package/doc/evalulations/COLOR_EVALUATION.md +0 -524
  77. package/doc/evalulations/COMPONENTS_EVALUATION.md +0 -477
  78. package/doc/evalulations/FORM_EVALUATION.md +0 -459
  79. package/doc/evalulations/HEADER_EVALUATION.md +0 -436
  80. package/doc/evalulations/ICON_EVALUATION.md +0 -254
  81. package/doc/evalulations/LIST_EVALUATION.md +0 -574
  82. package/doc/evalulations/PROGRESS_EVALUATION.md +0 -450
  83. package/doc/evalulations/RADIO_EVALUATION.md +0 -439
  84. package/doc/evalulations/RADIO_VISUAL_FIX.md +0 -183
  85. package/doc/evalulations/SECTION_IMPROVEMENTS.md +0 -153
  86. package/doc/evalulations/SWITCH_EVALUATION.md +0 -335
  87. package/doc/evalulations/SWITCH_VISUAL_FIX.md +0 -232
  88. package/doc/evalulations/TAB_EVALUATION.md +0 -626
  89. package/doc/evalulations/TEXTFIELD_EVALUATION.md +0 -747
  90. package/doc/evalulations/TOOLTIP_FIX.md +0 -157
  91. package/doc/evalulations/TREE_EVALUATION.md +0 -708
  92. package/doc/index.html +0 -0
  93. package/doc/package-lock.json +0 -17298
  94. package/doc/package.json +0 -34
  95. package/doc/public/index.html +0 -24
  96. package/doc/scripts/generate-examples.js +0 -129
  97. package/doc/src/App.css +0 -171
  98. package/doc/src/App.js +0 -114
  99. package/doc/src/components/ExamplePage.js +0 -129
  100. package/doc/src/components/WelcomePage.js +0 -84
  101. package/doc/src/index.css +0 -246
  102. package/doc/src/index.js +0 -17
  103. package/doc/src/theme.css +0 -256
  104. package/jest.config.js +0 -24
  105. package/preview.config.js +0 -38
  106. package/publish.sh +0 -6
  107. package/src/desktop/dektop.test.js +0 -11
  108. package/src/domain/CollectionAPI.test.js +0 -19
  109. package/src/domain/ContentEditor.test.js +0 -52
  110. package/src/domain2/CollectionAPI.test.js +0 -19
  111. package/src/domain2/CollectionContext.test.js +0 -71
  112. package/src/domain2/CollectionPage.test.js +0 -112
  113. package/src/domain2/DynamicForm.test.js +0 -47
  114. package/src/html/accordion.test.js +0 -37
  115. package/src/html/accordion.unit.test.js +0 -334
  116. package/src/html/button.example.new.js +0 -416
  117. package/src/html/button.test.js +0 -422
  118. package/src/html/checkbox.test.js +0 -285
  119. package/src/html/chip.test.js +0 -425
  120. package/src/html/color.example.js.backup +0 -527
  121. package/src/html/color.test.js +0 -377
  122. package/src/html/components.example.js.backup +0 -492
  123. package/src/html/components_enhanced.test.js +0 -581
  124. package/src/html/form.example.js.backup +0 -385
  125. package/src/html/form.test.js +0 -369
  126. package/src/html/header2.example.js.backup +0 -411
  127. package/src/html/header2.test.js +0 -377
  128. package/src/html/icon.example.js.backup +0 -268
  129. package/src/html/icon.test.js +0 -231
  130. package/src/html/label.test.js +0 -0
  131. package/src/html/list.example.js.backup +0 -404
  132. package/src/html/list.test.js +0 -383
  133. package/src/html/progress.example.js.backup +0 -424
  134. package/src/html/progress.test.js +0 -313
  135. package/src/html/property.example.js.backup +0 -553
  136. package/src/html/property.test.js +0 -371
  137. package/src/html/radio.example.js.backup +0 -389
  138. package/src/html/radio.test.js +0 -318
  139. package/src/html/section.example.js.backup +0 -99
  140. package/src/html/section.test.js +0 -131
  141. package/src/html/selector.test.js +0 -20
  142. package/src/html/switch.example.js.backup +0 -461
  143. package/src/html/switch.test.js +0 -355
  144. package/src/html/tab.example.js.backup +0 -446
  145. package/src/html/tab.test.js +0 -25
  146. package/src/html/tab_enhanced.test.js +0 -504
  147. package/src/html/table.test.js +0 -70
  148. package/src/html/table2.test.js +0 -582
  149. package/src/html/text.test.js +0 -15
  150. package/src/html/textfield.test.js +0 -51
  151. package/src/html/textfield2.example.js.backup +0 -1370
  152. package/src/html/textfield2.test.js +0 -950
  153. package/src/html/tokenfield.example.js.backup +0 -503
  154. package/src/html/tokenfield.test.js +0 -423
  155. package/src/html/tree.example.js.backup +0 -475
  156. package/src/html/tree.test.js +0 -43
  157. package/src/html/tree_enhanced.test.js +0 -495
  158. package/src/http/token.test.js +0 -50
  159. package/src/incubator/pdfViewer.js +0 -33
  160. package/src/incubator/wizard.test.js +0 -127
  161. package/src/site/site.test.js +0 -230
  162. package/src/site/view.test.js +0 -41
  163. package/src/widgets/calendar/Calendar.test.js +0 -28
  164. package/src/widgets/explorer/Explorer.test.js +0 -121
  165. package/src/widgets/ide/editor.test.js +0 -33
  166. package/src/widgets/kanban/Kanban.test.js +0 -78
  167. package/src/widgets/login/LoginBox.test.js +0 -12
  168. package/src/widgets/login/ResetPasswordBox.test.js +0 -34
  169. package/src/widgets/login/validations.test.js +0 -51
  170. package/src/widgets/planner/Planner.test.js +0 -60
  171. package/src/widgets/upload/Upload.test.js +0 -32
  172. package/table2.test.js +0 -454
@@ -1,1370 +0,0 @@
1
- import React, { useState } from 'react'
2
- import { TextField2, TextArea2, PasswordField2, DropDown2, DateRange2 } from './textfield2'
3
-
4
- /**
5
- * Ejemplos de uso de los componentes TextField2 mejorados
6
- */
7
- export const TextField2Examples = () => {
8
- const [formData, setFormData] = useState({})
9
- const [validationErrors, setValidationErrors] = useState({})
10
-
11
- const handleFieldChange = (id, value) => {
12
- setFormData(prev => ({
13
- ...prev,
14
- [id]: value
15
- }))
16
- }
17
-
18
- const handleValidation = (id, isValid, message) => {
19
- setValidationErrors(prev => ({
20
- ...prev,
21
- [id]: isValid ? null : message
22
- }))
23
- }
24
-
25
- // Validaciones personalizadas
26
- const validateEmail = (value) => {
27
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
28
- return {
29
- valid: emailRegex.test(value),
30
- message: emailRegex.test(value) ? '' : 'Please enter a valid email address'
31
- }
32
- }
33
-
34
- const validatePassword = (value) => {
35
- const hasLength = value.length >= 8
36
- const hasUpper = /[A-Z]/.test(value)
37
- const hasLower = /[a-z]/.test(value)
38
- const hasNumber = /\d/.test(value)
39
-
40
- const valid = hasLength && hasUpper && hasLower && hasNumber
41
- let message = ''
42
-
43
- if (!valid) {
44
- const missing = []
45
- if (!hasLength) missing.push('8+ characters')
46
- if (!hasUpper) missing.push('uppercase letter')
47
- if (!hasLower) missing.push('lowercase letter')
48
- if (!hasNumber) missing.push('number')
49
- message = `Password must contain: ${missing.join(', ')}`
50
- }
51
-
52
- return { valid, message }
53
- }
54
-
55
- const validatePhone = (value) => {
56
- const phoneRegex = /^\+?[\d\s\-\(\)]{10,}$/
57
- return phoneRegex.test(value)
58
- }
59
-
60
- // Opciones para dropdowns
61
- const countryOptions = [
62
- { value: 'us', label: 'United States', icon: 'flag' },
63
- { value: 'ca', label: 'Canada', icon: 'flag' },
64
- { value: 'mx', label: 'Mexico', icon: 'flag' },
65
- { value: 'uk', label: 'United Kingdom', icon: 'flag' },
66
- { value: 'de', label: 'Germany', icon: 'flag' },
67
- { value: 'fr', label: 'France', icon: 'flag' },
68
- { value: 'es', label: 'Spain', icon: 'flag' },
69
- { value: 'it', label: 'Italy', icon: 'flag' }
70
- ]
71
-
72
- const skillOptions = [
73
- { value: 'react', label: 'React', category: 'Frontend' },
74
- { value: 'vue', label: 'Vue.js', category: 'Frontend' },
75
- { value: 'angular', label: 'Angular', category: 'Frontend' },
76
- { value: 'nodejs', label: 'Node.js', category: 'Backend' },
77
- { value: 'python', label: 'Python', category: 'Backend' },
78
- { value: 'java', label: 'Java', category: 'Backend' },
79
- { value: 'docker', label: 'Docker', category: 'DevOps' },
80
- { value: 'kubernetes', label: 'Kubernetes', category: 'DevOps' }
81
- ]
82
-
83
- const priorityOptions = [
84
- { value: 'low', label: 'Low Priority', icon: 'arrow_downward' },
85
- { value: 'medium', label: 'Medium Priority', icon: 'remove' },
86
- { value: 'high', label: 'High Priority', icon: 'arrow_upward' },
87
- { value: 'urgent', label: 'Urgent', icon: 'warning' }
88
- ]
89
-
90
- return (
91
- <div style={{ padding: '2rem', maxWidth: '1200px', maxHeight: '100vh', overflow: 'auto' }}>
92
- <h1>Ejemplos de Componentes TextField2 Mejorados</h1>
93
-
94
- <div style={{
95
- background: '#f8f9fa',
96
- padding: '1rem',
97
- borderRadius: '8px',
98
- marginBottom: '2rem',
99
- border: '1px solid #e9ecef'
100
- }}>
101
- <h3>✅ Mejoras Implementadas:</h3>
102
- <ul>
103
- <li>🛡️ <strong>Validación robusta</strong> - PropTypes, validación personalizable, mensajes de error</li>
104
- <li>♿ <strong>Accesibilidad completa</strong> - ARIA, roles, live regions, soporte de teclado</li>
105
- <li>📝 <strong>Documentación completa</strong> - PropTypes detallados y ejemplos</li>
106
- <li>🎯 <strong>Estados avanzados</strong> - disabled, error, focused, invalid, readonly</li>
107
- <li>🎨 <strong>CSS mejorado</strong> - Altura automática, responsive, temas</li>
108
- <li>⚡ <strong>Debouncing</strong> - Control de frecuencia de onChange</li>
109
- <li>🔧 <strong>Componentes especializados</strong> - TextField2, TextArea2, PasswordField2, DropDown2, DateRange2</li>
110
- <li>🧪 <strong>Pruebas exhaustivas</strong> - 39 pruebas que cubren toda la funcionalidad</li>
111
- </ul>
112
- </div>
113
-
114
- {/* Comparación de Estilos */}
115
- <section style={{ marginBottom: '2rem' }}>
116
- <h3>🎨 Comparación de Estilos: Normal vs Outlined</h3>
117
- <div style={{
118
- background: '#fff',
119
- padding: '1.5rem',
120
- borderRadius: '8px',
121
- border: '1px solid #ddd'
122
- }}>
123
- <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '2rem' }}>
124
- <div>
125
- <h4 style={{
126
- background: '#e3f2fd',
127
- padding: '0.5rem',
128
- borderRadius: '4px',
129
- textAlign: 'center',
130
- margin: '0 0 1rem 0'
131
- }}>
132
- 📝 Estilo NORMAL (default)
133
- </h4>
134
- <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
135
- <TextField2
136
- id="normalBasic"
137
- label="Campo Normal"
138
- placeholder="Placeholder text"
139
- value={formData.normalBasic || ''}
140
- onChange={handleFieldChange}
141
- helperText="Estilo normal con underline"
142
- />
143
-
144
- <TextField2
145
- id="normalWithValue"
146
- label="Con Valor"
147
- value="Texto de ejemplo"
148
- onChange={handleFieldChange}
149
- helperText="Campo normal con valor"
150
- />
151
-
152
- <TextField2
153
- id="normalRequired"
154
- label="Campo Requerido"
155
- placeholder="Campo obligatorio"
156
- value={formData.normalRequired || ''}
157
- required={true}
158
- onChange={handleFieldChange}
159
- helperText="Campo requerido estilo normal"
160
- />
161
- </div>
162
- </div>
163
-
164
- <div>
165
- <h4 style={{
166
- background: '#f3e5f5',
167
- padding: '0.5rem',
168
- borderRadius: '4px',
169
- textAlign: 'center',
170
- margin: '0 0 1rem 0'
171
- }}>
172
- 🔲 Estilo OUTLINED
173
- </h4>
174
- <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
175
- <TextField2
176
- id="outlinedBasic"
177
- label="Campo Outlined"
178
- placeholder="Placeholder text"
179
- value={formData.outlinedBasic || ''}
180
- outlined={true}
181
- onChange={handleFieldChange}
182
- helperText="Estilo outlined con borde"
183
- />
184
-
185
- <TextField2
186
- id="outlinedWithValue"
187
- label="Con Valor"
188
- value="Texto de ejemplo"
189
- outlined={true}
190
- onChange={handleFieldChange}
191
- helperText="Campo outlined con valor"
192
- />
193
-
194
- <TextField2
195
- id="outlinedRequired"
196
- label="Campo Requerido"
197
- placeholder="Campo obligatorio"
198
- value={formData.outlinedRequired || ''}
199
- required={true}
200
- outlined={true}
201
- onChange={handleFieldChange}
202
- helperText="Campo requerido estilo outlined"
203
- />
204
- </div>
205
- </div>
206
- </div>
207
- </div>
208
- </section>
209
-
210
- {/* Tipos de Input - Normal */}
211
- <section style={{ marginBottom: '2rem' }}>
212
- <h3>📝 Tipos de Input - Estilo NORMAL</h3>
213
- <div style={{
214
- background: '#fff',
215
- padding: '1.5rem',
216
- borderRadius: '8px',
217
- border: '1px solid #ddd',
218
- display: 'grid',
219
- gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
220
- gap: '1rem'
221
- }}>
222
- <TextField2
223
- id="textNormal"
224
- type="text"
225
- label="Texto"
226
- placeholder="Ingresa texto"
227
- value={formData.textNormal || ''}
228
- onChange={handleFieldChange}
229
- helperText="Tipo: text (normal)"
230
- />
231
-
232
- <TextField2
233
- id="emailNormal"
234
- type="email"
235
- label="Email"
236
- placeholder="usuario@ejemplo.com"
237
- value={formData.emailNormal || ''}
238
- validation={validateEmail}
239
- onChange={handleFieldChange}
240
- onValidation={handleValidation}
241
- helperText="Tipo: email (normal)"
242
- />
243
-
244
- <TextField2
245
- id="passwordNormal"
246
- type="password"
247
- label="Contraseña"
248
- placeholder="Contraseña segura"
249
- value={formData.passwordNormal || ''}
250
- onChange={handleFieldChange}
251
- helperText="Tipo: password (normal)"
252
- />
253
-
254
- <TextField2
255
- id="telNormal"
256
- type="tel"
257
- label="Teléfono"
258
- placeholder="+34 123 456 789"
259
- value={formData.telNormal || ''}
260
- onChange={handleFieldChange}
261
- helperText="Tipo: tel (normal)"
262
- />
263
-
264
- <TextField2
265
- id="urlNormal"
266
- type="url"
267
- label="Sitio Web"
268
- placeholder="https://ejemplo.com"
269
- value={formData.urlNormal || ''}
270
- onChange={handleFieldChange}
271
- helperText="Tipo: url (normal)"
272
- />
273
-
274
- <TextField2
275
- id="numberNormal"
276
- type="number"
277
- label="Número"
278
- placeholder="123"
279
- value={formData.numberNormal || ''}
280
- min="0"
281
- max="999"
282
- onChange={handleFieldChange}
283
- helperText="Tipo: number (normal)"
284
- />
285
-
286
- <TextField2
287
- id="dateNormal"
288
- type="date"
289
- label="Fecha"
290
- value={formData.dateNormal || ''}
291
- onChange={handleFieldChange}
292
- helperText="Tipo: date (normal)"
293
- />
294
-
295
- <TextField2
296
- id="timeNormal"
297
- type="time"
298
- label="Hora"
299
- value={formData.timeNormal || ''}
300
- onChange={handleFieldChange}
301
- helperText="Tipo: time (normal)"
302
- />
303
-
304
- <TextField2
305
- id="searchNormal"
306
- type="search"
307
- label="Búsqueda"
308
- placeholder="Buscar..."
309
- value={formData.searchNormal || ''}
310
- onChange={handleFieldChange}
311
- helperText="Tipo: search (normal)"
312
- />
313
- </div>
314
- </section>
315
-
316
- {/* Tipos de Input - Outlined */}
317
- <section style={{ marginBottom: '2rem' }}>
318
- <h3>🔲 Tipos de Input - Estilo OUTLINED</h3>
319
- <div style={{
320
- background: '#fff',
321
- padding: '1.5rem',
322
- borderRadius: '8px',
323
- border: '1px solid #ddd',
324
- display: 'grid',
325
- gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
326
- gap: '1rem'
327
- }}>
328
- <TextField2
329
- id="textOutlined"
330
- type="text"
331
- label="Texto"
332
- placeholder="Ingresa texto"
333
- value={formData.textOutlined || ''}
334
- outlined={true}
335
- onChange={handleFieldChange}
336
- helperText="Tipo: text (outlined)"
337
- />
338
-
339
- <TextField2
340
- id="emailOutlined"
341
- type="email"
342
- label="Email"
343
- placeholder="usuario@ejemplo.com"
344
- value={formData.emailOutlined || ''}
345
- outlined={true}
346
- validation={validateEmail}
347
- onChange={handleFieldChange}
348
- onValidation={handleValidation}
349
- helperText="Tipo: email (outlined)"
350
- />
351
-
352
- <TextField2
353
- id="passwordOutlined"
354
- type="password"
355
- label="Contraseña"
356
- placeholder="Contraseña segura"
357
- value={formData.passwordOutlined || ''}
358
- outlined={true}
359
- onChange={handleFieldChange}
360
- helperText="Tipo: password (outlined)"
361
- />
362
-
363
- <TextField2
364
- id="telOutlined"
365
- type="tel"
366
- label="Teléfono"
367
- placeholder="+34 123 456 789"
368
- value={formData.telOutlined || ''}
369
- outlined={true}
370
- onChange={handleFieldChange}
371
- helperText="Tipo: tel (outlined)"
372
- />
373
-
374
- <TextField2
375
- id="urlOutlined"
376
- type="url"
377
- label="Sitio Web"
378
- placeholder="https://ejemplo.com"
379
- value={formData.urlOutlined || ''}
380
- outlined={true}
381
- onChange={handleFieldChange}
382
- helperText="Tipo: url (outlined)"
383
- />
384
-
385
- <TextField2
386
- id="numberOutlined"
387
- type="number"
388
- label="Número"
389
- placeholder="123"
390
- value={formData.numberOutlined || ''}
391
- outlined={true}
392
- min="0"
393
- max="999"
394
- onChange={handleFieldChange}
395
- helperText="Tipo: number (outlined)"
396
- />
397
-
398
- <TextField2
399
- id="dateOutlined"
400
- type="date"
401
- label="Fecha"
402
- value={formData.dateOutlined || ''}
403
- outlined={true}
404
- onChange={handleFieldChange}
405
- helperText="Tipo: date (outlined)"
406
- />
407
-
408
- <TextField2
409
- id="timeOutlined"
410
- type="time"
411
- label="Hora"
412
- value={formData.timeOutlined || ''}
413
- outlined={true}
414
- onChange={handleFieldChange}
415
- helperText="Tipo: time (outlined)"
416
- />
417
-
418
- <TextField2
419
- id="searchOutlined"
420
- type="search"
421
- label="Búsqueda"
422
- placeholder="Buscar..."
423
- value={formData.searchOutlined || ''}
424
- outlined={true}
425
- onChange={handleFieldChange}
426
- helperText="Tipo: search (outlined)"
427
- />
428
- </div>
429
- </section>
430
-
431
- {/* PasswordField2 - Normal */}
432
- <section style={{ marginBottom: '2rem' }}>
433
- <h3>🔐 PasswordField2 - Estilo NORMAL</h3>
434
- <div style={{
435
- background: '#fff',
436
- padding: '1.5rem',
437
- borderRadius: '8px',
438
- border: '1px solid #ddd',
439
- display: 'grid',
440
- gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
441
- gap: '1rem'
442
- }}>
443
- <PasswordField2
444
- id="passwordNormal"
445
- label="Contraseña"
446
- placeholder="Contraseña segura"
447
- value={formData.passwordNormal || ''}
448
- required={true}
449
- validation={validatePassword}
450
- onChange={handleFieldChange}
451
- onValidation={handleValidation}
452
- helperText="Estilo normal - 8+ chars, mayús, minús, número"
453
- autoComplete="new-password"
454
- />
455
-
456
- <PasswordField2
457
- id="confirmPasswordNormal"
458
- label="Confirmar Contraseña"
459
- placeholder="Confirma tu contraseña"
460
- value={formData.confirmPasswordNormal || ''}
461
- required={true}
462
- validation={(value) => value === formData.passwordNormal}
463
- error={formData.confirmPasswordNormal && formData.confirmPasswordNormal !== formData.passwordNormal ? 'Las contraseñas no coinciden' : ''}
464
- onChange={handleFieldChange}
465
- helperText="Estilo normal - Debe coincidir"
466
- autoComplete="new-password"
467
- />
468
-
469
- <PasswordField2
470
- id="currentPasswordNormal"
471
- label="Contraseña Actual"
472
- placeholder="Tu contraseña actual"
473
- value={formData.currentPasswordNormal || ''}
474
- onChange={handleFieldChange}
475
- helperText="Estilo normal - Contraseña existente"
476
- autoComplete="current-password"
477
- />
478
- </div>
479
- </section>
480
-
481
- {/* PasswordField2 - Outlined */}
482
- <section style={{ marginBottom: '2rem' }}>
483
- <h3>🔐 PasswordField2 - Estilo OUTLINED</h3>
484
- <div style={{
485
- background: '#fff',
486
- padding: '1.5rem',
487
- borderRadius: '8px',
488
- border: '1px solid #ddd',
489
- display: 'grid',
490
- gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
491
- gap: '1rem'
492
- }}>
493
- <PasswordField2
494
- id="passwordOutlined"
495
- label="Contraseña"
496
- placeholder="Contraseña segura"
497
- value={formData.passwordOutlined || ''}
498
- required={true}
499
- outlined={true}
500
- validation={validatePassword}
501
- onChange={handleFieldChange}
502
- onValidation={handleValidation}
503
- helperText="Estilo outlined - 8+ chars, mayús, minús, número"
504
- autoComplete="new-password"
505
- />
506
-
507
- <PasswordField2
508
- id="confirmPasswordOutlined"
509
- label="Confirmar Contraseña"
510
- placeholder="Confirma tu contraseña"
511
- value={formData.confirmPasswordOutlined || ''}
512
- required={true}
513
- outlined={true}
514
- validation={(value) => value === formData.passwordOutlined}
515
- error={formData.confirmPasswordOutlined && formData.confirmPasswordOutlined !== formData.passwordOutlined ? 'Las contraseñas no coinciden' : ''}
516
- onChange={handleFieldChange}
517
- helperText="Estilo outlined - Debe coincidir"
518
- autoComplete="new-password"
519
- />
520
-
521
- <PasswordField2
522
- id="currentPasswordOutlined"
523
- label="Contraseña Actual"
524
- placeholder="Tu contraseña actual"
525
- value={formData.currentPasswordOutlined || ''}
526
- outlined={true}
527
- onChange={handleFieldChange}
528
- helperText="Estilo outlined - Contraseña existente"
529
- autoComplete="current-password"
530
- />
531
- </div>
532
- </section>
533
-
534
- {/* TextArea2 - Normal */}
535
- <section style={{ marginBottom: '2rem' }}>
536
- <h3>📝 TextArea2 - Estilo NORMAL</h3>
537
- <div style={{
538
- background: '#fff',
539
- padding: '1.5rem',
540
- borderRadius: '8px',
541
- border: '1px solid #ddd'
542
- }}>
543
- <div style={{ display: 'grid', gap: '1rem' }}>
544
- <TextArea2
545
- id="bioNormal"
546
- label="Biografía"
547
- placeholder="Cuéntanos sobre ti..."
548
- value={formData.bioNormal || ''}
549
- rows={4}
550
- maxLength={500}
551
- onChange={handleFieldChange}
552
- helperText={`Estilo normal - ${(formData.bioNormal || '').length}/500 caracteres`}
553
- />
554
-
555
- <TextArea2
556
- id="commentsNormal"
557
- label="Comentarios Adicionales"
558
- placeholder="Información adicional..."
559
- value={formData.commentsNormal || ''}
560
- rows={3}
561
- onChange={handleFieldChange}
562
- helperText="Estilo normal - Campo opcional"
563
- />
564
-
565
- <TextArea2
566
- id="descriptionNormal"
567
- label="Descripción del Proyecto"
568
- placeholder="Describe tu proyecto en detalle..."
569
- value={formData.descriptionNormal || ''}
570
- rows={5}
571
- required={true}
572
- onChange={handleFieldChange}
573
- helperText="Estilo normal - Campo requerido"
574
- />
575
- </div>
576
- </div>
577
- </section>
578
-
579
- {/* TextArea2 - Outlined */}
580
- <section style={{ marginBottom: '2rem' }}>
581
- <h3>📝 TextArea2 - Estilo OUTLINED</h3>
582
- <div style={{
583
- background: '#fff',
584
- padding: '1.5rem',
585
- borderRadius: '8px',
586
- border: '1px solid #ddd'
587
- }}>
588
- <div style={{ display: 'grid', gap: '1rem' }}>
589
- <TextArea2
590
- id="bioOutlined"
591
- label="Biografía"
592
- placeholder="Cuéntanos sobre ti..."
593
- value={formData.bioOutlined || ''}
594
- rows={4}
595
- maxLength={500}
596
- outlined={true}
597
- onChange={handleFieldChange}
598
- helperText={`Estilo outlined - ${(formData.bioOutlined || '').length}/500 caracteres`}
599
- />
600
-
601
- <TextArea2
602
- id="commentsOutlined"
603
- label="Comentarios Adicionales"
604
- placeholder="Información adicional..."
605
- value={formData.commentsOutlined || ''}
606
- rows={3}
607
- outlined={true}
608
- onChange={handleFieldChange}
609
- helperText="Estilo outlined - Campo opcional"
610
- />
611
-
612
- <TextArea2
613
- id="descriptionOutlined"
614
- label="Descripción del Proyecto"
615
- placeholder="Describe tu proyecto en detalle..."
616
- value={formData.descriptionOutlined || ''}
617
- rows={5}
618
- required={true}
619
- outlined={true}
620
- onChange={handleFieldChange}
621
- helperText="Estilo outlined - Campo requerido"
622
- />
623
-
624
- <TextArea2
625
- id="feedbackOutlined"
626
- label="Feedback"
627
- placeholder="Comparte tu opinión..."
628
- value={formData.feedbackOutlined || ''}
629
- rows={6}
630
- outlined={true}
631
- maxLength={1000}
632
- onChange={handleFieldChange}
633
- helperText={`Estilo outlined - ${(formData.feedbackOutlined || '').length}/1000 caracteres`}
634
- />
635
- </div>
636
- </div>
637
- </section>
638
-
639
- {/* DropDown2 - Normal */}
640
- <section style={{ marginBottom: '2rem' }}>
641
- <h3>📋 DropDown2 - Estilo NORMAL</h3>
642
- <div style={{
643
- background: '#fff',
644
- padding: '1.5rem',
645
- borderRadius: '8px',
646
- border: '1px solid #ddd',
647
- display: 'grid',
648
- gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
649
- gap: '1rem'
650
- }}>
651
- <DropDown2
652
- id="countryNormal"
653
- label="País"
654
- placeholder="Selecciona tu país"
655
- options={countryOptions}
656
- value={formData.countryNormal || ''}
657
- searchable={true}
658
- clearable={true}
659
- onChange={handleFieldChange}
660
- helperText="Estilo normal - Búsqueda habilitada"
661
- />
662
-
663
- <DropDown2
664
- id="skillsNormal"
665
- label="Habilidades"
666
- placeholder="Selecciona tus habilidades"
667
- options={skillOptions}
668
- value={formData.skillsNormal || []}
669
- multiple={true}
670
- searchable={true}
671
- clearable={true}
672
- groupBy="category"
673
- onChange={handleFieldChange}
674
- helperText="Estilo normal - Selección múltiple con agrupación"
675
- />
676
-
677
- <DropDown2
678
- id="priorityNormal"
679
- label="Nivel de Prioridad"
680
- placeholder="Selecciona prioridad"
681
- options={priorityOptions}
682
- value={formData.priorityNormal || ''}
683
- onChange={handleFieldChange}
684
- helperText="Estilo normal - Opciones con iconos"
685
- />
686
-
687
- <DropDown2
688
- id="statusNormal"
689
- label="Estado"
690
- placeholder="Selecciona estado"
691
- options={[
692
- { value: 'active', label: 'Activo' },
693
- { value: 'inactive', label: 'Inactivo' },
694
- { value: 'pending', label: 'Pendiente' },
695
- { value: 'suspended', label: 'Suspendido' }
696
- ]}
697
- value={formData.statusNormal || ''}
698
- required={true}
699
- onChange={handleFieldChange}
700
- helperText="Estilo normal - Campo requerido"
701
- />
702
- </div>
703
- </section>
704
-
705
- {/* DropDown2 - Outlined */}
706
- <section style={{ marginBottom: '2rem' }}>
707
- <h3>📋 DropDown2 - Estilo OUTLINED</h3>
708
- <div style={{
709
- background: '#fff',
710
- padding: '1.5rem',
711
- borderRadius: '8px',
712
- border: '1px solid #ddd',
713
- display: 'grid',
714
- gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
715
- gap: '1rem'
716
- }}>
717
- <DropDown2
718
- id="countryOutlined"
719
- label="País"
720
- placeholder="Selecciona tu país"
721
- options={countryOptions}
722
- value={formData.countryOutlined || ''}
723
- outlined={true}
724
- searchable={true}
725
- clearable={true}
726
- onChange={handleFieldChange}
727
- helperText="Estilo outlined - Búsqueda habilitada"
728
- />
729
-
730
- <DropDown2
731
- id="skillsOutlined"
732
- label="Habilidades"
733
- placeholder="Selecciona tus habilidades"
734
- options={skillOptions}
735
- value={formData.skillsOutlined || []}
736
- multiple={true}
737
- outlined={true}
738
- searchable={true}
739
- clearable={true}
740
- groupBy="category"
741
- onChange={handleFieldChange}
742
- helperText="Estilo outlined - Selección múltiple con agrupación"
743
- />
744
-
745
- <DropDown2
746
- id="priorityOutlined"
747
- label="Nivel de Prioridad"
748
- placeholder="Selecciona prioridad"
749
- options={priorityOptions}
750
- value={formData.priorityOutlined || ''}
751
- outlined={true}
752
- onChange={handleFieldChange}
753
- helperText="Estilo outlined - Opciones con iconos"
754
- />
755
-
756
- <DropDown2
757
- id="statusOutlined"
758
- label="Estado"
759
- placeholder="Selecciona estado"
760
- options={[
761
- { value: 'active', label: 'Activo' },
762
- { value: 'inactive', label: 'Inactivo' },
763
- { value: 'pending', label: 'Pendiente' },
764
- { value: 'suspended', label: 'Suspendido' }
765
- ]}
766
- value={formData.statusOutlined || ''}
767
- required={true}
768
- outlined={true}
769
- onChange={handleFieldChange}
770
- helperText="Estilo outlined - Campo requerido"
771
- />
772
-
773
- <DropDown2
774
- id="categoryOutlined"
775
- label="Categoría"
776
- placeholder="Selecciona categoría"
777
- options={[
778
- { value: 'tech', label: 'Tecnología', category: 'Trabajo' },
779
- { value: 'design', label: 'Diseño', category: 'Trabajo' },
780
- { value: 'marketing', label: 'Marketing', category: 'Trabajo' },
781
- { value: 'sports', label: 'Deportes', category: 'Personal' },
782
- { value: 'music', label: 'Música', category: 'Personal' },
783
- { value: 'travel', label: 'Viajes', category: 'Personal' }
784
- ]}
785
- value={formData.categoryOutlined || ''}
786
- outlined={true}
787
- searchable={true}
788
- groupBy="category"
789
- onChange={handleFieldChange}
790
- helperText="Estilo outlined - Con agrupación personalizada"
791
- />
792
- </div>
793
- </section>
794
-
795
- {/* DateRange2 - Normal */}
796
- <section style={{ marginBottom: '2rem' }}>
797
- <h3>📅 DateRange2 - Estilo NORMAL</h3>
798
- <div style={{
799
- background: '#fff',
800
- padding: '1.5rem',
801
- borderRadius: '8px',
802
- border: '1px solid #ddd',
803
- display: 'grid',
804
- gridTemplateColumns: 'repeat(auto-fit, minmax(400px, 1fr))',
805
- gap: '1rem'
806
- }}>
807
- <DateRange2
808
- id="projectDatesNormal"
809
- label="Duración del Proyecto"
810
- value={formData.projectDatesNormal || {}}
811
- required={true}
812
- minDate="2024-01-01"
813
- maxDate="2025-12-31"
814
- onChange={handleFieldChange}
815
- onValidation={handleValidation}
816
- helperText="Estilo normal - Fechas de inicio y fin del proyecto"
817
- />
818
-
819
- <DateRange2
820
- id="vacationDatesNormal"
821
- label="Período de Vacaciones"
822
- value={formData.vacationDatesNormal || {}}
823
- onChange={handleFieldChange}
824
- helperText="Estilo normal - Fechas de vacaciones opcionales"
825
- />
826
- </div>
827
- </section>
828
-
829
- {/* DateRange2 - Outlined */}
830
- <section style={{ marginBottom: '2rem' }}>
831
- <h3>📅 DateRange2 - Estilo OUTLINED</h3>
832
- <div style={{
833
- background: '#fff',
834
- padding: '1.5rem',
835
- borderRadius: '8px',
836
- border: '1px solid #ddd',
837
- display: 'grid',
838
- gridTemplateColumns: 'repeat(auto-fit, minmax(400px, 1fr))',
839
- gap: '1rem'
840
- }}>
841
- <DateRange2
842
- id="projectDatesOutlined"
843
- label="Duración del Proyecto"
844
- value={formData.projectDatesOutlined || {}}
845
- outlined={true}
846
- required={true}
847
- minDate="2024-01-01"
848
- maxDate="2025-12-31"
849
- onChange={handleFieldChange}
850
- onValidation={handleValidation}
851
- helperText="Estilo outlined - Fechas de inicio y fin del proyecto"
852
- />
853
-
854
- <DateRange2
855
- id="vacationDatesOutlined"
856
- label="Período de Vacaciones"
857
- value={formData.vacationDatesOutlined || {}}
858
- outlined={true}
859
- onChange={handleFieldChange}
860
- helperText="Estilo outlined - Fechas de vacaciones opcionales"
861
- />
862
-
863
- <DateRange2
864
- id="eventDatesOutlined"
865
- label="Fechas del Evento"
866
- value={formData.eventDatesOutlined || {}}
867
- outlined={true}
868
- required={true}
869
- onChange={handleFieldChange}
870
- helperText="Estilo outlined - Fechas de inicio y fin del evento"
871
- />
872
- </div>
873
- </section>
874
-
875
- {/* Estados Especiales - Normal */}
876
- <section style={{ marginBottom: '2rem' }}>
877
- <h3>⚙️ Estados Especiales - Estilo NORMAL</h3>
878
- <div style={{
879
- background: '#fff',
880
- padding: '1.5rem',
881
- borderRadius: '8px',
882
- border: '1px solid #ddd',
883
- display: 'grid',
884
- gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
885
- gap: '1rem'
886
- }}>
887
- <TextField2
888
- id="disabledFieldNormal"
889
- label="Campo Deshabilitado"
890
- value="No se puede editar"
891
- disabled={true}
892
- helperText="Estilo normal - Campo deshabilitado"
893
- />
894
-
895
- <TextField2
896
- id="readOnlyFieldNormal"
897
- label="Campo Solo Lectura"
898
- value="Valor de solo lectura"
899
- readOnly={true}
900
- helperText="Estilo normal - Campo de solo lectura"
901
- />
902
-
903
- <TextField2
904
- id="errorFieldNormal"
905
- label="Campo con Error"
906
- value="Valor inválido"
907
- error="Este campo tiene un error"
908
- helperText="Estilo normal - Campo con error"
909
- />
910
-
911
- <TextField2
912
- id="debouncedFieldNormal"
913
- label="Campo con Debounce"
914
- placeholder="Escribe para ver el debouncing..."
915
- value={formData.debouncedFieldNormal || ''}
916
- debounceMs={500}
917
- onChange={handleFieldChange}
918
- helperText="Estilo normal - Cambios con debounce de 500ms"
919
- />
920
-
921
- <TextField2
922
- id="requiredFieldNormal"
923
- label="Campo Requerido"
924
- placeholder="Este campo es obligatorio"
925
- value={formData.requiredFieldNormal || ''}
926
- required={true}
927
- onChange={handleFieldChange}
928
- helperText="Estilo normal - Campo obligatorio"
929
- />
930
-
931
- <TextField2
932
- id="maxLengthFieldNormal"
933
- label="Campo con Límite"
934
- placeholder="Máximo 50 caracteres"
935
- value={formData.maxLengthFieldNormal || ''}
936
- maxLength={50}
937
- onChange={handleFieldChange}
938
- helperText={`Estilo normal - ${(formData.maxLengthFieldNormal || '').length}/50 caracteres`}
939
- />
940
- </div>
941
- </section>
942
-
943
- {/* Estados Especiales - Outlined */}
944
- <section style={{ marginBottom: '2rem' }}>
945
- <h3>⚙️ Estados Especiales - Estilo OUTLINED</h3>
946
- <div style={{
947
- background: '#fff',
948
- padding: '1.5rem',
949
- borderRadius: '8px',
950
- border: '1px solid #ddd',
951
- display: 'grid',
952
- gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
953
- gap: '1rem'
954
- }}>
955
- <TextField2
956
- id="disabledFieldOutlined"
957
- label="Campo Deshabilitado"
958
- value="No se puede editar"
959
- disabled={true}
960
- outlined={true}
961
- helperText="Estilo outlined - Campo deshabilitado"
962
- />
963
-
964
- <TextField2
965
- id="readOnlyFieldOutlined"
966
- label="Campo Solo Lectura"
967
- value="Valor de solo lectura"
968
- readOnly={true}
969
- outlined={true}
970
- helperText="Estilo outlined - Campo de solo lectura"
971
- />
972
-
973
- <TextField2
974
- id="errorFieldOutlined"
975
- label="Campo con Error"
976
- value="Valor inválido"
977
- outlined={true}
978
- error="Este campo tiene un error"
979
- helperText="Estilo outlined - Campo con error"
980
- />
981
-
982
- <TextField2
983
- id="debouncedFieldOutlined"
984
- label="Campo con Debounce"
985
- placeholder="Escribe para ver el debouncing..."
986
- value={formData.debouncedFieldOutlined || ''}
987
- outlined={true}
988
- debounceMs={500}
989
- onChange={handleFieldChange}
990
- helperText="Estilo outlined - Cambios con debounce de 500ms"
991
- />
992
-
993
- <TextField2
994
- id="requiredFieldOutlined"
995
- label="Campo Requerido"
996
- placeholder="Este campo es obligatorio"
997
- value={formData.requiredFieldOutlined || ''}
998
- required={true}
999
- outlined={true}
1000
- onChange={handleFieldChange}
1001
- helperText="Estilo outlined - Campo obligatorio"
1002
- />
1003
-
1004
- <TextField2
1005
- id="maxLengthFieldOutlined"
1006
- label="Campo con Límite"
1007
- placeholder="Máximo 50 caracteres"
1008
- value={formData.maxLengthFieldOutlined || ''}
1009
- maxLength={50}
1010
- outlined={true}
1011
- onChange={handleFieldChange}
1012
- helperText={`Estilo outlined - ${(formData.maxLengthFieldOutlined || '').length}/50 caracteres`}
1013
- />
1014
-
1015
- <TextField2
1016
- id="validationFieldOutlined"
1017
- label="Campo con Validación"
1018
- placeholder="Solo números"
1019
- value={formData.validationFieldOutlined || ''}
1020
- outlined={true}
1021
- validation={(value) => /^\d*$/.test(value)}
1022
- onChange={handleFieldChange}
1023
- onValidation={handleValidation}
1024
- helperText="Estilo outlined - Solo acepta números"
1025
- />
1026
-
1027
- <TextField2
1028
- id="autoCompleteFieldOutlined"
1029
- label="Campo con AutoComplete"
1030
- placeholder="Ingresa tu email"
1031
- value={formData.autoCompleteFieldOutlined || ''}
1032
- outlined={true}
1033
- type="email"
1034
- autoComplete="email"
1035
- onChange={handleFieldChange}
1036
- helperText="Estilo outlined - Con autocompletado"
1037
- />
1038
- </div>
1039
- </section>
1040
-
1041
- {/* Validación Avanzada */}
1042
- <section style={{ marginBottom: '2rem' }}>
1043
- <h3>🔍 Validación Avanzada y Casos Especiales</h3>
1044
- <div style={{
1045
- background: '#fff',
1046
- padding: '1.5rem',
1047
- borderRadius: '8px',
1048
- border: '1px solid #ddd',
1049
- display: 'grid',
1050
- gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
1051
- gap: '1rem'
1052
- }}>
1053
- <TextField2
1054
- id="emailValidation"
1055
- type="email"
1056
- label="Email con Validación"
1057
- placeholder="usuario@dominio.com"
1058
- value={formData.emailValidation || ''}
1059
- outlined={true}
1060
- validation={validateEmail}
1061
- onChange={handleFieldChange}
1062
- onValidation={handleValidation}
1063
- helperText="Validación en tiempo real de email"
1064
- />
1065
-
1066
- <PasswordField2
1067
- id="passwordValidation"
1068
- label="Contraseña Segura"
1069
- placeholder="Contraseña compleja"
1070
- value={formData.passwordValidation || ''}
1071
- outlined={true}
1072
- validation={validatePassword}
1073
- onChange={handleFieldChange}
1074
- onValidation={handleValidation}
1075
- helperText="8+ chars, mayús, minús, número"
1076
- />
1077
-
1078
- <TextField2
1079
- id="phoneValidation"
1080
- type="tel"
1081
- label="Teléfono con Validación"
1082
- placeholder="+34 123 456 789"
1083
- value={formData.phoneValidation || ''}
1084
- outlined={true}
1085
- validation={validatePhone}
1086
- onChange={handleFieldChange}
1087
- onValidation={handleValidation}
1088
- helperText="Formato internacional válido"
1089
- />
1090
-
1091
- <TextField2
1092
- id="customValidation"
1093
- label="Validación Personalizada"
1094
- placeholder="Solo letras y espacios"
1095
- value={formData.customValidation || ''}
1096
- outlined={true}
1097
- validation={(value) => {
1098
- const isValid = /^[a-zA-ZáéíóúÁÉÍÓÚñÑ\s]*$/.test(value)
1099
- return {
1100
- valid: isValid,
1101
- message: isValid ? '' : 'Solo se permiten letras y espacios'
1102
- }
1103
- }}
1104
- onChange={handleFieldChange}
1105
- onValidation={handleValidation}
1106
- helperText="Validación de solo letras"
1107
- />
1108
-
1109
- <TextField2
1110
- id="rangeValidation"
1111
- type="number"
1112
- label="Número en Rango"
1113
- placeholder="Entre 1 y 100"
1114
- value={formData.rangeValidation || ''}
1115
- outlined={true}
1116
- min="1"
1117
- max="100"
1118
- validation={(value) => {
1119
- const num = parseInt(value)
1120
- const isValid = !isNaN(num) && num >= 1 && num <= 100
1121
- return {
1122
- valid: isValid,
1123
- message: isValid ? '' : 'El número debe estar entre 1 y 100'
1124
- }
1125
- }}
1126
- onChange={handleFieldChange}
1127
- onValidation={handleValidation}
1128
- helperText="Número entre 1 y 100"
1129
- />
1130
-
1131
- <TextField2
1132
- id="asyncValidation"
1133
- label="Validación Asíncrona"
1134
- placeholder="Simula validación en servidor"
1135
- value={formData.asyncValidation || ''}
1136
- outlined={true}
1137
- debounceMs={1000}
1138
- validation={(value) => {
1139
- // Simular validación asíncrona
1140
- return new Promise((resolve) => {
1141
- setTimeout(() => {
1142
- const isValid = value.length >= 3 && !value.includes('admin')
1143
- resolve({
1144
- valid: isValid,
1145
- message: isValid ? 'Disponible' : 'No disponible o muy corto'
1146
- })
1147
- }, 500)
1148
- })
1149
- }}
1150
- onChange={handleFieldChange}
1151
- onValidation={handleValidation}
1152
- helperText="Validación con delay (simula servidor)"
1153
- />
1154
- </div>
1155
- </section>
1156
-
1157
- {/* Casos de Uso Reales */}
1158
- <section style={{ marginBottom: '2rem' }}>
1159
- <h3>🏢 Casos de Uso Reales</h3>
1160
- <div style={{
1161
- background: '#fff',
1162
- padding: '1.5rem',
1163
- borderRadius: '8px',
1164
- border: '1px solid #ddd'
1165
- }}>
1166
- <h4>Formulario de Registro de Usuario</h4>
1167
- <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: '1rem', marginBottom: '2rem' }}>
1168
- <TextField2
1169
- id="userFirstName"
1170
- label="Nombre"
1171
- placeholder="Tu nombre"
1172
- value={formData.userFirstName || ''}
1173
- required={true}
1174
- outlined={true}
1175
- onChange={handleFieldChange}
1176
- autoComplete="given-name"
1177
- />
1178
-
1179
- <TextField2
1180
- id="userLastName"
1181
- label="Apellidos"
1182
- placeholder="Tus apellidos"
1183
- value={formData.userLastName || ''}
1184
- required={true}
1185
- outlined={true}
1186
- onChange={handleFieldChange}
1187
- autoComplete="family-name"
1188
- />
1189
-
1190
- <TextField2
1191
- id="userEmail"
1192
- type="email"
1193
- label="Email"
1194
- placeholder="tu@email.com"
1195
- value={formData.userEmail || ''}
1196
- required={true}
1197
- outlined={true}
1198
- validation={validateEmail}
1199
- onChange={handleFieldChange}
1200
- onValidation={handleValidation}
1201
- autoComplete="email"
1202
- />
1203
-
1204
- <PasswordField2
1205
- id="userPassword"
1206
- label="Contraseña"
1207
- placeholder="Contraseña segura"
1208
- value={formData.userPassword || ''}
1209
- required={true}
1210
- outlined={true}
1211
- validation={validatePassword}
1212
- onChange={handleFieldChange}
1213
- onValidation={handleValidation}
1214
- autoComplete="new-password"
1215
- />
1216
- </div>
1217
-
1218
- <h4>Información de Contacto</h4>
1219
- <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: '1rem', marginBottom: '2rem' }}>
1220
- <TextField2
1221
- id="contactPhone"
1222
- type="tel"
1223
- label="Teléfono"
1224
- placeholder="+34 123 456 789"
1225
- value={formData.contactPhone || ''}
1226
- outlined={true}
1227
- validation={validatePhone}
1228
- onChange={handleFieldChange}
1229
- onValidation={handleValidation}
1230
- autoComplete="tel"
1231
- />
1232
-
1233
- <TextField2
1234
- id="contactAddress"
1235
- label="Dirección"
1236
- placeholder="Calle, número, ciudad"
1237
- value={formData.contactAddress || ''}
1238
- outlined={true}
1239
- onChange={handleFieldChange}
1240
- autoComplete="street-address"
1241
- />
1242
-
1243
- <DropDown2
1244
- id="contactCountry"
1245
- label="País"
1246
- placeholder="Selecciona tu país"
1247
- options={countryOptions}
1248
- value={formData.contactCountry || ''}
1249
- outlined={true}
1250
- searchable={true}
1251
- onChange={handleFieldChange}
1252
- />
1253
- </div>
1254
-
1255
- <h4>Información Adicional</h4>
1256
- <div style={{ display: 'grid', gap: '1rem' }}>
1257
- <TextArea2
1258
- id="userBio"
1259
- label="Biografía"
1260
- placeholder="Cuéntanos sobre ti..."
1261
- value={formData.userBio || ''}
1262
- outlined={true}
1263
- rows={4}
1264
- maxLength={500}
1265
- onChange={handleFieldChange}
1266
- helperText={`${(formData.userBio || '').length}/500 caracteres`}
1267
- />
1268
-
1269
- <DropDown2
1270
- id="userSkills"
1271
- label="Habilidades"
1272
- placeholder="Selecciona tus habilidades"
1273
- options={skillOptions}
1274
- value={formData.userSkills || []}
1275
- multiple={true}
1276
- outlined={true}
1277
- searchable={true}
1278
- groupBy="category"
1279
- onChange={handleFieldChange}
1280
- />
1281
- </div>
1282
- </div>
1283
- </section>
1284
-
1285
- {/* Estado actual del formulario */}
1286
- <section style={{ marginBottom: '2rem' }}>
1287
- <h3>📊 Estado Actual del Formulario</h3>
1288
- <div style={{
1289
- background: '#f8f9fa',
1290
- padding: '1rem',
1291
- borderRadius: '4px',
1292
- border: '1px solid #dee2e6'
1293
- }}>
1294
- <h4>Datos:</h4>
1295
- <pre style={{
1296
- background: '#ffffff',
1297
- padding: '1rem',
1298
- borderRadius: '4px',
1299
- fontSize: '0.8rem',
1300
- overflow: 'auto',
1301
- maxHeight: '200px'
1302
- }}>
1303
- {JSON.stringify(formData, null, 2)}
1304
- </pre>
1305
-
1306
- <h4>Errores de Validación:</h4>
1307
- <pre style={{
1308
- background: '#ffffff',
1309
- padding: '1rem',
1310
- borderRadius: '4px',
1311
- fontSize: '0.8rem',
1312
- overflow: 'auto',
1313
- maxHeight: '100px'
1314
- }}>
1315
- {JSON.stringify(Object.fromEntries(
1316
- Object.entries(validationErrors).filter(([_, error]) => error)
1317
- ), null, 2)}
1318
- </pre>
1319
- </div>
1320
- </section>
1321
-
1322
- {/* Comparación antes/después */}
1323
- <section style={{ marginBottom: '2rem' }}>
1324
- <h3>Comparación: TextField Original vs TextField2</h3>
1325
- <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '1rem' }}>
1326
- <div style={{
1327
- background: '#ffebee',
1328
- padding: '1rem',
1329
- borderRadius: '4px',
1330
- border: '1px solid #ffcdd2'
1331
- }}>
1332
- <h4>❌ TextField Original</h4>
1333
- <ul>
1334
- <li>Sin PropTypes</li>
1335
- <li>Sin accesibilidad</li>
1336
- <li>Manipulación directa del DOM</li>
1337
- <li>CSS con altura fija</li>
1338
- <li>Sin validación integrada</li>
1339
- <li>Sin debouncing</li>
1340
- <li>Sin estados de error</li>
1341
- <li>DropDown complejo y frágil</li>
1342
- <li>DateRange básico</li>
1343
- </ul>
1344
- </div>
1345
- <div style={{
1346
- background: '#e8f5e8',
1347
- padding: '1rem',
1348
- borderRadius: '4px',
1349
- border: '1px solid #c8e6c9'
1350
- }}>
1351
- <h4>✅ TextField2 Mejorado</h4>
1352
- <ul>
1353
- <li>PropTypes completos</li>
1354
- <li>Accesibilidad total (WCAG 2.1 AA)</li>
1355
- <li>Sin manipulación directa del DOM</li>
1356
- <li>CSS con altura automática</li>
1357
- <li>Validación personalizable</li>
1358
- <li>Debouncing configurable</li>
1359
- <li>Estados completos de error</li>
1360
- <li>DropDown2 robusto y accesible</li>
1361
- <li>DateRange2 con validación</li>
1362
- </ul>
1363
- </div>
1364
- </div>
1365
- </section>
1366
- </div>
1367
- )
1368
- }
1369
-
1370
- export default TextField2Examples