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.
Files changed (172) hide show
  1. package/dist/index.css +4941 -324
  2. package/dist/index.js +42338 -0
  3. package/dist/index.js.map +1 -0
  4. package/dist/index.modern.js +37458 -31678
  5. package/dist/index.modern.js.map +1 -1
  6. package/dist/index.umd.js +39634 -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 +254 -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,583 +0,0 @@
1
- # 📋 Evaluación del Componente Accordion
2
-
3
- ## 📊 Resumen de Evaluación
4
-
5
- **Calificación Original:** 6.5/10
6
- **Calificación Después de Mejoras:** 9.5/10
7
-
8
- ## 🔍 Análisis Original
9
-
10
- ### ✅ **Aspectos Positivos Identificados:**
11
-
12
- 1. **Funcionalidad completa** - Manejo de secciones abiertas/cerradas y checked
13
- 2. **Flexibilidad** - Soporte para icon, title, subtitle, info, toolbar
14
- 3. **Uso extensivo** - Se usa en SectionsEditor, TablePage2, ContentEditor
15
- 4. **Estado interno** - Maneja openSections y checkedSections correctamente
16
- 5. **Callbacks** - onCheck para notificar cambios
17
- 6. **Estructura clara** - Separación entre Accordion y AccordionSection
18
-
19
- ### ⚠️ **Problemas Críticos Identificados:**
20
-
21
- 1. **Falta de PropTypes** - No había validación de tipos ni documentación
22
- 2. **Falta de accesibilidad** - Sin atributos ARIA ni manejo de teclado
23
- 3. **Key usando index** - `key={index}` puede causar problemas de renderizado
24
- 4. **Concatenación de strings frágil** - `className={`accordion ${className}`}`
25
- 5. **Sin validación** - No validaba props requeridas
26
- 6. **Funciones no optimizadas** - No usaba useCallback
27
- 7. **CSS básico** - Falta padding, estados, responsive, animaciones
28
- 8. **Sin estados avanzados** - No manejaba disabled, loading
29
- 9. **Sin animaciones** - Transiciones abruptas
30
- 10. **Renderizado condicional con strings** - `? '' : ''` en lugar de null
31
-
32
- ## 🔧 Mejoras Implementadas
33
-
34
- ### 1. **Accordion Component (Mejorado)**
35
-
36
- **Antes:**
37
- ```javascript
38
- export const Accordion = (props) => {
39
- const { className, sections = [], onCheck } = props
40
- const [openSections, setOpenSections] = useState([])
41
- const [checkedSections, setCheckedSections] = useState([])
42
-
43
- function toggle(index) {
44
- const next = openSections.map((open, i) => i === index ? !open : open)
45
- setOpenSections(next)
46
- }
47
-
48
- function check(index) {
49
- const next = checkedSections.map((checked, i) => i === index ? !checked : checked)
50
- setCheckedSections(next)
51
- if (onCheck) onCheck(index, next[index], sections[index].id)
52
- }
53
-
54
- return (
55
- <div className={`accordion ${className}`}>
56
- {sections.map((section, index) => {
57
- const isOpen = openSections[index]
58
- const isChecked = checkedSections[index]
59
- return (
60
- <AccordionSection key={index} {...section} open={isOpen} checked={isChecked} onToggle={() => toggle(index)} onCheck={() => check(index)}>
61
- {section.children}
62
- </AccordionSection>
63
- )
64
- })}
65
- </div>
66
- )
67
- }
68
- ```
69
-
70
- **Después:**
71
- ```javascript
72
- export const Accordion = (props) => {
73
- const {
74
- className,
75
- sections = [],
76
- disabled = false,
77
- allowMultiple = true,
78
- animated = true,
79
- onCheck,
80
- onToggle,
81
- onSectionChange,
82
- ariaLabel,
83
- ...restProps
84
- } = props
85
-
86
- // Validación de props
87
- if (!Array.isArray(sections)) {
88
- console.warn('Accordion component: sections prop must be an array')
89
- }
90
-
91
- // Toggle optimizado con useCallback
92
- const toggle = useCallback((index) => {
93
- if (disabled) return
94
-
95
- setOpenSections(prevOpen => {
96
- const next = allowMultiple
97
- ? prevOpen.map((open, i) => i === index ? !open : open)
98
- : prevOpen.map((open, i) => i === index ? !open : false)
99
-
100
- if (onToggle) onToggle(index, next[index], sections[index])
101
- if (onSectionChange) onSectionChange('toggle', index, next[index], sections[index])
102
-
103
- return next
104
- })
105
- }, [disabled, allowMultiple, onToggle, onSectionChange, sections])
106
-
107
- // Check optimizado con useCallback
108
- const check = useCallback((index) => {
109
- if (disabled) return
110
-
111
- setCheckedSections(prevChecked => {
112
- const next = prevChecked.map((checked, i) => i === index ? !checked : checked)
113
-
114
- if (onCheck) onCheck(index, next[index], sections[index]?.id, sections[index])
115
- if (onSectionChange) onSectionChange('check', index, next[index], sections[index])
116
-
117
- return next
118
- })
119
- }, [disabled, onCheck, onSectionChange, sections])
120
-
121
- // Generación robusta de clases CSS
122
- const cssClasses = [
123
- 'accordion',
124
- disabled && 'disabled',
125
- animated && 'animated',
126
- className || ''
127
- ].filter(Boolean).join(' ')
128
-
129
- // Atributos de accesibilidad
130
- const ariaAttributes = {
131
- 'aria-label': ariaLabel || 'Accordion',
132
- 'aria-disabled': disabled,
133
- role: 'region'
134
- }
135
-
136
- return (
137
- <div className={cssClasses} {...ariaAttributes} {...restProps}>
138
- {sections.map((section, index) => {
139
- const isOpen = openSections[index]
140
- const isChecked = checkedSections[index]
141
- const sectionId = section.id || `accordion-section-${index}` // Key mejorado
142
-
143
- return (
144
- <AccordionSection
145
- key={sectionId} // Usa ID en lugar de index
146
- {...section}
147
- open={isOpen}
148
- checked={isChecked}
149
- disabled={disabled || section.disabled}
150
- animated={animated}
151
- sectionIndex={index}
152
- onToggle={() => toggle(index)}
153
- onCheck={() => check(index)}
154
- >
155
- {section.children}
156
- </AccordionSection>
157
- )
158
- })}
159
- </div>
160
- )
161
- }
162
- ```
163
-
164
- ### 2. **AccordionSection Component (Mejorado)**
165
-
166
- **Antes:**
167
- ```javascript
168
- const AccordionSection = (props) => {
169
- const { checked, icon, title, subtitle, open = false, onToggle, onCheck, toolbar, info, children } = props
170
- const togglerIcon = open ? "expand_less" : "expand_more"
171
- const checkedIcon = checked === undefined || checked === null ? null : checked === false ? "check_box_outline_blank" : "check_box"
172
-
173
- return (
174
- <section key={title} className={`accordion-section`}>
175
- <header>
176
- { checkedIcon ? <Icon className="accordion-section-checker" icon={checkedIcon} clickable action={onCheck}/> : '' }
177
- { icon ? <Icon className="accordion-section-icon" icon={icon} /> : '' }
178
- { title ? <div className="accordion-section--title">{title}</div> : '' }
179
- { subtitle ? <div className="accordion-section--subtitle">{subtitle}</div> : '' }
180
- { info ? <div className="accordion-section--info">{info}</div> : '' }
181
- { toolbar ? <div className="accordion-section--toolbar">{toolbar}</div> : '' }
182
- <Icon className="accordion-section-toggler" icon={togglerIcon} clickable action={onToggle} />
183
- </header>
184
- {open ? <main>{children}</main> : ''}
185
- </section>
186
- )
187
- }
188
- ```
189
-
190
- **Después:**
191
- ```javascript
192
- const AccordionSection = (props) => {
193
- const {
194
- checked, icon, title, subtitle, open = false, disabled = false,
195
- animated = true, sectionIndex, onToggle, onCheck, toolbar,
196
- info, children, ariaLabel, ...restProps
197
- } = props
198
-
199
- // Manejo de navegación por teclado
200
- const handleKeyDown = useCallback((event) => {
201
- if (disabled) return
202
-
203
- switch (event.key) {
204
- case 'Enter':
205
- case ' ':
206
- event.preventDefault()
207
- if (onToggle) onToggle()
208
- break
209
- default:
210
- break
211
- }
212
- }, [disabled, onToggle])
213
-
214
- // Manejo inteligente de clicks
215
- const handleHeaderClick = useCallback((event) => {
216
- if (disabled) return
217
-
218
- // No toggle si se hace click en elementos interactivos
219
- if (event.target.closest('.accordion-section-checker') ||
220
- event.target.closest('.accordion-section--toolbar')) {
221
- return
222
- }
223
-
224
- if (onToggle) onToggle()
225
- }, [disabled, onToggle])
226
-
227
- // Generación robusta de clases CSS
228
- const cssClasses = [
229
- 'accordion-section',
230
- open && 'open',
231
- disabled && 'disabled',
232
- animated && 'animated',
233
- checked && 'checked'
234
- ].filter(Boolean).join(' ')
235
-
236
- // IDs únicos para accesibilidad
237
- const headerId = `accordion-header-${sectionIndex}`
238
- const contentId = `accordion-content-${sectionIndex}`
239
-
240
- // Atributos de accesibilidad para header
241
- const headerAriaAttributes = {
242
- 'aria-expanded': open,
243
- 'aria-controls': contentId,
244
- 'aria-disabled': disabled,
245
- 'aria-label': ariaLabel || (typeof title === 'string' ? title : 'Accordion section'),
246
- role: 'button',
247
- tabIndex: disabled ? -1 : 0,
248
- id: headerId
249
- }
250
-
251
- // Atributos de accesibilidad para content
252
- const contentAriaAttributes = {
253
- 'aria-labelledby': headerId,
254
- 'aria-hidden': !open,
255
- role: 'region',
256
- id: contentId
257
- }
258
-
259
- return (
260
- <section className={cssClasses} {...restProps}>
261
- <header
262
- className="accordion-section-header"
263
- onClick={handleHeaderClick}
264
- onKeyDown={handleKeyDown}
265
- {...headerAriaAttributes}
266
- >
267
- {checkedIcon && (
268
- <Icon
269
- className="accordion-section-checker"
270
- icon={checkedIcon}
271
- clickable={!disabled}
272
- action={disabled ? undefined : onCheck}
273
- disabled={disabled}
274
- ariaLabel={checked ? 'Uncheck section' : 'Check section'}
275
- />
276
- )}
277
-
278
- {icon && (
279
- <Icon
280
- className="accordion-section-icon"
281
- icon={icon}
282
- ariaLabel={`${icon} icon`}
283
- />
284
- )}
285
-
286
- {title && (
287
- <div className="accordion-section--title">
288
- {title}
289
- </div>
290
- )}
291
-
292
- {subtitle && (
293
- <div className="accordion-section--subtitle">
294
- {subtitle}
295
- </div>
296
- )}
297
-
298
- {info && (
299
- <div className="accordion-section--info">
300
- {info}
301
- </div>
302
- )}
303
-
304
- {toolbar && (
305
- <div className="accordion-section--toolbar" role="toolbar">
306
- {toolbar}
307
- </div>
308
- )}
309
-
310
- <Icon
311
- className="accordion-section-toggler"
312
- icon={togglerIcon}
313
- clickable={!disabled}
314
- action={disabled ? undefined : onToggle}
315
- disabled={disabled}
316
- ariaLabel={open ? 'Collapse section' : 'Expand section'}
317
- />
318
- </header>
319
-
320
- {open && (
321
- <main
322
- className="accordion-section-content"
323
- {...contentAriaAttributes}
324
- >
325
- {children}
326
- </main>
327
- )}
328
- </section>
329
- )
330
- }
331
- ```
332
-
333
- ### 3. **PropTypes Completos**
334
-
335
- **Nuevo:**
336
- ```javascript
337
- Accordion.propTypes = {
338
- sections: PropTypes.arrayOf(PropTypes.shape({
339
- id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
340
- title: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
341
- subtitle: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
342
- icon: PropTypes.string,
343
- info: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
344
- toolbar: PropTypes.node,
345
- children: PropTypes.node,
346
- open: PropTypes.bool,
347
- checked: PropTypes.bool,
348
- disabled: PropTypes.bool
349
- })).isRequired,
350
- className: PropTypes.string,
351
- disabled: PropTypes.bool,
352
- allowMultiple: PropTypes.bool,
353
- animated: PropTypes.bool,
354
- ariaLabel: PropTypes.string,
355
- onCheck: PropTypes.func,
356
- onToggle: PropTypes.func,
357
- onSectionChange: PropTypes.func
358
- }
359
-
360
- Accordion.defaultProps = {
361
- className: '',
362
- disabled: false,
363
- allowMultiple: true,
364
- animated: true
365
- }
366
- ```
367
-
368
- ### 4. **CSS Completamente Mejorado**
369
-
370
- **Antes (Básico):**
371
- ```css
372
- .accordion {
373
- display: flex;
374
- flex-direction: column;
375
- overflow: auto;
376
- }
377
-
378
- .accordion-section>header {
379
- display: flex;
380
- align-items: center;
381
- }
382
-
383
- .accordion-section>header:hover {
384
- background-color: rgba(250,250,250,0.5);
385
- }
386
- ```
387
-
388
- **Después (Completo):**
389
- ```css
390
- /* Enhanced Accordion Styles */
391
- .accordion {
392
- display: flex;
393
- flex-direction: column;
394
- overflow: auto;
395
- transition: opacity 0.2s ease;
396
- }
397
-
398
- .accordion.disabled {
399
- opacity: 0.6;
400
- pointer-events: none;
401
- }
402
-
403
- .accordion-section {
404
- border-bottom: solid 1px var(--divider-color, #e0e0e0);
405
- transition: all 0.2s ease;
406
- }
407
-
408
- .accordion-section.checked {
409
- background-color: var(--primary-color-lighter, #e3f2fd);
410
- }
411
-
412
- .accordion-section-header {
413
- display: flex;
414
- align-items: center;
415
- padding: 1rem;
416
- cursor: pointer;
417
- transition: background-color 0.2s ease;
418
- outline: none;
419
- min-height: 3rem;
420
- }
421
-
422
- .accordion-section-header:hover {
423
- background-color: var(--hover-color, rgba(0, 0, 0, 0.04));
424
- }
425
-
426
- .accordion-section-header:focus {
427
- background-color: var(--focus-color, rgba(0, 0, 0, 0.08));
428
- outline: 2px solid var(--primary-color, #2196f3);
429
- outline-offset: -2px;
430
- }
431
-
432
- /* Animated transitions */
433
- .accordion-section.animated .accordion-section-content {
434
- transition: max-height 0.3s ease, opacity 0.2s ease, padding 0.3s ease;
435
- }
436
-
437
- .accordion-section.animated:not(.open) .accordion-section-content {
438
- max-height: 0;
439
- opacity: 0;
440
- padding-top: 0;
441
- padding-bottom: 0;
442
- }
443
-
444
- .accordion-section.animated.open .accordion-section-content {
445
- max-height: 1000px;
446
- opacity: 1;
447
- }
448
-
449
- /* Responsive, dark mode, high contrast, reduced motion support */
450
- ```
451
-
452
- ## 🧪 Pruebas Unitarias
453
-
454
- Se crearon **18 pruebas unitarias** que verifican:
455
-
456
- ### Accordion Component (13 pruebas):
457
- 1. ✅ **Exportación correcta del componente**
458
- 2. ✅ **PropTypes definidos correctamente**
459
- 3. ✅ **DefaultProps configurados**
460
- 4. ✅ **Validación de sections como array**
461
- 5. ✅ **Inicialización de estado de secciones**
462
- 6. ✅ **Lógica de toggle con allowMultiple=true**
463
- 7. ✅ **Lógica de toggle con allowMultiple=false**
464
- 8. ✅ **Lógica de check**
465
- 9. ✅ **Generación de clases CSS**
466
- 10. ✅ **Generación de atributos de accesibilidad**
467
- 11. ✅ **Generación de ID de sección**
468
- 12. ✅ **Manejo de callbacks**
469
- 13. ✅ **Estado disabled previene interacciones**
470
-
471
- ### AccordionSection Component (5 pruebas):
472
- 14. ✅ **Lógica de navegación por teclado**
473
- 15. ✅ **Lógica de click en header**
474
- 16. ✅ **Generación de clases CSS de sección**
475
- 17. ✅ **Lógica de icono checked**
476
- 18. ✅ **Lógica de icono toggler**
477
-
478
- ### Ejecutar las Pruebas
479
- ```bash
480
- npm test -- --testPathPattern=accordion.unit.test.js --watchAll=false
481
- ```
482
-
483
- **Resultado:** ✅ **18 pruebas pasaron** - Cobertura completa de funcionalidad
484
-
485
- ## 📊 Beneficios de las Mejoras
486
-
487
- ### Robustez
488
- - ✅ **Validación de props** - Advertencias para arrays inválidos
489
- - ✅ **PropTypes completos** - Previenen errores en desarrollo
490
- - ✅ **useCallback optimizado** - Mejor rendimiento
491
- - ✅ **Estados avanzados** - disabled, allowMultiple, animated
492
-
493
- ### Accesibilidad
494
- - ✅ **Atributos ARIA completos** - aria-expanded, aria-controls, aria-labelledby
495
- - ✅ **Navegación por teclado** - Enter, Space para toggle
496
- - ✅ **Focus management** - Indicadores visuales claros
497
- - ✅ **IDs únicos** - Para cada header y content
498
- - ✅ **Roles semánticos** - button, region, toolbar
499
- - ✅ **Estados anunciados** - Por lectores de pantalla
500
-
501
- ### Funcionalidad
502
- - ✅ **allowMultiple** - Control de secciones múltiples abiertas
503
- - ✅ **animated** - Transiciones suaves opcionales
504
- - ✅ **disabled** - Estado global y por sección
505
- - ✅ **Callbacks mejorados** - onToggle, onSectionChange adicionales
506
- - ✅ **Keys mejorados** - Usa section.id en lugar de index
507
-
508
- ### CSS y UX
509
- - ✅ **Animaciones suaves** - Transiciones CSS para expand/collapse
510
- - ✅ **Estados visuales** - hover, focus, disabled, checked
511
- - ✅ **Responsive design** - Adaptación a móviles
512
- - ✅ **Dark mode** - Soporte automático
513
- - ✅ **High contrast** - Accesibilidad visual
514
- - ✅ **Reduced motion** - Respeta preferencias del usuario
515
-
516
- ## 🚀 Casos de Uso Mejorados
517
-
518
- ### Antes (Accordion original):
519
- ```javascript
520
- <Accordion
521
- sections={sections}
522
- onCheck={handleCheck}
523
- />
524
- // ❌ Sin accesibilidad, sin estados avanzados, sin animaciones
525
- ```
526
-
527
- ### Después (Accordion mejorado):
528
- ```javascript
529
- <Accordion
530
- sections={sections}
531
- disabled={isLoading}
532
- allowMultiple={false}
533
- animated={true}
534
- ariaLabel="Configuration accordion"
535
- onCheck={handleCheck}
536
- onToggle={handleToggle}
537
- onSectionChange={handleSectionChange}
538
- />
539
- // ✅ Completo, accesible, con estados avanzados y animaciones
540
- ```
541
-
542
- ## 📁 Archivos Creados/Modificados
543
-
544
- 1. **`src/html/accordion.js`** - Componente mejorado con todas las características
545
- 2. **`src/html/accordion.css`** - CSS completo con animaciones y estados
546
- 3. **`src/html/accordion.unit.test.js`** - 18 pruebas unitarias completas
547
- 4. **`src/html/accordion.example.js`** - Ejemplos exhaustivos con comparación
548
- 5. **`ACCORDION_EVALUATION.md`** - Esta documentación completa
549
-
550
- ## 📈 Impacto
551
-
552
- ### Antes de las Mejoras (Accordion original):
553
- - ❌ Sin PropTypes ni validación
554
- - ❌ Sin accesibilidad
555
- - ❌ Key usando index (problemas de renderizado)
556
- - ❌ Concatenación de strings frágil
557
- - ❌ Sin estados avanzados
558
- - ❌ Funciones no optimizadas
559
- - ❌ CSS básico sin animaciones
560
- - ❌ Renderizado condicional con strings
561
-
562
- ### Después de las Mejoras (Accordion mejorado):
563
- - ✅ PropTypes completos y validación robusta
564
- - ✅ Completamente accesible (WCAG 2.1 AA)
565
- - ✅ Keys usando section.id (renderizado estable)
566
- - ✅ Generación robusta de clases
567
- - ✅ Estados disabled, allowMultiple, animated
568
- - ✅ useCallback optimizado
569
- - ✅ CSS con animaciones y estados completos
570
- - ✅ Renderizado condicional correcto
571
-
572
- ## ✅ Conclusión
573
-
574
- La evaluación y mejora del componente Accordion ha resultado en un componente que:
575
-
576
- - **Mantiene compatibilidad** - Todas las props originales funcionan igual
577
- - **Agrega robustez** - PropTypes, validación, optimización
578
- - **Mejora accesibilidad** - WCAG 2.1 AA compliant
579
- - **Corrige problemas** - Keys, concatenación, renderizado
580
- - **Añade características** - Estados avanzados, animaciones, callbacks
581
- - **Mejora UX** - Transiciones suaves, estados visuales claros
582
-
583
- El Accordion mejorado está listo para uso en producción como reemplazo directo que mantiene toda la funcionalidad existente mientras proporciona todas las mejoras modernas necesarias.