ywana-core8 0.1.103 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/dist/index.css +4941 -324
  2. package/dist/index.js +42339 -0
  3. package/dist/index.js.map +1 -0
  4. package/dist/index.modern.js +37459 -31678
  5. package/dist/index.modern.js.map +1 -1
  6. package/dist/index.umd.js +39635 -34010
  7. package/dist/index.umd.js.map +1 -1
  8. package/package.json +26 -29
  9. package/src/Test.stories.jsx +28 -0
  10. package/src/desktop/Desktop.stories.jsx +110 -0
  11. package/src/desktop/WindowContext.js +135 -0
  12. package/src/desktop/WindowManager.js +355 -0
  13. package/src/desktop/desktop.css +55 -4
  14. package/src/desktop/desktop.js +312 -6
  15. package/src/desktop/index.js +7 -0
  16. package/src/desktop/window.css +229 -36
  17. package/src/desktop/window.js +255 -20
  18. package/src/desktop.backup/desktop.css +6 -0
  19. package/src/desktop.backup/desktop.js +13 -0
  20. package/src/desktop.backup/window.css +58 -0
  21. package/src/desktop.backup/window.js +27 -0
  22. package/src/html/Accordion.stories.jsx +178 -0
  23. package/src/html/Button.stories.jsx +175 -0
  24. package/src/html/Checkbox.stories.jsx +131 -0
  25. package/src/html/Chip.stories.jsx +189 -0
  26. package/src/html/Color.stories.jsx +234 -0
  27. package/src/html/Form.stories.jsx +271 -0
  28. package/src/html/Icon.stories.jsx +233 -0
  29. package/src/html/Progress.stories.jsx +247 -0
  30. package/src/html/Radio.stories.jsx +289 -0
  31. package/src/html/StyleTest.stories.jsx +81 -0
  32. package/src/html/Switch.stories.jsx +329 -0
  33. package/src/html/Tab.stories.jsx +239 -0
  34. package/src/html/Table.stories.jsx +188 -0
  35. package/src/html/Table2.stories.jsx +238 -0
  36. package/src/html/TextField2.stories.jsx +337 -0
  37. package/src/html/Tree.stories.jsx +285 -0
  38. package/src/html/accordion.example.js +0 -74
  39. package/src/html/accordion.js +1 -6
  40. package/src/html/button.js +2 -13
  41. package/src/html/checkbox.js +1 -9
  42. package/src/html/chip.js +2 -19
  43. package/src/html/color.js +1 -14
  44. package/src/html/form.js +4 -15
  45. package/src/html/header2.js +1 -12
  46. package/src/html/icon.js +1 -7
  47. package/src/html/index.js +1 -1
  48. package/src/html/list.js +1 -19
  49. package/src/html/menu.js +9 -5
  50. package/src/html/progress.js +5 -53
  51. package/src/html/property.js +9 -25
  52. package/src/html/radio.js +2 -16
  53. package/src/html/section.js +1 -6
  54. package/src/html/selector.js +2 -19
  55. package/src/html/switch.css +134 -100
  56. package/src/html/switch.example.js +46 -36
  57. package/src/html/switch.js +43 -192
  58. package/src/html/tab.js +3 -24
  59. package/src/html/text.js +1 -12
  60. package/src/html/textfield2.js +5 -42
  61. package/src/html/thumbnail.js +1 -12
  62. package/src/html/tokenfield.js +2 -21
  63. package/src/html/tree.js +3 -35
  64. package/src/index.js +1 -0
  65. package/__previewjs__/Wrapper.tsx +0 -14
  66. package/build-doc.sh +0 -10
  67. package/db/db.json +0 -89
  68. package/db/routes.json +0 -0
  69. package/dist/index.cjs +0 -36722
  70. package/dist/index.cjs.map +0 -1
  71. package/dist/index.css.map +0 -1
  72. package/doc/README.md +0 -196
  73. package/doc/evalulations/ACCORDION_EVALUATION.md +0 -583
  74. package/doc/evalulations/CHECKBOX_EVALUATION.md +0 -273
  75. package/doc/evalulations/CHIP_EVALUATION.md +0 -542
  76. package/doc/evalulations/COLOR_EVALUATION.md +0 -524
  77. package/doc/evalulations/COMPONENTS_EVALUATION.md +0 -477
  78. package/doc/evalulations/FORM_EVALUATION.md +0 -459
  79. package/doc/evalulations/HEADER_EVALUATION.md +0 -436
  80. package/doc/evalulations/ICON_EVALUATION.md +0 -254
  81. package/doc/evalulations/LIST_EVALUATION.md +0 -574
  82. package/doc/evalulations/PROGRESS_EVALUATION.md +0 -450
  83. package/doc/evalulations/RADIO_EVALUATION.md +0 -439
  84. package/doc/evalulations/RADIO_VISUAL_FIX.md +0 -183
  85. package/doc/evalulations/SECTION_IMPROVEMENTS.md +0 -153
  86. package/doc/evalulations/SWITCH_EVALUATION.md +0 -335
  87. package/doc/evalulations/SWITCH_VISUAL_FIX.md +0 -232
  88. package/doc/evalulations/TAB_EVALUATION.md +0 -626
  89. package/doc/evalulations/TEXTFIELD_EVALUATION.md +0 -747
  90. package/doc/evalulations/TOOLTIP_FIX.md +0 -157
  91. package/doc/evalulations/TREE_EVALUATION.md +0 -708
  92. package/doc/index.html +0 -0
  93. package/doc/package-lock.json +0 -17298
  94. package/doc/package.json +0 -34
  95. package/doc/public/index.html +0 -24
  96. package/doc/scripts/generate-examples.js +0 -129
  97. package/doc/src/App.css +0 -171
  98. package/doc/src/App.js +0 -114
  99. package/doc/src/components/ExamplePage.js +0 -129
  100. package/doc/src/components/WelcomePage.js +0 -84
  101. package/doc/src/index.css +0 -246
  102. package/doc/src/index.js +0 -17
  103. package/doc/src/theme.css +0 -256
  104. package/jest.config.js +0 -24
  105. package/preview.config.js +0 -38
  106. package/publish.sh +0 -6
  107. package/src/desktop/dektop.test.js +0 -11
  108. package/src/domain/CollectionAPI.test.js +0 -19
  109. package/src/domain/ContentEditor.test.js +0 -52
  110. package/src/domain2/CollectionAPI.test.js +0 -19
  111. package/src/domain2/CollectionContext.test.js +0 -71
  112. package/src/domain2/CollectionPage.test.js +0 -112
  113. package/src/domain2/DynamicForm.test.js +0 -47
  114. package/src/html/accordion.test.js +0 -37
  115. package/src/html/accordion.unit.test.js +0 -334
  116. package/src/html/button.example.new.js +0 -416
  117. package/src/html/button.test.js +0 -422
  118. package/src/html/checkbox.test.js +0 -285
  119. package/src/html/chip.test.js +0 -425
  120. package/src/html/color.example.js.backup +0 -527
  121. package/src/html/color.test.js +0 -377
  122. package/src/html/components.example.js.backup +0 -492
  123. package/src/html/components_enhanced.test.js +0 -581
  124. package/src/html/form.example.js.backup +0 -385
  125. package/src/html/form.test.js +0 -369
  126. package/src/html/header2.example.js.backup +0 -411
  127. package/src/html/header2.test.js +0 -377
  128. package/src/html/icon.example.js.backup +0 -268
  129. package/src/html/icon.test.js +0 -231
  130. package/src/html/label.test.js +0 -0
  131. package/src/html/list.example.js.backup +0 -404
  132. package/src/html/list.test.js +0 -383
  133. package/src/html/progress.example.js.backup +0 -424
  134. package/src/html/progress.test.js +0 -313
  135. package/src/html/property.example.js.backup +0 -553
  136. package/src/html/property.test.js +0 -371
  137. package/src/html/radio.example.js.backup +0 -389
  138. package/src/html/radio.test.js +0 -318
  139. package/src/html/section.example.js.backup +0 -99
  140. package/src/html/section.test.js +0 -131
  141. package/src/html/selector.test.js +0 -20
  142. package/src/html/switch.example.js.backup +0 -461
  143. package/src/html/switch.test.js +0 -355
  144. package/src/html/tab.example.js.backup +0 -446
  145. package/src/html/tab.test.js +0 -25
  146. package/src/html/tab_enhanced.test.js +0 -504
  147. package/src/html/table.test.js +0 -70
  148. package/src/html/table2.test.js +0 -582
  149. package/src/html/text.test.js +0 -15
  150. package/src/html/textfield.test.js +0 -51
  151. package/src/html/textfield2.example.js.backup +0 -1370
  152. package/src/html/textfield2.test.js +0 -950
  153. package/src/html/tokenfield.example.js.backup +0 -503
  154. package/src/html/tokenfield.test.js +0 -423
  155. package/src/html/tree.example.js.backup +0 -475
  156. package/src/html/tree.test.js +0 -43
  157. package/src/html/tree_enhanced.test.js +0 -495
  158. package/src/http/token.test.js +0 -50
  159. package/src/incubator/pdfViewer.js +0 -33
  160. package/src/incubator/wizard.test.js +0 -127
  161. package/src/site/site.test.js +0 -230
  162. package/src/site/view.test.js +0 -41
  163. package/src/widgets/calendar/Calendar.test.js +0 -28
  164. package/src/widgets/explorer/Explorer.test.js +0 -121
  165. package/src/widgets/ide/editor.test.js +0 -33
  166. package/src/widgets/kanban/Kanban.test.js +0 -78
  167. package/src/widgets/login/LoginBox.test.js +0 -12
  168. package/src/widgets/login/ResetPasswordBox.test.js +0 -34
  169. package/src/widgets/login/validations.test.js +0 -51
  170. package/src/widgets/planner/Planner.test.js +0 -60
  171. package/src/widgets/upload/Upload.test.js +0 -32
  172. package/table2.test.js +0 -454
