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,504 +0,0 @@
1
- import React from 'react'
2
- import { Tabs, Tab, Stack } from './tab'
3
-
4
- // Pruebas unitarias para los componentes Tab mejorados
5
- describe('Enhanced Tab Components', () => {
6
- // Mock de los componentes dependientes
7
- const mockIcon = jest.fn()
8
- const mockText = jest.fn()
9
-
10
- beforeEach(() => {
11
- jest.clearAllMocks()
12
-
13
- // Mock de componentes
14
- jest.doMock('./icon', () => ({ Icon: mockIcon }))
15
- jest.doMock('./text', () => ({ Text: mockText }))
16
-
17
- // Mock de console.warn
18
- jest.spyOn(console, 'warn').mockImplementation(() => {})
19
-
20
- // Mock de localStorage
21
- const localStorageMock = {
22
- getItem: jest.fn(),
23
- setItem: jest.fn(),
24
- removeItem: jest.fn(),
25
- clear: jest.fn(),
26
- }
27
- global.localStorage = localStorageMock
28
- })
29
-
30
- afterEach(() => {
31
- console.warn.mockRestore()
32
- })
33
-
34
- // Tabs Component Tests
35
- describe('Tabs Component', () => {
36
- test('component exports correctly', () => {
37
- expect(Tabs).toBeDefined()
38
- expect(typeof Tabs).toBe('function')
39
- })
40
-
41
- test('component has correct PropTypes', () => {
42
- expect(Tabs.propTypes).toBeDefined()
43
- expect(Tabs.propTypes.children).toBeDefined()
44
- expect(Tabs.propTypes.selected).toBeDefined()
45
- expect(Tabs.propTypes.onChange).toBeDefined()
46
- expect(Tabs.propTypes.fillLeft).toBeDefined()
47
- expect(Tabs.propTypes.fillRight).toBeDefined()
48
- expect(Tabs.propTypes.orientation).toBeDefined()
49
- expect(Tabs.propTypes.variant).toBeDefined()
50
- expect(Tabs.propTypes.disabled).toBeDefined()
51
- expect(Tabs.propTypes.animated).toBeDefined()
52
- expect(Tabs.propTypes.persistent).toBeDefined()
53
- })
54
-
55
- test('component has correct defaultProps', () => {
56
- expect(Tabs.defaultProps).toBeDefined()
57
- expect(Tabs.defaultProps.fillLeft).toBe(false)
58
- expect(Tabs.defaultProps.fillRight).toBe(true)
59
- expect(Tabs.defaultProps.orientation).toBe('horizontal')
60
- expect(Tabs.defaultProps.variant).toBe('standard')
61
- expect(Tabs.defaultProps.disabled).toBe(false)
62
- expect(Tabs.defaultProps.animated).toBe(true)
63
- expect(Tabs.defaultProps.persistent).toBe(false)
64
- })
65
-
66
- test('warns when children is empty', () => {
67
- const validateChildren = (children) => {
68
- if (children && !React.Children.count(children)) {
69
- console.warn('Tabs component: children prop should contain Tab components')
70
- }
71
- }
72
-
73
- validateChildren([])
74
- expect(console.warn).toHaveBeenCalledWith('Tabs component: children prop should contain Tab components')
75
-
76
- console.warn.mockClear()
77
- validateChildren(null)
78
- expect(console.warn).not.toHaveBeenCalled()
79
- })
80
-
81
- test('handles selection correctly', () => {
82
- const mockOnChange = jest.fn()
83
-
84
- const handleSelect = async (id, index, disabled, beforeChange, onChange, selected) => {
85
- if (disabled) return
86
-
87
- if (beforeChange) {
88
- try {
89
- const canChange = await beforeChange(id || index, selected)
90
- if (canChange === false) return
91
- } catch (error) {
92
- console.warn('Tabs beforeChange hook error:', error)
93
- return
94
- }
95
- }
96
-
97
- if (onChange) onChange(id || index)
98
- }
99
-
100
- // Normal selection
101
- handleSelect('tab1', 0, false, null, mockOnChange, null)
102
- expect(mockOnChange).toHaveBeenCalledWith('tab1')
103
-
104
- mockOnChange.mockClear()
105
-
106
- // Disabled state
107
- handleSelect('tab1', 0, true, null, mockOnChange, null)
108
- expect(mockOnChange).not.toHaveBeenCalled()
109
- })
110
-
111
- test('handles beforeChange hook correctly', async () => {
112
- const mockOnChange = jest.fn()
113
- const mockBeforeChange = jest.fn()
114
-
115
- const handleSelect = async (id, index, disabled, beforeChange, onChange, selected) => {
116
- if (disabled) return
117
-
118
- if (beforeChange) {
119
- try {
120
- const canChange = await beforeChange(id || index, selected)
121
- if (canChange === false) return
122
- } catch (error) {
123
- console.warn('Tabs beforeChange hook error:', error)
124
- return
125
- }
126
- }
127
-
128
- if (onChange) onChange(id || index)
129
- }
130
-
131
- // Allow change
132
- mockBeforeChange.mockResolvedValue(true)
133
- await handleSelect('tab1', 0, false, mockBeforeChange, mockOnChange, 'tab0')
134
- expect(mockBeforeChange).toHaveBeenCalledWith('tab1', 'tab0')
135
- expect(mockOnChange).toHaveBeenCalledWith('tab1')
136
-
137
- mockOnChange.mockClear()
138
- mockBeforeChange.mockClear()
139
-
140
- // Prevent change
141
- mockBeforeChange.mockResolvedValue(false)
142
- await handleSelect('tab1', 0, false, mockBeforeChange, mockOnChange, 'tab0')
143
- expect(mockBeforeChange).toHaveBeenCalledWith('tab1', 'tab0')
144
- expect(mockOnChange).not.toHaveBeenCalled()
145
-
146
- mockOnChange.mockClear()
147
- mockBeforeChange.mockClear()
148
-
149
- // Error in beforeChange
150
- mockBeforeChange.mockRejectedValue(new Error('Test error'))
151
- await handleSelect('tab1', 0, false, mockBeforeChange, mockOnChange, 'tab0')
152
- expect(console.warn).toHaveBeenCalledWith('Tabs beforeChange hook error:', expect.any(Error))
153
- expect(mockOnChange).not.toHaveBeenCalled()
154
- })
155
-
156
- test('handles keyboard navigation correctly', () => {
157
- const mockHandleSelect = jest.fn()
158
- const children = [
159
- { props: { id: 'tab1' } },
160
- { props: { id: 'tab2' } },
161
- { props: { id: 'tab3' } }
162
- ]
163
-
164
- const handleKeyDown = (event, disabled, selected, notNullChildren, handleSelect) => {
165
- if (disabled) return
166
-
167
- const currentIndex = typeof selected === 'number' ? selected :
168
- notNullChildren.findIndex(child => child.props.id === selected)
169
-
170
- let newIndex = currentIndex
171
-
172
- switch (event.key) {
173
- case 'ArrowLeft':
174
- case 'ArrowUp':
175
- event.preventDefault()
176
- newIndex = currentIndex > 0 ? currentIndex - 1 : notNullChildren.length - 1
177
- break
178
- case 'ArrowRight':
179
- case 'ArrowDown':
180
- event.preventDefault()
181
- newIndex = currentIndex < notNullChildren.length - 1 ? currentIndex + 1 : 0
182
- break
183
- case 'Home':
184
- event.preventDefault()
185
- newIndex = 0
186
- break
187
- case 'End':
188
- event.preventDefault()
189
- newIndex = notNullChildren.length - 1
190
- break
191
- default:
192
- return
193
- }
194
-
195
- const targetChild = notNullChildren[newIndex]
196
- if (targetChild && !targetChild.props.disabled) {
197
- handleSelect(targetChild.props.id, newIndex)
198
- }
199
- }
200
-
201
- const mockEvent = { preventDefault: jest.fn() }
202
-
203
- // Arrow right from first tab
204
- handleKeyDown({ ...mockEvent, key: 'ArrowRight' }, false, 0, children, mockHandleSelect)
205
- expect(mockHandleSelect).toHaveBeenCalledWith('tab2', 1)
206
-
207
- mockHandleSelect.mockClear()
208
-
209
- // Arrow left from last tab (wrap around)
210
- handleKeyDown({ ...mockEvent, key: 'ArrowLeft' }, false, 2, children, mockHandleSelect)
211
- expect(mockHandleSelect).toHaveBeenCalledWith('tab2', 1)
212
-
213
- mockHandleSelect.mockClear()
214
-
215
- // Home key
216
- handleKeyDown({ ...mockEvent, key: 'Home' }, false, 2, children, mockHandleSelect)
217
- expect(mockHandleSelect).toHaveBeenCalledWith('tab1', 0)
218
-
219
- mockHandleSelect.mockClear()
220
-
221
- // End key
222
- handleKeyDown({ ...mockEvent, key: 'End' }, false, 0, children, mockHandleSelect)
223
- expect(mockHandleSelect).toHaveBeenCalledWith('tab3', 2)
224
- })
225
-
226
- test('generates CSS classes correctly', () => {
227
- const generateClasses = (orientation, variant, scrollable, centered, disabled, animated, className) => {
228
- return [
229
- 'tabs',
230
- `tabs--${orientation}`,
231
- `tabs--${variant}`,
232
- scrollable && 'tabs--scrollable',
233
- centered && 'tabs--centered',
234
- disabled && 'tabs--disabled',
235
- animated && 'tabs--animated',
236
- className
237
- ].filter(Boolean).join(' ')
238
- }
239
-
240
- expect(generateClasses('horizontal', 'standard', false, false, false, false, ''))
241
- .toBe('tabs tabs--horizontal tabs--standard')
242
-
243
- expect(generateClasses('vertical', 'scrollable', true, true, true, true, 'custom'))
244
- .toBe('tabs tabs--vertical tabs--scrollable tabs--scrollable tabs--centered tabs--disabled tabs--animated custom')
245
- })
246
-
247
- test('generates accessibility attributes correctly', () => {
248
- const generateAriaAttributes = (ariaLabel, disabled, orientation) => {
249
- return {
250
- 'aria-label': ariaLabel || 'Tabs',
251
- 'aria-disabled': disabled,
252
- 'aria-orientation': orientation,
253
- role: 'tablist'
254
- }
255
- }
256
-
257
- const result1 = generateAriaAttributes(null, false, 'horizontal')
258
- expect(result1['aria-label']).toBe('Tabs')
259
- expect(result1['aria-disabled']).toBe(false)
260
- expect(result1['aria-orientation']).toBe('horizontal')
261
- expect(result1.role).toBe('tablist')
262
-
263
- const result2 = generateAriaAttributes('Custom Tabs', true, 'vertical')
264
- expect(result2['aria-label']).toBe('Custom Tabs')
265
- expect(result2['aria-disabled']).toBe(true)
266
- expect(result2['aria-orientation']).toBe('vertical')
267
- })
268
-
269
- test('handles persistent tabs correctly', () => {
270
- const mockOnChange = jest.fn()
271
-
272
- // Test persistence logic
273
- const testPersistence = (persistent, persistKey, savedValue, currentSelected) => {
274
- if (persistent && persistKey && savedValue !== null) {
275
- const parsedTab = isNaN(savedValue) ? savedValue : parseInt(savedValue)
276
- if (parsedTab !== currentSelected) {
277
- return parsedTab
278
- }
279
- }
280
- return currentSelected
281
- }
282
-
283
- // Test loading saved tab
284
- const result1 = testPersistence(true, 'test-tabs', '2', 0)
285
- expect(result1).toBe(2)
286
-
287
- // Test no change when same tab
288
- const result2 = testPersistence(true, 'test-tabs', '1', 1)
289
- expect(result2).toBe(1)
290
-
291
- // Test disabled persistence
292
- const result3 = testPersistence(false, 'test-tabs', '2', 0)
293
- expect(result3).toBe(0)
294
-
295
- // Test save logic
296
- const testSave = (persistent, persistKey, selected) => {
297
- if (persistent && persistKey && selected !== undefined) {
298
- return `tabs-${persistKey}:${selected.toString()}`
299
- }
300
- return null
301
- }
302
-
303
- expect(testSave(true, 'test-tabs', 1)).toBe('tabs-test-tabs:1')
304
- expect(testSave(false, 'test-tabs', 1)).toBe(null)
305
- })
306
- })
307
-
308
- // Tab Component Tests
309
- describe('Tab Component', () => {
310
- test('component has correct PropTypes', () => {
311
- expect(Tab.propTypes).toBeDefined()
312
- expect(Tab.propTypes.id).toBeDefined()
313
- expect(Tab.propTypes.icon).toBeDefined()
314
- expect(Tab.propTypes.label).toBeDefined()
315
- expect(Tab.propTypes.selected).toBeDefined()
316
- expect(Tab.propTypes.disabled).toBeDefined()
317
- expect(Tab.propTypes.closeable).toBeDefined()
318
- expect(Tab.propTypes.badge).toBeDefined()
319
- })
320
-
321
- test('component has correct defaultProps', () => {
322
- expect(Tab.defaultProps).toBeDefined()
323
- expect(Tab.defaultProps.disabled).toBe(false)
324
- expect(Tab.defaultProps.closeable).toBe(false)
325
- expect(Tab.defaultProps.animated).toBe(true)
326
- })
327
-
328
- test('handles selection correctly', () => {
329
- const mockOnSelect = jest.fn()
330
-
331
- const handleSelect = (event, disabled, onSelect, id) => {
332
- if (disabled) return
333
- event.preventDefault()
334
- if (onSelect) onSelect(id)
335
- }
336
-
337
- const mockEvent = { preventDefault: jest.fn() }
338
-
339
- // Normal selection
340
- handleSelect(mockEvent, false, mockOnSelect, 'tab1')
341
- expect(mockEvent.preventDefault).toHaveBeenCalled()
342
- expect(mockOnSelect).toHaveBeenCalledWith('tab1')
343
-
344
- mockOnSelect.mockClear()
345
-
346
- // Disabled state
347
- handleSelect(mockEvent, true, mockOnSelect, 'tab1')
348
- expect(mockOnSelect).not.toHaveBeenCalled()
349
- })
350
-
351
- test('handles close correctly', () => {
352
- const mockOnClose = jest.fn()
353
-
354
- const handleClose = (event, onClose, id) => {
355
- event.stopPropagation()
356
- if (onClose) onClose(id)
357
- }
358
-
359
- const mockEvent = { stopPropagation: jest.fn() }
360
-
361
- handleClose(mockEvent, mockOnClose, 'tab1')
362
- expect(mockEvent.stopPropagation).toHaveBeenCalled()
363
- expect(mockOnClose).toHaveBeenCalledWith('tab1')
364
- })
365
-
366
- test('handles keyboard interaction correctly', () => {
367
- const mockOnSelect = jest.fn()
368
- const mockOnClose = jest.fn()
369
-
370
- const handleKeyDown = (event, disabled, onSelect, id, closeable, onClose) => {
371
- if (disabled) return
372
-
373
- switch (event.key) {
374
- case 'Enter':
375
- case ' ':
376
- event.preventDefault()
377
- if (onSelect) onSelect(id)
378
- break
379
- case 'Delete':
380
- case 'Backspace':
381
- if (closeable && onClose) {
382
- event.preventDefault()
383
- onClose(id)
384
- }
385
- break
386
- default:
387
- break
388
- }
389
- }
390
-
391
- const mockEvent = { preventDefault: jest.fn() }
392
-
393
- // Enter key
394
- handleKeyDown({ ...mockEvent, key: 'Enter' }, false, mockOnSelect, 'tab1', false, null)
395
- expect(mockOnSelect).toHaveBeenCalledWith('tab1')
396
-
397
- mockOnSelect.mockClear()
398
-
399
- // Delete key with closeable tab
400
- handleKeyDown({ ...mockEvent, key: 'Delete' }, false, mockOnSelect, 'tab1', true, mockOnClose)
401
- expect(mockOnClose).toHaveBeenCalledWith('tab1')
402
- })
403
-
404
- test('generates CSS classes correctly', () => {
405
- const generateClasses = (selected, disabled, closeable, animated, orientation, variant, className) => {
406
- return [
407
- 'tab',
408
- selected && 'selected',
409
- disabled && 'tab--disabled',
410
- closeable && 'tab--closeable',
411
- animated && 'tab--animated',
412
- `tab--${orientation}`,
413
- `tab--${variant}`,
414
- className
415
- ].filter(Boolean).join(' ')
416
- }
417
-
418
- expect(generateClasses(false, false, false, false, 'horizontal', 'standard', ''))
419
- .toBe('tab tab--horizontal tab--standard')
420
-
421
- expect(generateClasses(true, true, true, true, 'vertical', 'scrollable', 'custom'))
422
- .toBe('tab selected tab--disabled tab--closeable tab--animated tab--vertical tab--scrollable custom')
423
- })
424
-
425
- test('generates accessibility attributes correctly', () => {
426
- const generateAriaAttributes = (selected, disabled, id, tabIndex, label) => {
427
- return {
428
- 'aria-selected': selected,
429
- 'aria-disabled': disabled,
430
- 'aria-controls': `tabpanel-${id || tabIndex}`,
431
- 'aria-label': typeof label === 'string' ? label : `Tab ${(tabIndex || 0) + 1}`,
432
- role: 'tab',
433
- tabIndex: selected ? 0 : -1,
434
- id: `tab-${id || tabIndex}`
435
- }
436
- }
437
-
438
- const result1 = generateAriaAttributes(true, false, 'tab1', 0, 'First Tab')
439
- expect(result1['aria-selected']).toBe(true)
440
- expect(result1['aria-disabled']).toBe(false)
441
- expect(result1['aria-controls']).toBe('tabpanel-tab1')
442
- expect(result1['aria-label']).toBe('First Tab')
443
- expect(result1.role).toBe('tab')
444
- expect(result1.tabIndex).toBe(0)
445
- expect(result1.id).toBe('tab-tab1')
446
-
447
- const result2 = generateAriaAttributes(false, true, null, 1, null)
448
- expect(result2['aria-selected']).toBe(false)
449
- expect(result2['aria-disabled']).toBe(true)
450
- expect(result2['aria-label']).toBe('Tab 2')
451
- expect(result2.tabIndex).toBe(-1)
452
- })
453
- })
454
-
455
- // Stack Component Tests
456
- describe('Stack Component', () => {
457
- test('component has correct PropTypes', () => {
458
- expect(Stack.propTypes).toBeDefined()
459
- expect(Stack.propTypes.selected).toBeDefined()
460
- expect(Stack.propTypes.children).toBeDefined()
461
- expect(Stack.propTypes.lazy).toBeDefined()
462
- expect(Stack.propTypes.keepMounted).toBeDefined()
463
- expect(Stack.propTypes.animated).toBeDefined()
464
- })
465
-
466
- test('component has correct defaultProps', () => {
467
- expect(Stack.defaultProps).toBeDefined()
468
- expect(Stack.defaultProps.selected).toBe(0)
469
- expect(Stack.defaultProps.lazy).toBe(false)
470
- expect(Stack.defaultProps.keepMounted).toBe(false)
471
- expect(Stack.defaultProps.animated).toBe(true)
472
- })
473
-
474
- test('handles lazy loading correctly', () => {
475
- const handleLazyLoading = (selected, lazy, keepMounted, mountedTabs) => {
476
- if (lazy || keepMounted) {
477
- return new Set([...mountedTabs, selected])
478
- }
479
- return mountedTabs
480
- }
481
-
482
- const initialMounted = new Set([0])
483
-
484
- // Add new tab to mounted set
485
- const newMounted = handleLazyLoading(2, true, false, initialMounted)
486
- expect(newMounted.has(0)).toBe(true)
487
- expect(newMounted.has(2)).toBe(true)
488
- expect(newMounted.has(1)).toBe(false)
489
- })
490
-
491
- test('generates CSS classes correctly', () => {
492
- const generateClasses = (animated, className) => {
493
- return [
494
- 'stack',
495
- animated && 'stack--animated',
496
- className
497
- ].filter(Boolean).join(' ')
498
- }
499
-
500
- expect(generateClasses(false, '')).toBe('stack')
501
- expect(generateClasses(true, 'custom')).toBe('stack stack--animated custom')
502
- })
503
- })
504
- })
@@ -1,70 +0,0 @@
1
- import React, { useState } from 'react'
2
- import { FORMATS } from '../domain/ContentType'
3
- import { DataTable } from './table'
4
-
5
- export const TableTest = (prop) => {
6
-
7
- const [rows, setRows] = useState(
8
- [
9
- { id: 1, checked: false, name: "John Smith" , description: "lorem ipsum 9", color: "#CACAFF", num: "25", thumb: "https://w7.pngwing.com/pngs/881/826/png-transparent-pikachu-ash-ketchum-pokemon-vrste-pikachu-leaf-flower-meme-thumbnail.png" },
10
- { id: 2, checked: false, name: "Ann Martin" , description: "lorem ipsum 2", color: "#CCFFFF", num: "1234567890.1234567890" },
11
- { id: 3, checked: false, name: "Ann Martin" , description: "lorem ipsum 8", color: "#CCFFFF", num: "12340.1234567890" },
12
- { id: 4, checked: false, name: "Zack McCracken", description: "lorem ipsum 4", color: "#CCFFFF", num: "567890.1234567890" },
13
- { id: 5, checked: false, name: "Ann Martin" , description: "lorem ipsum 1", color: "#CCFFFF", num: "23670.190" },
14
- { id: 6, checked: false, name: "John Smith" , description: "lorem ipsum 2", color: "#CCFFFF", num: "71230.10" },
15
- { id: 7, checked: false, name: "Ann Martin" , description: "lorem ipsum 1", color: "#CCFFFF", num: "3490.23" },
16
- { id: 8, checked: false, name: "Martin Freeman", description: "lorem ipsum 4", color: "#CCFFFF" , num: "890.1234567890" },
17
- { id: 9, checked: false, name: "Ann Martin" , description: "lorem ipsum 5", color: "#CCFFFF", num: "365", date: new Date().toString() },
18
- ]
19
- )
20
-
21
- function editCell(row, cell, value) {
22
- //console.log(row, cell, value)
23
- }
24
-
25
- function select(row) {
26
- const next = rows.map(r => r.id === row.id ? { ...r, selected: !r.selected } : r)
27
- setRows(next)
28
- }
29
-
30
- function check(rowID, columnID, value) {
31
- const next = rows.map(r => r.id === rowID ? { ...r, checked: value } : r)
32
- setRows(next)
33
- }
34
-
35
- function checkAll(ids, checked) {
36
- const next = rows.map(row => Object.assign({}, row, { checked }))
37
- setRows(next)
38
- }
39
-
40
- const table1 = {
41
- className: "xxx",
42
- editable: true,
43
- columns: [
44
- { id: "index" , label: "#" , type: "INDEX" },
45
- { id: "checked" , onChange: check },
46
- { id: "name" , label: "Name" , type: "String", sortable: true, filterable: true, resizable: true },
47
- { id: "category" , label: "Category" , type: "String", sortable: true, filterable: true, resizable: false, options: [
48
- { label: "A", value: "A" },
49
- { label: "B", value: "B" },
50
- { label: "C", value: "C" },
51
- ]},
52
- { id: "description", label: "Description", type: "String", sortable: true },
53
- { id: "color" , label: "Color" , type: "String", format: FORMATS.COLOR },
54
- { id: "date" , label: "Date" , type: "String", format: FORMATS.DATE },
55
- { id: "num" , label: "Num" , type: "Number", maxDecimals: 2, sortable: true},
56
- ],
57
- rows
58
- }
59
-
60
- return (
61
- <>
62
- <div style={{ maxHeight: "20rem", overflow: "auto", margin: "2rem", display: "flex" }}>
63
- <DataTable {...table1} onRowSelection={select} outlined multisort={true}/>
64
- </div>
65
- <div style={{ maxHeight: "20rem", overflow: "auto", margin: "2rem" }}>
66
- <DataTable {...table1} onRowSelection={select} onCheckAll={checkAll} filterable={true} />
67
- </div>
68
- </>
69
- )
70
- }