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.
- package/dist/index.css +4941 -324
- package/dist/index.js +42339 -0
- package/dist/index.js.map +1 -0
- package/dist/index.modern.js +37459 -31678
- package/dist/index.modern.js.map +1 -1
- package/dist/index.umd.js +39635 -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 +255 -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,385 +0,0 @@
|
|
1
|
-
import React, { useState } from 'react'
|
2
|
-
import { Form } from './form'
|
3
|
-
import { TextField2 } from './textfield2'
|
4
|
-
import { Button } from './button'
|
5
|
-
import { RadioGroup } from './radio'
|
6
|
-
import { Chips } from './chip'
|
7
|
-
|
8
|
-
/**
|
9
|
-
* Ejemplos de uso del componente Form mejorado
|
10
|
-
*/
|
11
|
-
export const FormExamples = () => {
|
12
|
-
const [formData, setFormData] = useState({})
|
13
|
-
const [isValid, setIsValid] = useState(false)
|
14
|
-
const [isSubmitting, setIsSubmitting] = useState(false)
|
15
|
-
|
16
|
-
const handleFormChange = (data, valid) => {
|
17
|
-
setFormData(data)
|
18
|
-
setIsValid(valid)
|
19
|
-
}
|
20
|
-
|
21
|
-
const handleSubmit = async (data) => {
|
22
|
-
setIsSubmitting(true)
|
23
|
-
try {
|
24
|
-
// Simular envío de formulario
|
25
|
-
await new Promise(resolve => setTimeout(resolve, 2000))
|
26
|
-
alert(`Formulario enviado: ${JSON.stringify(data, null, 2)}`)
|
27
|
-
} catch (error) {
|
28
|
-
alert('Error al enviar formulario')
|
29
|
-
} finally {
|
30
|
-
setIsSubmitting(false)
|
31
|
-
}
|
32
|
-
}
|
33
|
-
|
34
|
-
const handleReset = () => {
|
35
|
-
setFormData({})
|
36
|
-
setIsValid(false)
|
37
|
-
}
|
38
|
-
|
39
|
-
// Validaciones personalizadas
|
40
|
-
const validateEmail = (value) => {
|
41
|
-
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
42
|
-
return emailRegex.test(value)
|
43
|
-
}
|
44
|
-
|
45
|
-
const validatePassword = (value) => {
|
46
|
-
return value && value.length >= 6
|
47
|
-
}
|
48
|
-
|
49
|
-
const validateAge = (value) => {
|
50
|
-
const age = parseInt(value)
|
51
|
-
return age >= 18 && age <= 100
|
52
|
-
}
|
53
|
-
|
54
|
-
return (
|
55
|
-
<div style={{ padding: '2rem', maxWidth: '1000px' }}>
|
56
|
-
<h1>Ejemplos de Componente Form Mejorado</h1>
|
57
|
-
|
58
|
-
<div style={{
|
59
|
-
background: '#f8f9fa',
|
60
|
-
padding: '1rem',
|
61
|
-
borderRadius: '8px',
|
62
|
-
marginBottom: '2rem',
|
63
|
-
border: '1px solid #e9ecef'
|
64
|
-
}}>
|
65
|
-
<h3>✅ Mejoras Implementadas:</h3>
|
66
|
-
<ul>
|
67
|
-
<li>🛡️ <strong>Validación de props</strong> - Advertencias para props incorrectas</li>
|
68
|
-
<li>♿ <strong>Accesibilidad completa</strong> - ARIA, manejo de formularios</li>
|
69
|
-
<li>📝 <strong>PropTypes y documentación</strong> - Validación y documentación completa</li>
|
70
|
-
<li>🎯 <strong>Estados avanzados</strong> - disabled, loading, submission</li>
|
71
|
-
<li>🎨 <strong>CSS mejorado</strong> - Altura automática, responsive design</li>
|
72
|
-
<li>🔧 <strong>Manejo de envío</strong> - onSubmit, onReset, validación</li>
|
73
|
-
<li>📊 <strong>Validación integrada</strong> - Validación automática de campos</li>
|
74
|
-
<li>🔄 <strong>Estado inmutable</strong> - Sin mutación directa de estado</li>
|
75
|
-
<li>📱 <strong>Responsive</strong> - Adaptable a diferentes tamaños</li>
|
76
|
-
<li>🧪 <strong>Pruebas unitarias</strong> - 15 pruebas que cubren toda la funcionalidad</li>
|
77
|
-
</ul>
|
78
|
-
</div>
|
79
|
-
|
80
|
-
{/* Formulario básico */}
|
81
|
-
<section style={{ marginBottom: '2rem' }}>
|
82
|
-
<h3>Formulario Básico</h3>
|
83
|
-
<div style={{
|
84
|
-
background: '#fff',
|
85
|
-
padding: '1.5rem',
|
86
|
-
borderRadius: '8px',
|
87
|
-
border: '1px solid #ddd'
|
88
|
-
}}>
|
89
|
-
<Form
|
90
|
-
title="Información Personal"
|
91
|
-
columns={2}
|
92
|
-
outlined={true}
|
93
|
-
onChange={handleFormChange}
|
94
|
-
onSubmit={handleSubmit}
|
95
|
-
onReset={handleReset}
|
96
|
-
>
|
97
|
-
<TextField2
|
98
|
-
id="firstName"
|
99
|
-
label="Nombre"
|
100
|
-
required={true}
|
101
|
-
span={1}
|
102
|
-
/>
|
103
|
-
<TextField2
|
104
|
-
id="lastName"
|
105
|
-
label="Apellido"
|
106
|
-
required={true}
|
107
|
-
span={1}
|
108
|
-
/>
|
109
|
-
<TextField2
|
110
|
-
id="email"
|
111
|
-
label="Email"
|
112
|
-
type="email"
|
113
|
-
required={true}
|
114
|
-
validation={validateEmail}
|
115
|
-
span={2}
|
116
|
-
/>
|
117
|
-
<TextField2
|
118
|
-
id="age"
|
119
|
-
label="Edad"
|
120
|
-
type="number"
|
121
|
-
required={true}
|
122
|
-
validation={validateAge}
|
123
|
-
span={1}
|
124
|
-
/>
|
125
|
-
<TextField2
|
126
|
-
id="phone"
|
127
|
-
label="Teléfono"
|
128
|
-
type="tel"
|
129
|
-
span={1}
|
130
|
-
/>
|
131
|
-
|
132
|
-
<div style={{ gridColumn: 'span 2', display: 'flex', gap: '1rem', justifyContent: 'flex-end' }}>
|
133
|
-
<Button
|
134
|
-
type="reset"
|
135
|
-
label="Limpiar"
|
136
|
-
outlined={true}
|
137
|
-
/>
|
138
|
-
<Button
|
139
|
-
type="submit"
|
140
|
-
label="Enviar"
|
141
|
-
raised={true}
|
142
|
-
disabled={!isValid}
|
143
|
-
loading={isSubmitting}
|
144
|
-
/>
|
145
|
-
</div>
|
146
|
-
</Form>
|
147
|
-
</div>
|
148
|
-
</section>
|
149
|
-
|
150
|
-
{/* Formulario con validación */}
|
151
|
-
<section style={{ marginBottom: '2rem' }}>
|
152
|
-
<h3>Formulario con Validación Avanzada</h3>
|
153
|
-
<div style={{
|
154
|
-
background: '#fff',
|
155
|
-
padding: '1.5rem',
|
156
|
-
borderRadius: '8px',
|
157
|
-
border: '1px solid #ddd'
|
158
|
-
}}>
|
159
|
-
<Form
|
160
|
-
title="Registro de Usuario"
|
161
|
-
columns={1}
|
162
|
-
outlined={true}
|
163
|
-
onChange={handleFormChange}
|
164
|
-
>
|
165
|
-
<TextField2
|
166
|
-
id="username"
|
167
|
-
label="Nombre de usuario"
|
168
|
-
required={true}
|
169
|
-
validation={(value) => value && value.length >= 3}
|
170
|
-
/>
|
171
|
-
<TextField2
|
172
|
-
id="password"
|
173
|
-
label="Contraseña"
|
174
|
-
type="password"
|
175
|
-
required={true}
|
176
|
-
validation={validatePassword}
|
177
|
-
/>
|
178
|
-
<TextField2
|
179
|
-
id="confirmPassword"
|
180
|
-
label="Confirmar contraseña"
|
181
|
-
type="password"
|
182
|
-
required={true}
|
183
|
-
validation={(value) => value === formData.password}
|
184
|
-
/>
|
185
|
-
|
186
|
-
<RadioGroup
|
187
|
-
id="accountType"
|
188
|
-
label="Tipo de cuenta"
|
189
|
-
required={true}
|
190
|
-
options={[
|
191
|
-
{ id: 'personal', label: 'Personal', value: 'personal' },
|
192
|
-
{ id: 'business', label: 'Empresarial', value: 'business' },
|
193
|
-
{ id: 'developer', label: 'Desarrollador', value: 'developer' }
|
194
|
-
]}
|
195
|
-
/>
|
196
|
-
</Form>
|
197
|
-
</div>
|
198
|
-
</section>
|
199
|
-
|
200
|
-
{/* Formulario de múltiples columnas */}
|
201
|
-
<section style={{ marginBottom: '2rem' }}>
|
202
|
-
<h3>Formulario de Múltiples Columnas</h3>
|
203
|
-
<div style={{
|
204
|
-
background: '#fff',
|
205
|
-
padding: '1.5rem',
|
206
|
-
borderRadius: '8px',
|
207
|
-
border: '1px solid #ddd'
|
208
|
-
}}>
|
209
|
-
<Form
|
210
|
-
title="Dirección de Envío"
|
211
|
-
columns={3}
|
212
|
-
outlined={true}
|
213
|
-
onChange={handleFormChange}
|
214
|
-
>
|
215
|
-
<TextField2
|
216
|
-
id="street"
|
217
|
-
label="Calle"
|
218
|
-
required={true}
|
219
|
-
span={2}
|
220
|
-
/>
|
221
|
-
<TextField2
|
222
|
-
id="number"
|
223
|
-
label="Número"
|
224
|
-
required={true}
|
225
|
-
span={1}
|
226
|
-
/>
|
227
|
-
<TextField2
|
228
|
-
id="city"
|
229
|
-
label="Ciudad"
|
230
|
-
required={true}
|
231
|
-
span={1}
|
232
|
-
/>
|
233
|
-
<TextField2
|
234
|
-
id="state"
|
235
|
-
label="Estado/Provincia"
|
236
|
-
required={true}
|
237
|
-
span={1}
|
238
|
-
/>
|
239
|
-
<TextField2
|
240
|
-
id="zipCode"
|
241
|
-
label="Código Postal"
|
242
|
-
required={true}
|
243
|
-
span={1}
|
244
|
-
/>
|
245
|
-
<TextField2
|
246
|
-
id="country"
|
247
|
-
label="País"
|
248
|
-
required={true}
|
249
|
-
span={3}
|
250
|
-
/>
|
251
|
-
</Form>
|
252
|
-
</div>
|
253
|
-
</section>
|
254
|
-
|
255
|
-
{/* Formulario deshabilitado */}
|
256
|
-
<section style={{ marginBottom: '2rem' }}>
|
257
|
-
<h3>Estados Especiales</h3>
|
258
|
-
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '1rem' }}>
|
259
|
-
<div style={{
|
260
|
-
background: '#fff',
|
261
|
-
padding: '1.5rem',
|
262
|
-
borderRadius: '8px',
|
263
|
-
border: '1px solid #ddd'
|
264
|
-
}}>
|
265
|
-
<h4>Formulario Deshabilitado</h4>
|
266
|
-
<Form
|
267
|
-
title="Solo Lectura"
|
268
|
-
columns={1}
|
269
|
-
outlined={true}
|
270
|
-
disabled={true}
|
271
|
-
>
|
272
|
-
<TextField2
|
273
|
-
id="readOnlyField1"
|
274
|
-
label="Campo 1"
|
275
|
-
value="Valor fijo"
|
276
|
-
/>
|
277
|
-
<TextField2
|
278
|
-
id="readOnlyField2"
|
279
|
-
label="Campo 2"
|
280
|
-
value="Otro valor"
|
281
|
-
/>
|
282
|
-
</Form>
|
283
|
-
</div>
|
284
|
-
|
285
|
-
<div style={{
|
286
|
-
background: '#fff',
|
287
|
-
padding: '1.5rem',
|
288
|
-
borderRadius: '8px',
|
289
|
-
border: '1px solid #ddd'
|
290
|
-
}}>
|
291
|
-
<h4>Formulario Cargando</h4>
|
292
|
-
<Form
|
293
|
-
title="Enviando..."
|
294
|
-
columns={1}
|
295
|
-
outlined={true}
|
296
|
-
loading={true}
|
297
|
-
>
|
298
|
-
<TextField2
|
299
|
-
id="loadingField1"
|
300
|
-
label="Campo 1"
|
301
|
-
value="Enviando datos..."
|
302
|
-
/>
|
303
|
-
<TextField2
|
304
|
-
id="loadingField2"
|
305
|
-
label="Campo 2"
|
306
|
-
value="Por favor espere..."
|
307
|
-
/>
|
308
|
-
</Form>
|
309
|
-
</div>
|
310
|
-
</div>
|
311
|
-
</section>
|
312
|
-
|
313
|
-
{/* Estado actual del formulario */}
|
314
|
-
<section style={{ marginBottom: '2rem' }}>
|
315
|
-
<h3>Estado Actual del Formulario</h3>
|
316
|
-
<div style={{
|
317
|
-
background: '#f8f9fa',
|
318
|
-
padding: '1rem',
|
319
|
-
borderRadius: '4px',
|
320
|
-
border: '1px solid #dee2e6'
|
321
|
-
}}>
|
322
|
-
<p><strong>Válido:</strong> {isValid ? '✅ Sí' : '❌ No'}</p>
|
323
|
-
<p><strong>Enviando:</strong> {isSubmitting ? '⏳ Sí' : '✅ No'}</p>
|
324
|
-
<pre style={{
|
325
|
-
background: '#ffffff',
|
326
|
-
padding: '1rem',
|
327
|
-
borderRadius: '4px',
|
328
|
-
fontSize: '0.9rem',
|
329
|
-
overflow: 'auto',
|
330
|
-
maxHeight: '200px'
|
331
|
-
}}>
|
332
|
-
{JSON.stringify(formData, null, 2)}
|
333
|
-
</pre>
|
334
|
-
</div>
|
335
|
-
</section>
|
336
|
-
|
337
|
-
{/* Comparación antes/después */}
|
338
|
-
<section style={{ marginBottom: '2rem' }}>
|
339
|
-
<h3>Comparación: Antes vs Después</h3>
|
340
|
-
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '1rem' }}>
|
341
|
-
<div style={{
|
342
|
-
background: '#ffebee',
|
343
|
-
padding: '1rem',
|
344
|
-
borderRadius: '4px',
|
345
|
-
border: '1px solid #ffcdd2'
|
346
|
-
}}>
|
347
|
-
<h4>❌ Antes</h4>
|
348
|
-
<ul>
|
349
|
-
<li>Sin validación de props</li>
|
350
|
-
<li>Sin accesibilidad</li>
|
351
|
-
<li>Mutación directa de estado</li>
|
352
|
-
<li>Sin manejo de submit</li>
|
353
|
-
<li>CSS con altura fija</li>
|
354
|
-
<li>Dependencias frágiles</li>
|
355
|
-
<li>Sin estados de loading/error</li>
|
356
|
-
<li>Sin reset de formulario</li>
|
357
|
-
<li>Sin soporte para fieldsets</li>
|
358
|
-
</ul>
|
359
|
-
</div>
|
360
|
-
<div style={{
|
361
|
-
background: '#e8f5e8',
|
362
|
-
padding: '1rem',
|
363
|
-
borderRadius: '4px',
|
364
|
-
border: '1px solid #c8e6c9'
|
365
|
-
}}>
|
366
|
-
<h4>✅ Después</h4>
|
367
|
-
<ul>
|
368
|
-
<li>PropTypes completos</li>
|
369
|
-
<li>Accesibilidad total</li>
|
370
|
-
<li>Estado inmutable</li>
|
371
|
-
<li>Manejo completo de envío</li>
|
372
|
-
<li>CSS con altura automática</li>
|
373
|
-
<li>Props robustas</li>
|
374
|
-
<li>Estados de loading/disabled</li>
|
375
|
-
<li>Reset integrado</li>
|
376
|
-
<li>Estructura flexible</li>
|
377
|
-
</ul>
|
378
|
-
</div>
|
379
|
-
</div>
|
380
|
-
</section>
|
381
|
-
</div>
|
382
|
-
)
|
383
|
-
}
|
384
|
-
|
385
|
-
export default FormExamples
|