@@ -1,231 +0,0 @@
1
- import React from 'react'
2
- import { Icon } from './icon'
3
-
4
- // Pruebas unitarias para el componente Icon
5
- describe('Icon Component', () => {
6
- // Mock del componente Tooltip
7
- const mockTooltip = jest.fn()
8
-
9
- beforeEach(() => {
10
- jest.clearAllMocks()
11
-
12
- // Mock del componente Tooltip
13
- jest.doMock('./tooltip', () => ({
14
- Tooltip: mockTooltip
15
- }))
16
-
17
- // Mock de console.warn para las pruebas
18
- jest.spyOn(console, 'warn').mockImplementation(() => {})
19
- })
20
-
21
- afterEach(() => {
22
- console.warn.mockRestore()
23
- })
24
-
25
- test('component exports correctly', () => {
26
- expect(Icon).toBeDefined()
27
- expect(typeof Icon).toBe('function')
28
- })
29
-
30
- test('component has correct PropTypes', () => {
31
- expect(Icon.propTypes).toBeDefined()
32
- expect(Icon.propTypes.id).toBeDefined()
33
- expect(Icon.propTypes.icon).toBeDefined()
34
- expect(Icon.propTypes.size).toBeDefined()
35
- expect(Icon.propTypes.tooltip).toBeDefined()
36
- expect(Icon.propTypes.clickable).toBeDefined()
37
- expect(Icon.propTypes.disabled).toBeDefined()
38
- expect(Icon.propTypes.action).toBeDefined()
39
- expect(Icon.propTypes.eventPropagation).toBeDefined()
40
- expect(Icon.propTypes.className).toBeDefined()
41
- expect(Icon.propTypes.ariaLabel).toBeDefined()
42
- })
43
-
44
- test('component has correct defaultProps', () => {
45
- expect(Icon.defaultProps).toBeDefined()
46
- expect(Icon.defaultProps.size).toBe('normal')
47
- expect(Icon.defaultProps.clickable).toBe(false)
48
- expect(Icon.defaultProps.disabled).toBe(false)
49
- expect(Icon.defaultProps.eventPropagation).toBe(false)
50
- expect(Icon.defaultProps.className).toBe('')
51
- })
52
-
53
- test('returns null and warns when icon prop is missing', () => {
54
- const result = Icon({})
55
-
56
- expect(result).toBeNull()
57
- expect(console.warn).toHaveBeenCalledWith('Icon component: icon prop is required')
58
- })
59
-
60
- test('handles className safely', () => {
61
- // Simular el manejo seguro de className
62
- const testClassName = (className) => {
63
- const safeClassName = className || ''
64
- return `icon normal ${safeClassName} material-icons`
65
- }
66
-
67
- expect(testClassName('custom-class')).toBe('icon normal custom-class material-icons')
68
- expect(testClassName(undefined)).toBe('icon normal material-icons')
69
- expect(testClassName('')).toBe('icon normal material-icons')
70
- expect(testClassName(null)).toBe('icon normal material-icons')
71
- })
72
-
73
- test('generates correct CSS classes for different states', () => {
74
- // Simular la lógica de generación de clases
75
- const generateClasses = (size, disabled, clickable, className) => {
76
- const style = disabled ? "disabled" : clickable ? "clickable" : ""
77
- const safeClassName = className || ''
78
- return `icon ${size} ${style} ${safeClassName} material-icons`
79
- }
80
-
81
- expect(generateClasses('normal', false, false, '')).toBe('icon normal material-icons')
82
- expect(generateClasses('small', false, true, '')).toBe('icon small clickable material-icons')
83
- expect(generateClasses('large', true, false, '')).toBe('icon large disabled material-icons')
84
- expect(generateClasses('normal', false, true, 'custom')).toBe('icon normal clickable custom material-icons')
85
- })
86
-
87
- test('generates correct accessibility attributes', () => {
88
- // Simular la lógica de atributos de accesibilidad
89
- const generateAriaAttributes = (clickable, disabled, icon, ariaLabel) => {
90
- return {
91
- role: clickable ? 'button' : 'img',
92
- 'aria-label': ariaLabel || (clickable ? `${icon} button` : icon),
93
- 'aria-disabled': disabled,
94
- tabIndex: clickable && !disabled ? 0 : -1
95
- }
96
- }
97
-
98
- // Icono no clickable
99
- const nonClickable = generateAriaAttributes(false, false, 'home', null)
100
- expect(nonClickable.role).toBe('img')
101
- expect(nonClickable['aria-label']).toBe('home')
102
- expect(nonClickable.tabIndex).toBe(-1)
103
-
104
- // Icono clickable
105
- const clickable = generateAriaAttributes(true, false, 'settings', null)
106
- expect(clickable.role).toBe('button')
107
- expect(clickable['aria-label']).toBe('settings button')
108
- expect(clickable.tabIndex).toBe(0)
109
-
110
- // Icono clickable pero disabled
111
- const disabled = generateAriaAttributes(true, true, 'delete', null)
112
- expect(disabled.role).toBe('button')
113
- expect(disabled['aria-disabled']).toBe(true)
114
- expect(disabled.tabIndex).toBe(-1)
115
-
116
- // Con aria-label personalizado
117
- const customLabel = generateAriaAttributes(true, false, 'star', 'Favorito')
118
- expect(customLabel['aria-label']).toBe('Favorito')
119
- })
120
-
121
- test('click handler works correctly', () => {
122
- const mockAction = jest.fn()
123
-
124
- // Simular el comportamiento del click handler
125
- const simulateClick = (eventPropagation, disabled, action) => {
126
- const event = {
127
- stopPropagation: jest.fn(),
128
- preventDefault: jest.fn()
129
- }
130
-
131
- // Lógica del click handler
132
- if (!eventPropagation) {
133
- event.stopPropagation()
134
- event.preventDefault()
135
- }
136
- if (action && !disabled) action(event)
137
-
138
- return event
139
- }
140
-
141
- // Click normal
142
- const event1 = simulateClick(false, false, mockAction)
143
- expect(event1.stopPropagation).toHaveBeenCalled()
144
- expect(event1.preventDefault).toHaveBeenCalled()
145
- expect(mockAction).toHaveBeenCalledWith(event1)
146
-
147
- mockAction.mockClear()
148
-
149
- // Click con disabled
150
- const event2 = simulateClick(false, true, mockAction)
151
- expect(mockAction).not.toHaveBeenCalled()
152
-
153
- // Click con event propagation
154
- const event3 = simulateClick(true, false, mockAction)
155
- expect(event3.stopPropagation).not.toHaveBeenCalled()
156
- expect(event3.preventDefault).not.toHaveBeenCalled()
157
- expect(mockAction).toHaveBeenCalledWith(event3)
158
- })
159
-
160
- test('keyboard event handling works correctly', () => {
161
- const mockAction = jest.fn()
162
-
163
- // Simular el manejo de eventos de teclado
164
- const simulateKeyDown = (key, clickable, disabled, action) => {
165
- const event = {
166
- key,
167
- preventDefault: jest.fn()
168
- }
169
-
170
- // Lógica del keyboard handler
171
- if (clickable && !disabled && (event.key === 'Enter' || event.key === ' ')) {
172
- event.preventDefault()
173
- // Simular llamada a click
174
- if (action) action(event)
175
- }
176
-
177
- return event
178
- }
179
-
180
- // Enter key
181
- const enterEvent = simulateKeyDown('Enter', true, false, mockAction)
182
- expect(enterEvent.preventDefault).toHaveBeenCalled()
183
- expect(mockAction).toHaveBeenCalledWith(enterEvent)
184
-
185
- mockAction.mockClear()
186
-
187
- // Space key
188
- const spaceEvent = simulateKeyDown(' ', true, false, mockAction)
189
- expect(spaceEvent.preventDefault).toHaveBeenCalled()
190
- expect(mockAction).toHaveBeenCalledWith(spaceEvent)
191
-
192
- mockAction.mockClear()
193
-
194
- // Other key (should not trigger)
195
- const otherEvent = simulateKeyDown('a', true, false, mockAction)
196
- expect(otherEvent.preventDefault).not.toHaveBeenCalled()
197
- expect(mockAction).not.toHaveBeenCalled()
198
-
199
- // Disabled icon (should not trigger)
200
- const disabledEvent = simulateKeyDown('Enter', true, true, mockAction)
201
- expect(disabledEvent.preventDefault).not.toHaveBeenCalled()
202
- expect(mockAction).not.toHaveBeenCalled()
203
- })
204
-
205
- test('size variants are handled correctly', () => {
206
- const validSizes = ['small', 'normal', 'large']
207
-
208
- validSizes.forEach(size => {
209
- const classes = `icon ${size} material-icons`
210
- expect(classes).toContain(size)
211
- })
212
- })
213
-
214
- test('tooltip integration works correctly', () => {
215
- // Verificar que el componente puede manejar tooltips
216
- const tooltipConfig = {
217
- text: 'Test tooltip',
218
- top: '-2rem',
219
- left: '-1rem'
220
- }
221
-
222
- // Simular la lógica de tooltip
223
- const hasTooltip = !!tooltipConfig
224
- expect(hasTooltip).toBe(true)
225
-
226
- // Verificar que la configuración es válida
227
- expect(tooltipConfig.text).toBe('Test tooltip')
228
- expect(tooltipConfig.top).toBe('-2rem')
229
- expect(tooltipConfig.left).toBe('-1rem')
230
- })
231
- })
File without changes
@@ -1,404 +0,0 @@
1
- import React, { useState } from 'react'
2
- import { List } from './list'
3
- import { Button } from './button'
4
- import { Icon } from './icon'
5
-
6
- /**
7
- * Ejemplos del componente List mejorado manteniendo 100% compatibilidad
8
- */
9
- export const ListExamples = () => {
10
- const [selectedItem, setSelectedItem] = useState(null)
11
- const [selectedItems, setSelectedItems] = useState([])
12
- const [isLoading, setIsLoading] = useState(false)
13
- const [showEmpty, setShowEmpty] = useState(false)
14
-
15
- // Datos de ejemplo
16
- const basicItems = [
17
- {
18
- id: 1,
19
- line1: 'John Doe',
20
- line2: 'Software Engineer',
21
- icon: 'person',
22
- meta: 'Active',
23
- badge: 'New'
24
- },
25
- {
26
- id: 2,
27
- line1: 'Jane Smith',
28
- line2: 'Product Manager',
29
- icon: 'business_center',
30
- meta: '2 days ago',
31
- avatar: 'https://via.placeholder.com/40x40/2196f3/ffffff?text=JS'
32
- },
33
- {
34
- id: 3,
35
- line1: 'Mike Johnson',
36
- line2: 'UX Designer',
37
- icon: 'design_services',
38
- meta: 'Offline',
39
- actions: (
40
- <div style={{ display: 'flex', gap: '0.25rem' }}>
41
- <Button icon="edit" size="small" />
42
- <Button icon="delete" size="small" />
43
- </div>
44
- )
45
- },
46
- {
47
- id: 4,
48
- line1: 'Sarah Wilson',
49
- line2: 'Data Scientist',
50
- icon: 'analytics',
51
- meta: 'Online',
52
- disabled: true
53
- }
54
- ]
55
-
56
- const groupedItems = [
57
- { id: 1, line1: 'Apple iPhone 14', line2: '$999', category: 'Electronics', icon: 'phone_iphone' },
58
- { id: 2, line1: 'Samsung Galaxy S23', line2: '$899', category: 'Electronics', icon: 'smartphone' },
59
- { id: 3, line1: 'Nike Air Max', line2: '$120', category: 'Clothing', icon: 'sports_soccer' },
60
- { id: 4, line1: 'Adidas Ultraboost', line2: '$180', category: 'Clothing', icon: 'directions_run' },
61
- { id: 5, line1: 'MacBook Pro', line2: '$2499', category: 'Electronics', icon: 'laptop_mac' },
62
- { id: 6, line1: 'Levi\'s Jeans', line2: '$80', category: 'Clothing', icon: 'checkroom' }
63
- ]
64
-
65
- const handleSelect = (id) => {
66
- setSelectedItem(id)
67
- console.log('Selected:', id)
68
- }
69
-
70
- const handleMultiSelect = (ids) => {
71
- setSelectedItems(ids)
72
- console.log('Multi-selected:', ids)
73
- }
74
-
75
- const handleSort = (sortConfig) => {
76
- console.log('Sort config:', sortConfig)
77
- }
78
-
79
- const simulateLoading = () => {
80
- setIsLoading(true)
81
- setTimeout(() => setIsLoading(false), 2000)
82
- }
83
-
84
- return (
85
- <div style={{ padding: '2rem', maxWidth: '1200px', maxHeight: '100vh', overflow: 'auto' }}>
86
- <h1>Componente List Mejorado</h1>
87
-
88
- <div style={{
89
- background: '#f8f9fa',
90
- padding: '1rem',
91
- borderRadius: '8px',
92
- marginBottom: '2rem',
93
- border: '1px solid #e9ecef'
94
- }}>
95
- <h3>✅ Mejoras Implementadas (100% Compatibilidad):</h3>
96
- <ul>
97
- <li>🛡️ <strong>PropTypes completos</strong> - Validación y documentación detallada</li>
98
- <li>♿ <strong>Accesibilidad completa</strong> - ARIA, navegación por teclado, focus management</li>
99
- <li>🔍 <strong>Búsqueda integrada</strong> - Filtrado en tiempo real por múltiples campos</li>
100
- <li>📊 <strong>Ordenamiento</strong> - Sorting ascendente/descendente por cualquier campo</li>
101
- <li>✅ <strong>Selección múltiple</strong> - Con Ctrl+click y estados visuales</li>
102
- <li>🎭 <strong>Estados avanzados</strong> - loading, empty, disabled, dense</li>
103
- <li>👤 <strong>Avatares y badges</strong> - Soporte para imágenes y etiquetas</li>
104
- <li>⚡ <strong>Acciones por item</strong> - Botones que aparecen en hover</li>
105
- <li>📱 <strong>Responsive total</strong> - Adaptación móvil, dark mode, high contrast</li>
106
- <li>🧪 <strong>16 Pruebas unitarias</strong> - Verifican compatibilidad y funcionalidad</li>
107
- </ul>
108
- </div>
109
-
110
- {/* Controles de demostración */}
111
- <section style={{ marginBottom: '2rem' }}>
112
- <h3>Controles de Demostración</h3>
113
- <div style={{
114
- background: '#fff',
115
- padding: '1rem',
116
- borderRadius: '8px',
117
- border: '1px solid #ddd',
118
- display: 'flex',
119
- gap: '1rem',
120
- alignItems: 'center',
121
- flexWrap: 'wrap'
122
- }}>
123
- <Button
124
- label="Simulate Loading"
125
- icon="refresh"
126
- action={simulateLoading}
127
- disabled={isLoading}
128
- />
129
- <Button
130
- label={showEmpty ? "Show Items" : "Show Empty"}
131
- icon={showEmpty ? "list" : "inbox"}
132
- action={() => setShowEmpty(!showEmpty)}
133
- />
134
- <Button
135
- label="Clear Selection"
136
- icon="clear"
137
- action={() => {
138
- setSelectedItem(null)
139
- setSelectedItems([])
140
- }}
141
- />
142
- <span style={{ marginLeft: 'auto', color: '#666' }}>
143
- Selected: {selectedItem || 'None'} | Multi: [{selectedItems.join(', ')}]
144
- </span>
145
- </div>
146
- </section>
147
-
148
- {/* Lista básica (compatible con versión original) */}
149
- <section style={{ marginBottom: '2rem' }}>
150
- <h3>Lista Básica (100% Compatible)</h3>
151
- <div style={{
152
- background: '#fff',
153
- border: '1px solid #ddd',
154
- borderRadius: '8px',
155
- overflow: 'hidden'
156
- }}>
157
- <List
158
- items={basicItems}
159
- selected={selectedItem}
160
- onSelect={handleSelect}
161
- />
162
- </div>
163
- </section>
164
-
165
- {/* Lista con búsqueda */}
166
- <section style={{ marginBottom: '2rem' }}>
167
- <h3>Lista con Búsqueda Integrada</h3>
168
- <div style={{
169
- background: '#fff',
170
- border: '1px solid #ddd',
171
- borderRadius: '8px',
172
- overflow: 'hidden'
173
- }}>
174
- <List
175
- items={basicItems}
176
- selected={selectedItem}
177
- onSelect={handleSelect}
178
- searchable={true}
179
- searchPlaceholder="Buscar personas..."
180
- searchBy={['line1', 'line2']}
181
- ariaLabel="Lista de personas con búsqueda"
182
- />
183
- </div>
184
- </section>
185
-
186
- {/* Lista con ordenamiento */}
187
- <section style={{ marginBottom: '2rem' }}>
188
- <h3>Lista con Ordenamiento</h3>
189
- <div style={{
190
- background: '#fff',
191
- border: '1px solid #ddd',
192
- borderRadius: '8px',
193
- overflow: 'hidden'
194
- }}>
195
- <List
196
- items={basicItems}
197
- selected={selectedItem}
198
- onSelect={handleSelect}
199
- sortable={true}
200
- sortBy="line1"
201
- onSort={handleSort}
202
- ariaLabel="Lista ordenable de personas"
203
- />
204
- </div>
205
- </section>
206
-
207
- {/* Lista con selección múltiple */}
208
- <section style={{ marginBottom: '2rem' }}>
209
- <h3>Lista con Selección Múltiple</h3>
210
- <div style={{
211
- background: '#fff',
212
- border: '1px solid #ddd',
213
- borderRadius: '8px',
214
- overflow: 'hidden'
215
- }}>
216
- <List
217
- items={basicItems}
218
- selected={selectedItems}
219
- onSelect={handleSelect}
220
- multiSelect={true}
221
- onMultiSelect={handleMultiSelect}
222
- ariaLabel="Lista con selección múltiple"
223
- />
224
- </div>
225
- </section>
226
-
227
- {/* Lista agrupada (compatible con versión original) */}
228
- <section style={{ marginBottom: '2rem' }}>
229
- <h3>Lista Agrupada (100% Compatible)</h3>
230
- <div style={{
231
- background: '#fff',
232
- border: '1px solid #ddd',
233
- borderRadius: '8px',
234
- overflow: 'hidden'
235
- }}>
236
- <List
237
- items={groupedItems}
238
- selected={selectedItem}
239
- onSelect={handleSelect}
240
- groupBy="category"
241
- searchable={true}
242
- searchPlaceholder="Buscar productos..."
243
- />
244
- </div>
245
- </section>
246
-
247
- {/* Lista densa */}
248
- <section style={{ marginBottom: '2rem' }}>
249
- <h3>Lista Densa</h3>
250
- <div style={{
251
- background: '#fff',
252
- border: '1px solid #ddd',
253
- borderRadius: '8px',
254
- overflow: 'hidden'
255
- }}>
256
- <List
257
- items={basicItems}
258
- selected={selectedItem}
259
- onSelect={handleSelect}
260
- dense={true}
261
- ariaLabel="Lista densa"
262
- />
263
- </div>
264
- </section>
265
-
266
- {/* Estados especiales */}
267
- <section style={{ marginBottom: '2rem' }}>
268
- <h3>Estados Especiales</h3>
269
- <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '1rem' }}>
270
- <div style={{
271
- background: '#fff',
272
- border: '1px solid #ddd',
273
- borderRadius: '8px',
274
- overflow: 'hidden'
275
- }}>
276
- <h4 style={{ margin: '1rem', marginBottom: '0' }}>Loading State</h4>
277
- <List
278
- items={basicItems}
279
- loading={isLoading}
280
- ariaLabel="Lista en estado de carga"
281
- />
282
- </div>
283
-
284
- <div style={{
285
- background: '#fff',
286
- border: '1px solid #ddd',
287
- borderRadius: '8px',
288
- overflow: 'hidden'
289
- }}>
290
- <h4 style={{ margin: '1rem', marginBottom: '0' }}>Empty State</h4>
291
- <List
292
- items={showEmpty ? [] : basicItems}
293
- empty={showEmpty}
294
- emptyMessage="No hay elementos para mostrar"
295
- emptyIcon="inbox"
296
- searchable={true}
297
- ariaLabel="Lista vacía"
298
- />
299
- </div>
300
- </div>
301
- </section>
302
-
303
- {/* Lista completa con todas las características */}
304
- <section style={{ marginBottom: '2rem' }}>
305
- <h3>Lista Completa (Todas las Características)</h3>
306
- <div style={{
307
- background: '#fff',
308
- border: '1px solid #ddd',
309
- borderRadius: '8px',
310
- overflow: 'hidden'
311
- }}>
312
- <List
313
- items={basicItems}
314
- selected={selectedItems}
315
- onSelect={handleSelect}
316
- multiSelect={true}
317
- onMultiSelect={handleMultiSelect}
318
- searchable={true}
319
- searchPlaceholder="Buscar en la lista completa..."
320
- searchBy={['line1', 'line2', 'meta']}
321
- sortable={true}
322
- sortBy="line1"
323
- onSort={handleSort}
324
- animated={true}
325
- maxHeight="300px"
326
- ariaLabel="Lista completa con todas las características"
327
- />
328
- </div>
329
- </section>
330
-
331
- {/* Comparación antes/después */}
332
- <section style={{ marginBottom: '2rem' }}>
333
- <h3>Comparación: List Original vs Mejorado</h3>
334
- <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '1rem' }}>
335
- <div style={{
336
- background: '#ffebee',
337
- padding: '1rem',
338
- borderRadius: '4px',
339
- border: '1px solid #ffcdd2'
340
- }}>
341
- <h4>❌ List Original</h4>
342
- <ul>
343
- <li>Sin PropTypes ni validación</li>
344
- <li>Sin accesibilidad</li>
345
- <li>Sin búsqueda integrada</li>
346
- <li>Sin ordenamiento</li>
347
- <li>Selección múltiple básica</li>
348
- <li>Sin estados loading/empty</li>
349
- <li>CSS básico sin responsive</li>
350
- <li>Sin avatares ni badges</li>
351
- <li>Sin acciones por item</li>
352
- </ul>
353
- </div>
354
- <div style={{
355
- background: '#e8f5e8',
356
- padding: '1rem',
357
- borderRadius: '4px',
358
- border: '1px solid #c8e6c9'
359
- }}>
360
- <h4>✅ List Mejorado</h4>
361
- <ul>
362
- <li>PropTypes completos</li>
363
- <li>Accesibilidad total (WCAG 2.1 AA)</li>
364
- <li>Búsqueda en tiempo real</li>
365
- <li>Ordenamiento ascendente/descendente</li>
366
- <li>Selección múltiple avanzada</li>
367
- <li>Estados loading, empty, disabled</li>
368
- <li>CSS responsive con dark mode</li>
369
- <li>Avatares, badges y meta</li>
370
- <li>Acciones que aparecen en hover</li>
371
- </ul>
372
- </div>
373
- </div>
374
- </section>
375
-
376
- {/* Garantía de compatibilidad */}
377
- <section style={{ marginBottom: '2rem' }}>
378
- <h3>🔒 Garantía de Compatibilidad</h3>
379
- <div style={{
380
- background: '#fff3cd',
381
- padding: '1rem',
382
- borderRadius: '4px',
383
- border: '1px solid #ffeaa7'
384
- }}>
385
- <p><strong>100% Compatible con Código Existente:</strong></p>
386
- <ul>
387
- <li>✅ Todas las props originales funcionan exactamente igual</li>
388
- <li>✅ Comportamiento de selección idéntico</li>
389
- <li>✅ Agrupación funciona sin cambios</li>
390
- <li>✅ CSS original preservado</li>
391
- <li>✅ Nuevas características son opcionales</li>
392
- <li>✅ No se rompe ningún código existente</li>
393
- </ul>
394
- <p style={{ marginTop: '1rem', fontSize: '0.9rem', color: '#856404' }}>
395
- <strong>Migración:</strong> Simplemente reemplaza el import y todas las
396
- mejoras se aplican automáticamente sin cambiar una línea de código existente.
397
- </p>
398
- </div>
399
- </section>
400
- </div>
401
- )
402
- }
403
-
404
- export default ListExamples