ywana-core8 0.1.103 → 0.2.1
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.
- package/dist/index.css +4941 -324
- package/dist/index.js +42338 -0
- package/dist/index.js.map +1 -0
- package/dist/index.modern.js +37458 -31678
- package/dist/index.modern.js.map +1 -1
- package/dist/index.umd.js +39634 -34010
- package/dist/index.umd.js.map +1 -1
- package/package.json +26 -29
- package/src/Test.stories.jsx +28 -0
- package/src/desktop/Desktop.stories.jsx +110 -0
- package/src/desktop/WindowContext.js +135 -0
- package/src/desktop/WindowManager.js +355 -0
- package/src/desktop/desktop.css +55 -4
- package/src/desktop/desktop.js +312 -6
- package/src/desktop/index.js +7 -0
- package/src/desktop/window.css +229 -36
- package/src/desktop/window.js +254 -20
- package/src/desktop.backup/desktop.css +6 -0
- package/src/desktop.backup/desktop.js +13 -0
- package/src/desktop.backup/window.css +58 -0
- package/src/desktop.backup/window.js +27 -0
- package/src/html/Accordion.stories.jsx +178 -0
- package/src/html/Button.stories.jsx +175 -0
- package/src/html/Checkbox.stories.jsx +131 -0
- package/src/html/Chip.stories.jsx +189 -0
- package/src/html/Color.stories.jsx +234 -0
- package/src/html/Form.stories.jsx +271 -0
- package/src/html/Icon.stories.jsx +233 -0
- package/src/html/Progress.stories.jsx +247 -0
- package/src/html/Radio.stories.jsx +289 -0
- package/src/html/StyleTest.stories.jsx +81 -0
- package/src/html/Switch.stories.jsx +329 -0
- package/src/html/Tab.stories.jsx +239 -0
- package/src/html/Table.stories.jsx +188 -0
- package/src/html/Table2.stories.jsx +238 -0
- package/src/html/TextField2.stories.jsx +337 -0
- package/src/html/Tree.stories.jsx +285 -0
- package/src/html/accordion.example.js +0 -74
- package/src/html/accordion.js +1 -6
- package/src/html/button.js +2 -13
- package/src/html/checkbox.js +1 -9
- package/src/html/chip.js +2 -19
- package/src/html/color.js +1 -14
- package/src/html/form.js +4 -15
- package/src/html/header2.js +1 -12
- package/src/html/icon.js +1 -7
- package/src/html/index.js +1 -1
- package/src/html/list.js +1 -19
- package/src/html/menu.js +9 -5
- package/src/html/progress.js +5 -53
- package/src/html/property.js +9 -25
- package/src/html/radio.js +2 -16
- package/src/html/section.js +1 -6
- package/src/html/selector.js +2 -19
- package/src/html/switch.css +134 -100
- package/src/html/switch.example.js +46 -36
- package/src/html/switch.js +43 -192
- package/src/html/tab.js +3 -24
- package/src/html/text.js +1 -12
- package/src/html/textfield2.js +5 -42
- package/src/html/thumbnail.js +1 -12
- package/src/html/tokenfield.js +2 -21
- package/src/html/tree.js +3 -35
- package/src/index.js +1 -0
- package/__previewjs__/Wrapper.tsx +0 -14
- package/build-doc.sh +0 -10
- package/db/db.json +0 -89
- package/db/routes.json +0 -0
- package/dist/index.cjs +0 -36722
- package/dist/index.cjs.map +0 -1
- package/dist/index.css.map +0 -1
- package/doc/README.md +0 -196
- package/doc/evalulations/ACCORDION_EVALUATION.md +0 -583
- package/doc/evalulations/CHECKBOX_EVALUATION.md +0 -273
- package/doc/evalulations/CHIP_EVALUATION.md +0 -542
- package/doc/evalulations/COLOR_EVALUATION.md +0 -524
- package/doc/evalulations/COMPONENTS_EVALUATION.md +0 -477
- package/doc/evalulations/FORM_EVALUATION.md +0 -459
- package/doc/evalulations/HEADER_EVALUATION.md +0 -436
- package/doc/evalulations/ICON_EVALUATION.md +0 -254
- package/doc/evalulations/LIST_EVALUATION.md +0 -574
- package/doc/evalulations/PROGRESS_EVALUATION.md +0 -450
- package/doc/evalulations/RADIO_EVALUATION.md +0 -439
- package/doc/evalulations/RADIO_VISUAL_FIX.md +0 -183
- package/doc/evalulations/SECTION_IMPROVEMENTS.md +0 -153
- package/doc/evalulations/SWITCH_EVALUATION.md +0 -335
- package/doc/evalulations/SWITCH_VISUAL_FIX.md +0 -232
- package/doc/evalulations/TAB_EVALUATION.md +0 -626
- package/doc/evalulations/TEXTFIELD_EVALUATION.md +0 -747
- package/doc/evalulations/TOOLTIP_FIX.md +0 -157
- package/doc/evalulations/TREE_EVALUATION.md +0 -708
- package/doc/index.html +0 -0
- package/doc/package-lock.json +0 -17298
- package/doc/package.json +0 -34
- package/doc/public/index.html +0 -24
- package/doc/scripts/generate-examples.js +0 -129
- package/doc/src/App.css +0 -171
- package/doc/src/App.js +0 -114
- package/doc/src/components/ExamplePage.js +0 -129
- package/doc/src/components/WelcomePage.js +0 -84
- package/doc/src/index.css +0 -246
- package/doc/src/index.js +0 -17
- package/doc/src/theme.css +0 -256
- package/jest.config.js +0 -24
- package/preview.config.js +0 -38
- package/publish.sh +0 -6
- package/src/desktop/dektop.test.js +0 -11
- package/src/domain/CollectionAPI.test.js +0 -19
- package/src/domain/ContentEditor.test.js +0 -52
- package/src/domain2/CollectionAPI.test.js +0 -19
- package/src/domain2/CollectionContext.test.js +0 -71
- package/src/domain2/CollectionPage.test.js +0 -112
- package/src/domain2/DynamicForm.test.js +0 -47
- package/src/html/accordion.test.js +0 -37
- package/src/html/accordion.unit.test.js +0 -334
- package/src/html/button.example.new.js +0 -416
- package/src/html/button.test.js +0 -422
- package/src/html/checkbox.test.js +0 -285
- package/src/html/chip.test.js +0 -425
- package/src/html/color.example.js.backup +0 -527
- package/src/html/color.test.js +0 -377
- package/src/html/components.example.js.backup +0 -492
- package/src/html/components_enhanced.test.js +0 -581
- package/src/html/form.example.js.backup +0 -385
- package/src/html/form.test.js +0 -369
- package/src/html/header2.example.js.backup +0 -411
- package/src/html/header2.test.js +0 -377
- package/src/html/icon.example.js.backup +0 -268
- package/src/html/icon.test.js +0 -231
- package/src/html/label.test.js +0 -0
- package/src/html/list.example.js.backup +0 -404
- package/src/html/list.test.js +0 -383
- package/src/html/progress.example.js.backup +0 -424
- package/src/html/progress.test.js +0 -313
- package/src/html/property.example.js.backup +0 -553
- package/src/html/property.test.js +0 -371
- package/src/html/radio.example.js.backup +0 -389
- package/src/html/radio.test.js +0 -318
- package/src/html/section.example.js.backup +0 -99
- package/src/html/section.test.js +0 -131
- package/src/html/selector.test.js +0 -20
- package/src/html/switch.example.js.backup +0 -461
- package/src/html/switch.test.js +0 -355
- package/src/html/tab.example.js.backup +0 -446
- package/src/html/tab.test.js +0 -25
- package/src/html/tab_enhanced.test.js +0 -504
- package/src/html/table.test.js +0 -70
- package/src/html/table2.test.js +0 -582
- package/src/html/text.test.js +0 -15
- package/src/html/textfield.test.js +0 -51
- package/src/html/textfield2.example.js.backup +0 -1370
- package/src/html/textfield2.test.js +0 -950
- package/src/html/tokenfield.example.js.backup +0 -503
- package/src/html/tokenfield.test.js +0 -423
- package/src/html/tree.example.js.backup +0 -475
- package/src/html/tree.test.js +0 -43
- package/src/html/tree_enhanced.test.js +0 -495
- package/src/http/token.test.js +0 -50
- package/src/incubator/pdfViewer.js +0 -33
- package/src/incubator/wizard.test.js +0 -127
- package/src/site/site.test.js +0 -230
- package/src/site/view.test.js +0 -41
- package/src/widgets/calendar/Calendar.test.js +0 -28
- package/src/widgets/explorer/Explorer.test.js +0 -121
- package/src/widgets/ide/editor.test.js +0 -33
- package/src/widgets/kanban/Kanban.test.js +0 -78
- package/src/widgets/login/LoginBox.test.js +0 -12
- package/src/widgets/login/ResetPasswordBox.test.js +0 -34
- package/src/widgets/login/validations.test.js +0 -51
- package/src/widgets/planner/Planner.test.js +0 -60
- package/src/widgets/upload/Upload.test.js +0 -32
- 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
|