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,377 +0,0 @@
1
- import React from 'react'
2
- import { Header2 } from './header2'
3
-
4
- // Pruebas unitarias para el componente Header2
5
- describe('Header2 Component', () => {
6
- // Mock de los componentes dependientes
7
- const mockText = jest.fn()
8
- const mockIcon = jest.fn()
9
-
10
- beforeEach(() => {
11
- jest.clearAllMocks()
12
-
13
- // Mock del componente Text
14
- jest.doMock('./text', () => ({
15
- Text: mockText
16
- }))
17
-
18
- // Mock del componente Icon
19
- jest.doMock('./icon', () => ({
20
- Icon: mockIcon
21
- }))
22
-
23
- // Mock de console.warn para las pruebas
24
- jest.spyOn(console, 'warn').mockImplementation(() => {})
25
- })
26
-
27
- afterEach(() => {
28
- console.warn.mockRestore()
29
- })
30
-
31
- test('component exports correctly', () => {
32
- expect(Header2).toBeDefined()
33
- expect(typeof Header2).toBe('function')
34
- })
35
-
36
- test('component has correct PropTypes', () => {
37
- expect(Header2.propTypes).toBeDefined()
38
- expect(Header2.propTypes.title).toBeDefined()
39
- expect(Header2.propTypes.icon).toBeDefined()
40
- expect(Header2.propTypes.iconSrc).toBeDefined()
41
- expect(Header2.propTypes.img).toBeDefined()
42
- expect(Header2.propTypes.caption).toBeDefined()
43
- expect(Header2.propTypes.prominent).toBeDefined()
44
- expect(Header2.propTypes.dense).toBeDefined()
45
- expect(Header2.propTypes.primary).toBeDefined()
46
- expect(Header2.propTypes.secondary).toBeDefined()
47
- expect(Header2.propTypes.clickable).toBeDefined()
48
- expect(Header2.propTypes.disabled).toBeDefined()
49
- expect(Header2.propTypes.loading).toBeDefined()
50
- expect(Header2.propTypes.className).toBeDefined()
51
- expect(Header2.propTypes.children).toBeDefined()
52
- expect(Header2.propTypes.action).toBeDefined()
53
- expect(Header2.propTypes.ariaLabel).toBeDefined()
54
- expect(Header2.propTypes.role).toBeDefined()
55
- expect(Header2.propTypes.onClick).toBeDefined()
56
- expect(Header2.propTypes.onIconClick).toBeDefined()
57
- })
58
-
59
- test('component has correct defaultProps', () => {
60
- expect(Header2.defaultProps).toBeDefined()
61
- expect(Header2.defaultProps.caption).toBe(false)
62
- expect(Header2.defaultProps.prominent).toBe(false)
63
- expect(Header2.defaultProps.dense).toBe(false)
64
- expect(Header2.defaultProps.primary).toBe(false)
65
- expect(Header2.defaultProps.secondary).toBe(false)
66
- expect(Header2.defaultProps.clickable).toBe(false)
67
- expect(Header2.defaultProps.disabled).toBe(false)
68
- expect(Header2.defaultProps.loading).toBe(false)
69
- expect(Header2.defaultProps.role).toBe('banner')
70
- expect(Header2.defaultProps.className).toBe('')
71
- })
72
-
73
- test('warns when no accessibility props are provided', () => {
74
- const validateAccessibility = (title, icon, iconSrc, ariaLabel) => {
75
- if (!title && !icon && !iconSrc && !ariaLabel) {
76
- console.warn('Header2 component: title, icon, iconSrc, or ariaLabel should be provided for accessibility')
77
- }
78
- }
79
-
80
- validateAccessibility(null, null, null, null)
81
- expect(console.warn).toHaveBeenCalledWith('Header2 component: title, icon, iconSrc, or ariaLabel should be provided for accessibility')
82
-
83
- console.warn.mockClear()
84
- validateAccessibility('Test Title', null, null, null)
85
- expect(console.warn).not.toHaveBeenCalled()
86
- })
87
-
88
- test('CSS classes generation maintains original logic', () => {
89
- const generateClasses = (caption, prominent, dense, primary, secondary, disabled, loading, className) => {
90
- const captionClass = caption ? 'caption' : ''
91
- const prominentClass = prominent ? 'prominent' : ''
92
- const denseClass = dense ? 'dense' : ''
93
- let themeClass = primary ? 'primary' : ''
94
- themeClass = secondary ? 'secondary' : themeClass
95
-
96
- return [
97
- 'header2',
98
- captionClass,
99
- prominentClass,
100
- denseClass,
101
- themeClass,
102
- disabled && 'disabled',
103
- loading && 'loading',
104
- className || ''
105
- ].filter(Boolean).join(' ')
106
- }
107
-
108
- // Test basic header
109
- expect(generateClasses(false, false, false, false, false, false, false, ''))
110
- .toBe('header2')
111
-
112
- // Test caption variant
113
- expect(generateClasses(true, false, false, false, false, false, false, ''))
114
- .toBe('header2 caption')
115
-
116
- // Test prominent variant
117
- expect(generateClasses(false, true, false, false, false, false, false, ''))
118
- .toBe('header2 prominent')
119
-
120
- // Test dense variant
121
- expect(generateClasses(false, false, true, false, false, false, false, ''))
122
- .toBe('header2 dense')
123
-
124
- // Test primary theme
125
- expect(generateClasses(false, false, false, true, false, false, false, ''))
126
- .toBe('header2 primary')
127
-
128
- // Test secondary theme (overrides primary)
129
- expect(generateClasses(false, false, false, true, true, false, false, ''))
130
- .toBe('header2 secondary')
131
-
132
- // Test disabled state
133
- expect(generateClasses(false, false, false, false, false, true, false, ''))
134
- .toBe('header2 disabled')
135
-
136
- // Test loading state
137
- expect(generateClasses(false, false, false, false, false, false, true, ''))
138
- .toBe('header2 loading')
139
-
140
- // Test custom className
141
- expect(generateClasses(false, false, false, false, false, false, false, 'custom-class'))
142
- .toBe('header2 custom-class')
143
-
144
- // Test combination
145
- expect(generateClasses(true, false, false, true, false, false, false, 'custom'))
146
- .toBe('header2 caption primary custom')
147
- })
148
-
149
- test('icon element generation maintains original logic', () => {
150
- const generateIconElement = (icon, iconSrc, clickable, disabled, loading, handleIconClick, ariaLabel, title) => {
151
- if (icon) {
152
- return {
153
- type: 'Icon',
154
- props: {
155
- icon: icon,
156
- clickable: clickable && !disabled && !loading,
157
- action: handleIconClick,
158
- disabled: disabled,
159
- ariaLabel: `${icon} icon`
160
- }
161
- }
162
- } else if (iconSrc) {
163
- return {
164
- type: 'img',
165
- props: {
166
- className: 'header2-icon',
167
- src: iconSrc,
168
- alt: ariaLabel || title || 'Header icon',
169
- onClick: clickable && !disabled && !loading ? handleIconClick : undefined,
170
- style: {
171
- cursor: clickable && !disabled && !loading ? 'pointer' : 'default',
172
- opacity: disabled ? 0.6 : 1
173
- }
174
- }
175
- }
176
- }
177
- return null
178
- }
179
-
180
- const mockHandler = jest.fn()
181
-
182
- // Test with icon
183
- const iconResult = generateIconElement('home', null, true, false, false, mockHandler, null, null)
184
- expect(iconResult.type).toBe('Icon')
185
- expect(iconResult.props.icon).toBe('home')
186
- expect(iconResult.props.clickable).toBe(true)
187
- expect(iconResult.props.ariaLabel).toBe('home icon')
188
-
189
- // Test with iconSrc
190
- const imgResult = generateIconElement(null, '/icon.png', true, false, false, mockHandler, 'Custom label', 'Title')
191
- expect(imgResult.type).toBe('img')
192
- expect(imgResult.props.src).toBe('/icon.png')
193
- expect(imgResult.props.alt).toBe('Custom label')
194
- expect(imgResult.props.style.cursor).toBe('pointer')
195
-
196
- // Test disabled state
197
- const disabledResult = generateIconElement('home', null, true, true, false, mockHandler, null, null)
198
- expect(disabledResult.props.clickable).toBe(false)
199
-
200
- // Test loading state
201
- const loadingResult = generateIconElement('home', null, true, false, true, mockHandler, null, null)
202
- expect(loadingResult.props.clickable).toBe(false)
203
-
204
- // Test no icon
205
- const noIconResult = generateIconElement(null, null, true, false, false, mockHandler, null, null)
206
- expect(noIconResult).toBeNull()
207
- })
208
-
209
- test('background style generation maintains original logic', () => {
210
- const generateBackgroundStyle = (img) => {
211
- return img ? { backgroundImage: `url(${img})` } : {}
212
- }
213
-
214
- expect(generateBackgroundStyle(null)).toEqual({})
215
- expect(generateBackgroundStyle('')).toEqual({})
216
- expect(generateBackgroundStyle('/bg.jpg')).toEqual({ backgroundImage: 'url(/bg.jpg)' })
217
- expect(generateBackgroundStyle('https://example.com/bg.png')).toEqual({ backgroundImage: 'url(https://example.com/bg.png)' })
218
- })
219
-
220
- test('accessibility attributes generation works correctly', () => {
221
- const generateAriaAttributes = (ariaLabel, title, disabled, loading, role) => {
222
- return {
223
- 'aria-label': ariaLabel || (typeof title === 'string' ? title : 'Header'),
224
- 'aria-disabled': disabled,
225
- 'aria-busy': loading,
226
- role: role
227
- }
228
- }
229
-
230
- // Test with string title
231
- const result1 = generateAriaAttributes(null, 'Test Title', false, false, 'banner')
232
- expect(result1['aria-label']).toBe('Test Title')
233
- expect(result1['aria-disabled']).toBe(false)
234
- expect(result1['aria-busy']).toBe(false)
235
- expect(result1.role).toBe('banner')
236
-
237
- // Test with custom aria-label
238
- const result2 = generateAriaAttributes('Custom Label', 'Test Title', false, false, 'banner')
239
- expect(result2['aria-label']).toBe('Custom Label')
240
-
241
- // Test with non-string title
242
- const result3 = generateAriaAttributes(null, { type: 'span', children: 'Complex Title' }, false, false, 'banner')
243
- expect(result3['aria-label']).toBe('Header')
244
-
245
- // Test disabled state
246
- const result4 = generateAriaAttributes(null, 'Test Title', true, false, 'banner')
247
- expect(result4['aria-disabled']).toBe(true)
248
-
249
- // Test loading state
250
- const result5 = generateAriaAttributes(null, 'Test Title', false, true, 'banner')
251
- expect(result5['aria-busy']).toBe(true)
252
-
253
- // Test custom role
254
- const result6 = generateAriaAttributes(null, 'Test Title', false, false, 'heading')
255
- expect(result6.role).toBe('heading')
256
- })
257
-
258
- test('icon click handling works correctly', () => {
259
- const mockOnIconClick = jest.fn()
260
- const mockAction = jest.fn()
261
-
262
- const simulateIconClick = (disabled, loading, onIconClick, action) => {
263
- if (disabled || loading) return false
264
-
265
- if (onIconClick) {
266
- onIconClick({})
267
- return true
268
- } else if (action) {
269
- action({})
270
- return true
271
- }
272
- return false
273
- }
274
-
275
- // Normal click with onIconClick
276
- expect(simulateIconClick(false, false, mockOnIconClick, null)).toBe(true)
277
- expect(mockOnIconClick).toHaveBeenCalled()
278
-
279
- mockOnIconClick.mockClear()
280
-
281
- // Normal click with action (fallback)
282
- expect(simulateIconClick(false, false, null, mockAction)).toBe(true)
283
- expect(mockAction).toHaveBeenCalled()
284
-
285
- mockAction.mockClear()
286
-
287
- // Disabled click
288
- expect(simulateIconClick(true, false, mockOnIconClick, null)).toBe(false)
289
- expect(mockOnIconClick).not.toHaveBeenCalled()
290
-
291
- // Loading click
292
- expect(simulateIconClick(false, true, mockOnIconClick, null)).toBe(false)
293
- expect(mockOnIconClick).not.toHaveBeenCalled()
294
-
295
- // No handlers
296
- expect(simulateIconClick(false, false, null, null)).toBe(false)
297
- })
298
-
299
- test('header click handling works correctly', () => {
300
- const mockOnClick = jest.fn()
301
-
302
- const simulateHeaderClick = (disabled, loading, onClick) => {
303
- if (disabled || loading) return false
304
-
305
- if (onClick) {
306
- onClick({})
307
- return true
308
- }
309
- return false
310
- }
311
-
312
- // Normal click
313
- expect(simulateHeaderClick(false, false, mockOnClick)).toBe(true)
314
- expect(mockOnClick).toHaveBeenCalled()
315
-
316
- mockOnClick.mockClear()
317
-
318
- // Disabled click
319
- expect(simulateHeaderClick(true, false, mockOnClick)).toBe(false)
320
- expect(mockOnClick).not.toHaveBeenCalled()
321
-
322
- // Loading click
323
- expect(simulateHeaderClick(false, true, mockOnClick)).toBe(false)
324
- expect(mockOnClick).not.toHaveBeenCalled()
325
-
326
- // No handler
327
- expect(simulateHeaderClick(false, false, null)).toBe(false)
328
- })
329
-
330
- test('title element generation maintains original logic', () => {
331
- const generateTitleElement = (title) => {
332
- return title ? {
333
- type: 'label',
334
- className: 'header2-title',
335
- children: { type: 'Text', children: title }
336
- } : null
337
- }
338
-
339
- expect(generateTitleElement(null)).toBeNull()
340
- expect(generateTitleElement('')).toBeNull()
341
-
342
- const result = generateTitleElement('Test Title')
343
- expect(result.type).toBe('label')
344
- expect(result.className).toBe('header2-title')
345
- expect(result.children.children).toBe('Test Title')
346
- })
347
-
348
- test('theme class logic maintains original behavior', () => {
349
- const generateThemeClass = (primary, secondary) => {
350
- let themeClass = primary ? 'primary' : ''
351
- themeClass = secondary ? 'secondary' : themeClass
352
- return themeClass
353
- }
354
-
355
- expect(generateThemeClass(false, false)).toBe('')
356
- expect(generateThemeClass(true, false)).toBe('primary')
357
- expect(generateThemeClass(false, true)).toBe('secondary')
358
- expect(generateThemeClass(true, true)).toBe('secondary') // secondary overrides primary
359
- })
360
-
361
- test('maintains exact same height calculations as original', () => {
362
- const getHeaderHeight = (caption, prominent, dense) => {
363
- if (prominent) return '12.8rem'
364
- if (caption) return '4rem'
365
- if (dense) return '2.4rem'
366
- return '3rem' // min-height for normal
367
- }
368
-
369
- expect(getHeaderHeight(false, false, false)).toBe('3rem')
370
- expect(getHeaderHeight(true, false, false)).toBe('4rem')
371
- expect(getHeaderHeight(false, true, false)).toBe('12.8rem')
372
- expect(getHeaderHeight(false, false, true)).toBe('2.4rem')
373
-
374
- // Prominent takes precedence
375
- expect(getHeaderHeight(true, true, true)).toBe('12.8rem')
376
- })
377
- })
@@ -1,268 +0,0 @@
1
- import React, { useState } from 'react'
2
- import { Icon } from './icon'
3
-
4
- /**
5
- * Ejemplos de uso del componente Icon mejorado
6
- */
7
- export const IconExamples = () => {
8
- const [clickCount, setClickCount] = useState(0)
9
- const [isDisabled, setIsDisabled] = useState(false)
10
-
11
- const handleClick = () => {
12
- setClickCount(prev => prev + 1)
13
- }
14
-
15
- const toggleDisabled = () => {
16
- setIsDisabled(prev => !prev)
17
- }
18
-
19
- return (
20
- <div style={{ padding: '2rem', maxWidth: '800px' }}>
21
- <h1>Ejemplos del Componente Icon Mejorado</h1>
22
-
23
- <div style={{
24
- background: '#f8f9fa',
25
- padding: '1rem',
26
- borderRadius: '8px',
27
- marginBottom: '2rem',
28
- border: '1px solid #e9ecef'
29
- }}>
30
- <h3>✅ Mejoras Implementadas:</h3>
31
- <ul>
32
- <li>🛡️ <strong>Manejo seguro de className</strong> - No falla con valores undefined</li>
33
- <li>♿ <strong>Accesibilidad mejorada</strong> - Atributos ARIA y soporte de teclado</li>
34
- <li>📝 <strong>PropTypes y documentación</strong> - Validación y documentación completa</li>
35
- <li>🎯 <strong>Validación de props</strong> - Advertencias para props requeridos</li>
36
- <li>🎨 <strong>CSS mejorado</strong> - Cursor consistente y estados de focus</li>
37
- <li>⌨️ <strong>Soporte de teclado</strong> - Enter y Espacio para activar</li>
38
- <li>🧪 <strong>Pruebas unitarias</strong> - 11 pruebas que cubren toda la funcionalidad</li>
39
- </ul>
40
- </div>
41
-
42
- {/* Iconos básicos */}
43
- <section style={{ marginBottom: '2rem' }}>
44
- <h3>Iconos Básicos</h3>
45
- <div style={{ display: 'flex', gap: '1rem', alignItems: 'center' }}>
46
- <Icon icon="home" />
47
- <Icon icon="settings" />
48
- <Icon icon="favorite" />
49
- <Icon icon="info" />
50
- </div>
51
- <p><em>Iconos simples sin interacción</em></p>
52
- </section>
53
-
54
- {/* Diferentes tamaños */}
55
- <section style={{ marginBottom: '2rem' }}>
56
- <h3>Diferentes Tamaños</h3>
57
- <div style={{ display: 'flex', gap: '1rem', alignItems: 'center' }}>
58
- <Icon icon="star" size="small" />
59
- <Icon icon="star" size="normal" />
60
- <Icon icon="star" size="large" />
61
- </div>
62
- <p><em>Tamaños: small, normal, large</em></p>
63
- </section>
64
-
65
- {/* Iconos clickables */}
66
- <section style={{ marginBottom: '2rem' }}>
67
- <h3>Iconos Clickables</h3>
68
- <div style={{ display: 'flex', gap: '1rem', alignItems: 'center' }}>
69
- <Icon
70
- icon="thumb_up"
71
- clickable
72
- action={handleClick}
73
- tooltip={{
74
- text: 'Hacer clic para incrementar',
75
- top: '-3rem',
76
- left: '-2rem'
77
- }}
78
- />
79
- <Icon
80
- icon="refresh"
81
- clickable
82
- action={() => setClickCount(0)}
83
- tooltip={{
84
- text: 'Resetear contador',
85
- top: '-3rem',
86
- left: '-2rem'
87
- }}
88
- />
89
- <span>Clics: {clickCount}</span>
90
- </div>
91
- <p><em>Prueba hacer clic en los iconos o usar Enter/Espacio cuando tengan focus</em></p>
92
- </section>
93
-
94
- {/* Estados disabled */}
95
- <section style={{ marginBottom: '2rem' }}>
96
- <h3>Estados Disabled</h3>
97
- <div style={{ display: 'flex', gap: '1rem', alignItems: 'center' }}>
98
- <Icon
99
- icon="toggle_on"
100
- clickable
101
- action={toggleDisabled}
102
- tooltip={{
103
- text: 'Alternar estado disabled',
104
- top: '-3rem',
105
- left: '-3rem'
106
- }}
107
- />
108
- <Icon
109
- icon="delete"
110
- clickable
111
- disabled={isDisabled}
112
- action={() => alert('¡Eliminado!')}
113
- tooltip={{
114
- text: isDisabled ? 'Icono deshabilitado' : 'Eliminar elemento',
115
- top: '-3rem',
116
- left: '-2rem'
117
- }}
118
- />
119
- <span>Estado: {isDisabled ? 'Disabled' : 'Enabled'}</span>
120
- </div>
121
- <p><em>El primer icono alterna el estado del segundo</em></p>
122
- </section>
123
-
124
- {/* Iconos con tooltips */}
125
- <section style={{ marginBottom: '2rem' }}>
126
- <h3>Iconos con Tooltips</h3>
127
- <div style={{ display: 'flex', gap: '1rem', alignItems: 'center' }}>
128
- <Icon
129
- icon="help"
130
- clickable
131
- tooltip={{
132
- text: 'Ayuda y soporte',
133
- top: '-3rem',
134
- left: '-2rem'
135
- }}
136
- action={() => alert('¡Ayuda!')}
137
- />
138
- <Icon
139
- icon="download"
140
- clickable
141
- tooltip={{
142
- text: 'Descargar archivo',
143
- top: '-3rem',
144
- left: '-2rem'
145
- }}
146
- action={() => alert('¡Descargando!')}
147
- />
148
- <Icon
149
- icon="share"
150
- clickable
151
- tooltip={{
152
- text: 'Compartir contenido',
153
- top: '-3rem',
154
- left: '-2rem'
155
- }}
156
- action={() => alert('¡Compartiendo!')}
157
- />
158
- </div>
159
- <p><em>Tooltips posicionados para no interferir con los clics</em></p>
160
- </section>
161
-
162
- {/* Accesibilidad */}
163
- <section style={{ marginBottom: '2rem' }}>
164
- <h3>Accesibilidad Mejorada</h3>
165
- <div style={{ display: 'flex', gap: '1rem', alignItems: 'center' }}>
166
- <Icon
167
- icon="accessibility"
168
- clickable
169
- ariaLabel="Configuración de accesibilidad"
170
- action={() => alert('Configuración de accesibilidad')}
171
- />
172
- <Icon
173
- icon="visibility"
174
- clickable
175
- ariaLabel="Alternar visibilidad"
176
- action={() => alert('Visibilidad alternada')}
177
- />
178
- <Icon
179
- icon="hearing"
180
- clickable
181
- ariaLabel="Configuración de audio"
182
- action={() => alert('Configuración de audio')}
183
- />
184
- </div>
185
- <p><em>Iconos con etiquetas ARIA personalizadas y soporte completo de teclado</em></p>
186
- </section>
187
-
188
- {/* Clases personalizadas */}
189
- <section style={{ marginBottom: '2rem' }}>
190
- <h3>Clases CSS Personalizadas</h3>
191
- <div style={{ display: 'flex', gap: '1rem', alignItems: 'center' }}>
192
- <Icon
193
- icon="palette"
194
- className="custom-icon-style"
195
- style={{ color: '#e91e63' }}
196
- />
197
- <Icon
198
- icon="brush"
199
- className="another-custom-class"
200
- style={{ color: '#2196f3' }}
201
- />
202
- <Icon
203
- icon="color_lens"
204
- className={undefined} // Manejo seguro de undefined
205
- style={{ color: '#4caf50' }}
206
- />
207
- </div>
208
- <p><em>Manejo seguro de className, incluso con valores undefined</em></p>
209
- </section>
210
-
211
- {/* Demostración de validación */}
212
- <section style={{ marginBottom: '2rem' }}>
213
- <h3>Validación de Props</h3>
214
- <div style={{
215
- background: '#fff3cd',
216
- padding: '1rem',
217
- borderRadius: '4px',
218
- border: '1px solid #ffeaa7'
219
- }}>
220
- <p><strong>Prueba en la consola del navegador:</strong></p>
221
- <p>El componente ahora valida que la prop <code>icon</code> sea requerida y muestra advertencias apropiadas.</p>
222
- <p>También valida tipos de props en desarrollo para detectar errores temprano.</p>
223
- </div>
224
- </section>
225
-
226
- {/* Comparación antes/después */}
227
- <section>
228
- <h3>Comparación: Antes vs Después</h3>
229
- <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '1rem' }}>
230
- <div style={{
231
- background: '#ffebee',
232
- padding: '1rem',
233
- borderRadius: '4px',
234
- border: '1px solid #ffcdd2'
235
- }}>
236
- <h4>❌ Antes</h4>
237
- <ul>
238
- <li>className undefined causaba errores</li>
239
- <li>Sin validación de props</li>
240
- <li>Sin accesibilidad</li>
241
- <li>Sin soporte de teclado</li>
242
- <li>Cursor inconsistente</li>
243
- <li>Sin documentación</li>
244
- </ul>
245
- </div>
246
- <div style={{
247
- background: '#e8f5e8',
248
- padding: '1rem',
249
- borderRadius: '4px',
250
- border: '1px solid #c8e6c9'
251
- }}>
252
- <h4>✅ Después</h4>
253
- <ul>
254
- <li>Manejo seguro de todas las props</li>
255
- <li>PropTypes completos</li>
256
- <li>Atributos ARIA apropiados</li>
257
- <li>Soporte completo de teclado</li>
258
- <li>Estados visuales consistentes</li>
259
- <li>Documentación y ejemplos</li>
260
- </ul>
261
- </div>
262
- </div>
263
- </section>
264
- </div>
265
- )
266
- }
267
-
268
- export default IconExamples