ywana-core8 0.1.74 → 0.1.76

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 (123) hide show
  1. package/ACCORDION_EVALUATION.md +583 -0
  2. package/CHECKBOX_EVALUATION.md +273 -0
  3. package/CHIP_EVALUATION.md +542 -0
  4. package/COLOR_EVALUATION.md +524 -0
  5. package/COMPONENTS_EVALUATION.md +477 -0
  6. package/FORM_EVALUATION.md +459 -0
  7. package/HEADER_EVALUATION.md +436 -0
  8. package/ICON_EVALUATION.md +254 -0
  9. package/LIST_EVALUATION.md +574 -0
  10. package/PROGRESS_EVALUATION.md +450 -0
  11. package/RADIO_EVALUATION.md +439 -0
  12. package/RADIO_VISUAL_FIX.md +183 -0
  13. package/SECTION_IMPROVEMENTS.md +153 -0
  14. package/SWITCH_EVALUATION.md +335 -0
  15. package/SWITCH_VISUAL_FIX.md +232 -0
  16. package/TAB_EVALUATION.md +626 -0
  17. package/TEXTFIELD_EVALUATION.md +747 -0
  18. package/TOOLTIP_FIX.md +157 -0
  19. package/TREE_EVALUATION.md +708 -0
  20. package/dist/index.cjs +7900 -1615
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.css +6094 -1122
  23. package/dist/index.css.map +1 -1
  24. package/dist/index.modern.js +7929 -1645
  25. package/dist/index.modern.js.map +1 -1
  26. package/dist/index.umd.js +7900 -1615
  27. package/dist/index.umd.js.map +1 -1
  28. package/jest.config.js +24 -0
  29. package/package.json +10 -1
  30. package/src/html/accordion.css +208 -4
  31. package/src/html/accordion.example.js +390 -0
  32. package/src/html/accordion.js +284 -28
  33. package/src/html/accordion.unit.test.js +334 -0
  34. package/src/html/button.css +157 -16
  35. package/src/html/button.example.js +374 -0
  36. package/src/html/button.js +240 -60
  37. package/src/html/button.test.js +422 -0
  38. package/src/html/checkbox.css +74 -2
  39. package/src/html/checkbox.example.js +316 -0
  40. package/src/html/checkbox.js +113 -26
  41. package/src/html/checkbox.test.js +285 -0
  42. package/src/html/chip.css +230 -19
  43. package/src/html/chip.example.js +355 -0
  44. package/src/html/chip.js +321 -25
  45. package/src/html/chip.test.js +425 -0
  46. package/src/html/color.css +435 -6
  47. package/src/html/color.example.js +527 -0
  48. package/src/html/color.js +458 -9
  49. package/src/html/color.test.js +362 -4
  50. package/src/html/components.example.js +492 -0
  51. package/src/html/components_enhanced.test.js +581 -0
  52. package/src/html/form.css +70 -3
  53. package/src/html/form.example.js +385 -0
  54. package/src/html/form.js +232 -34
  55. package/src/html/form.test.js +369 -0
  56. package/src/html/header2.css +264 -0
  57. package/src/html/header2.example.js +411 -0
  58. package/src/html/header2.js +203 -0
  59. package/src/html/header2.test.js +377 -0
  60. package/src/html/icon.css +20 -2
  61. package/src/html/icon.example.js +268 -0
  62. package/src/html/icon.js +86 -16
  63. package/src/html/icon.test.js +231 -0
  64. package/src/html/index.js +1 -1
  65. package/src/html/list.css +393 -1
  66. package/src/html/list.example.js +404 -0
  67. package/src/html/list.js +583 -40
  68. package/src/html/list.test.js +383 -0
  69. package/src/html/progress.css +707 -17
  70. package/src/html/progress.example.js +424 -0
  71. package/src/html/progress.js +906 -9
  72. package/src/html/progress.test.js +313 -0
  73. package/src/html/property.css +399 -0
  74. package/src/html/property.example.js +553 -0
  75. package/src/html/property.js +393 -15
  76. package/src/html/property.test.js +351 -2
  77. package/src/html/radio-visual-test.js +289 -0
  78. package/src/html/radio.css +137 -11
  79. package/src/html/radio.example.js +389 -0
  80. package/src/html/radio.js +234 -10
  81. package/src/html/radio.test.js +318 -0
  82. package/src/html/section.example.js +99 -0
  83. package/src/html/section.js +40 -3
  84. package/src/html/section.test.js +131 -0
  85. package/src/html/selector.css +329 -3
  86. package/src/html/selector.js +369 -23
  87. package/src/html/switch-debug.js +197 -0
  88. package/src/html/switch-test-visual.js +294 -0
  89. package/src/html/switch.css +200 -0
  90. package/src/html/switch.example.js +461 -0
  91. package/src/html/switch.js +283 -23
  92. package/src/html/switch.test.js +355 -0
  93. package/src/html/tab.css +288 -0
  94. package/src/html/tab.example.js +446 -0
  95. package/src/html/tab.js +387 -22
  96. package/src/html/tab_enhanced.js +378 -0
  97. package/src/html/tab_enhanced.test.js +504 -0
  98. package/src/html/table2.css +576 -0
  99. package/src/html/table2.example.js +703 -0
  100. package/src/html/table2.js +1252 -0
  101. package/src/html/table2.migration.md +328 -0
  102. package/src/html/table2.test.js +582 -0
  103. package/src/html/text.css +375 -0
  104. package/src/html/text.js +311 -20
  105. package/src/html/textfield.js +1 -1
  106. package/src/html/textfield2.css +842 -0
  107. package/src/html/textfield2.example.js +499 -0
  108. package/src/html/textfield2.js +1130 -0
  109. package/src/html/textfield2.test.js +950 -0
  110. package/src/html/thumbnail.css +289 -2
  111. package/src/html/thumbnail.js +214 -9
  112. package/src/html/tokenfield.css +449 -1
  113. package/src/html/tokenfield.example.js +503 -0
  114. package/src/html/tokenfield.js +561 -56
  115. package/src/html/tokenfield.test.js +423 -0
  116. package/src/html/tooltip-positioning-demo.js +187 -0
  117. package/src/html/tooltip.css +25 -2
  118. package/src/html/tree.css +228 -0
  119. package/src/html/tree.example.js +475 -0
  120. package/src/html/tree.js +712 -28
  121. package/src/html/tree_enhanced.test.js +495 -0
  122. package/table2.test.js +454 -0
  123. package/src/html/button.tsx +0 -38
@@ -1,11 +1,367 @@
1
1
  import React, { useState } from 'react'
2
- import { ColorField } from './color'
2
+ import { ColorField, ColorPicker, ColorUtils } from './color'
3
3
 
4
- const ColorFieldTest = (prop) => {
4
+ // Pruebas unitarias para los componentes Color mejorados
5
+ describe('Enhanced Color 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 DOM methods
21
+ global.document = {
22
+ createElement: jest.fn().mockReturnValue({
23
+ style: {},
24
+ appendChild: jest.fn(),
25
+ removeChild: jest.fn()
26
+ }),
27
+ body: {
28
+ appendChild: jest.fn(),
29
+ removeChild: jest.fn()
30
+ }
31
+ }
32
+ global.window = {
33
+ getComputedStyle: jest.fn().mockReturnValue({
34
+ color: 'rgb(255, 0, 0)'
35
+ })
36
+ }
37
+ })
38
+
39
+ afterEach(() => {
40
+ console.warn.mockRestore()
41
+ })
42
+
43
+ // ColorField Component Tests
44
+ describe('ColorField Component', () => {
45
+ test('component exports correctly', () => {
46
+ expect(ColorField).toBeDefined()
47
+ expect(typeof ColorField).toBe('function')
48
+ })
49
+
50
+ test('component has correct PropTypes', () => {
51
+ expect(ColorField.propTypes).toBeDefined()
52
+ expect(ColorField.propTypes.id).toBeDefined()
53
+ expect(ColorField.propTypes.label).toBeDefined()
54
+ expect(ColorField.propTypes.value).toBeDefined()
55
+ expect(ColorField.propTypes.onChange).toBeDefined()
56
+ expect(ColorField.propTypes.disabled).toBeDefined()
57
+ expect(ColorField.propTypes.required).toBeDefined()
58
+ expect(ColorField.propTypes.format).toBeDefined()
59
+ expect(ColorField.propTypes.showPreview).toBeDefined()
60
+ expect(ColorField.propTypes.presetColors).toBeDefined()
61
+ })
62
+
63
+ test('component has correct defaultProps', () => {
64
+ expect(ColorField.defaultProps).toBeDefined()
65
+ expect(ColorField.defaultProps.label).toBe("Color")
66
+ expect(ColorField.defaultProps.disabled).toBe(false)
67
+ expect(ColorField.defaultProps.required).toBe(false)
68
+ expect(ColorField.defaultProps.placeholder).toBe("#000000")
69
+ expect(ColorField.defaultProps.format).toBe('hex')
70
+ expect(ColorField.defaultProps.showPreview).toBe(true)
71
+ expect(ColorField.defaultProps.showValue).toBe(false)
72
+ expect(ColorField.defaultProps.size).toBe('medium')
73
+ expect(ColorField.defaultProps.variant).toBe('default')
74
+ })
75
+
76
+ test('validates color format correctly', () => {
77
+ const validateColor = (color, allowTransparent = false) => {
78
+ if (!color) return allowTransparent
79
+
80
+ const hexRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/
81
+ const rgbRegex = /^rgb\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*\)$/
82
+ const rgbaRegex = /^rgba\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*[\d.]+\s*\)$/
83
+ const hslRegex = /^hsl\(\s*\d+\s*,\s*\d+%\s*,\s*\d+%\s*\)$/
84
+ const hslaRegex = /^hsla\(\s*\d+\s*,\s*\d+%\s*,\s*\d+%\s*,\s*[\d.]+\s*\)$/
85
+
86
+ return hexRegex.test(color) || rgbRegex.test(color) || rgbaRegex.test(color) ||
87
+ hslRegex.test(color) || hslaRegex.test(color) ||
88
+ (allowTransparent && color.toLowerCase() === 'transparent')
89
+ }
90
+
91
+ // Valid hex colors
92
+ expect(validateColor('#FF0000')).toBe(true)
93
+ expect(validateColor('#f00')).toBe(true)
94
+ expect(validateColor('#123ABC')).toBe(true)
95
+
96
+ // Valid RGB colors
97
+ expect(validateColor('rgb(255, 0, 0)')).toBe(true)
98
+ expect(validateColor('rgba(255, 0, 0, 0.5)')).toBe(true)
99
+
100
+ // Valid HSL colors
101
+ expect(validateColor('hsl(0, 100%, 50%)')).toBe(true)
102
+ expect(validateColor('hsla(0, 100%, 50%, 0.5)')).toBe(true)
103
+
104
+ // Invalid colors
105
+ expect(validateColor('invalid')).toBe(false)
106
+ expect(validateColor('#GG0000')).toBe(false)
107
+ // Note: rgb(256, 0, 0) is technically valid regex but invalid color value
108
+ // The regex doesn't validate ranges, just format
109
+
110
+ // Transparent
111
+ expect(validateColor('transparent', true)).toBe(true)
112
+ expect(validateColor('transparent', false)).toBe(false)
113
+ expect(validateColor('', true)).toBe(true)
114
+ expect(validateColor('', false)).toBe(false)
115
+ })
116
+
117
+ test('handles change correctly', () => {
118
+ const mockOnChange = jest.fn()
119
+
120
+ const handleChange = (event, id, onChange, format) => {
121
+ const newColor = event.target.value
122
+
123
+ if (onChange) {
124
+ onChange(id, newColor)
125
+ }
126
+ }
127
+
128
+ const mockEvent = { target: { value: '#FF0000' } }
129
+
130
+ // Normal change
131
+ handleChange(mockEvent, 'color1', mockOnChange, 'hex')
132
+ expect(mockOnChange).toHaveBeenCalledWith('color1', '#FF0000')
133
+
134
+ mockOnChange.mockClear()
135
+
136
+ // No onChange callback
137
+ handleChange(mockEvent, 'color1', null, 'hex')
138
+ expect(mockOnChange).not.toHaveBeenCalled()
139
+ })
140
+
141
+ test('handles focus and blur correctly', () => {
142
+ const mockOnFocus = jest.fn()
143
+ const mockOnBlur = jest.fn()
144
+ const mockSetIsFocused = jest.fn()
145
+
146
+ const handleFocus = (event, onFocus, setIsFocused) => {
147
+ setIsFocused(true)
148
+ if (onFocus) onFocus(event)
149
+ }
150
+
151
+ const handleBlur = (event, onBlur, setIsFocused) => {
152
+ setIsFocused(false)
153
+ if (onBlur) onBlur(event)
154
+ }
155
+
156
+ const mockEvent = { target: {} }
157
+
158
+ // Focus
159
+ handleFocus(mockEvent, mockOnFocus, mockSetIsFocused)
160
+ expect(mockSetIsFocused).toHaveBeenCalledWith(true)
161
+ expect(mockOnFocus).toHaveBeenCalledWith(mockEvent)
162
+
163
+ // Blur
164
+ handleBlur(mockEvent, mockOnBlur, mockSetIsFocused)
165
+ expect(mockSetIsFocused).toHaveBeenCalledWith(false)
166
+ expect(mockOnBlur).toHaveBeenCalledWith(mockEvent)
167
+ })
168
+
169
+ test('handles clear correctly', () => {
170
+ const mockOnChange = jest.fn()
171
+ const mockOnClear = jest.fn()
172
+ const mockSetInternalValue = jest.fn()
173
+
174
+ const handleClear = (disabled, allowTransparent, placeholder, id, onChange, onClear, setInternalValue) => {
175
+ if (disabled) return
176
+
177
+ const clearedValue = allowTransparent ? 'transparent' : placeholder
178
+ setInternalValue(clearedValue)
179
+
180
+ if (onChange) onChange(id, clearedValue)
181
+ if (onClear) onClear()
182
+ }
183
+
184
+ // Normal clear
185
+ handleClear(false, false, '#000000', 'color1', mockOnChange, mockOnClear, mockSetInternalValue)
186
+ expect(mockSetInternalValue).toHaveBeenCalledWith('#000000')
187
+ expect(mockOnChange).toHaveBeenCalledWith('color1', '#000000')
188
+ expect(mockOnClear).toHaveBeenCalled()
5
189
 
6
- const [form, setForm] = useState({
190
+ mockOnChange.mockClear()
191
+ mockOnClear.mockClear()
192
+ mockSetInternalValue.mockClear()
193
+
194
+ // Clear with transparent
195
+ handleClear(false, true, '#000000', 'color1', mockOnChange, mockOnClear, mockSetInternalValue)
196
+ expect(mockSetInternalValue).toHaveBeenCalledWith('transparent')
197
+ expect(mockOnChange).toHaveBeenCalledWith('color1', 'transparent')
198
+
199
+ mockOnChange.mockClear()
200
+ mockSetInternalValue.mockClear()
201
+
202
+ // Disabled clear
203
+ handleClear(true, false, '#000000', 'color1', mockOnChange, mockOnClear, mockSetInternalValue)
204
+ expect(mockSetInternalValue).not.toHaveBeenCalled()
205
+ expect(mockOnChange).not.toHaveBeenCalled()
206
+ })
207
+
208
+ test('handles preset selection correctly', () => {
209
+ const mockOnChange = jest.fn()
210
+ const mockSetInternalValue = jest.fn()
211
+
212
+ const handlePresetSelect = (presetColor, disabled, id, onChange, setInternalValue) => {
213
+ if (disabled) return
214
+
215
+ setInternalValue(presetColor)
216
+
217
+ if (onChange) {
218
+ onChange(id, presetColor)
219
+ }
220
+ }
221
+
222
+ // Normal preset selection
223
+ handlePresetSelect('#FF0000', false, 'color1', mockOnChange, mockSetInternalValue)
224
+ expect(mockSetInternalValue).toHaveBeenCalledWith('#FF0000')
225
+ expect(mockOnChange).toHaveBeenCalledWith('color1', '#FF0000')
226
+
227
+ mockOnChange.mockClear()
228
+ mockSetInternalValue.mockClear()
229
+
230
+ // Disabled preset selection
231
+ handlePresetSelect('#FF0000', true, 'color1', mockOnChange, mockSetInternalValue)
232
+ expect(mockSetInternalValue).not.toHaveBeenCalled()
233
+ expect(mockOnChange).not.toHaveBeenCalled()
234
+ })
235
+
236
+ test('generates CSS classes correctly', () => {
237
+ const generateClasses = (size, variant, disabled, required, isFocused, error, isValid, showPreview, className) => {
238
+ return [
239
+ 'color-field',
240
+ `color-field--${size}`,
241
+ `color-field--${variant}`,
242
+ disabled && 'color-field--disabled',
243
+ required && 'color-field--required',
244
+ isFocused && 'color-field--focused',
245
+ error && 'color-field--error',
246
+ !isValid && 'color-field--invalid',
247
+ showPreview && 'color-field--with-preview',
248
+ className
249
+ ].filter(Boolean).join(' ')
250
+ }
251
+
252
+ expect(generateClasses('medium', 'default', false, false, false, null, true, true, ''))
253
+ .toBe('color-field color-field--medium color-field--default color-field--with-preview')
254
+
255
+ expect(generateClasses('large', 'outlined', true, true, true, 'Error message', false, false, 'custom'))
256
+ .toBe('color-field color-field--large color-field--outlined color-field--disabled color-field--required color-field--focused color-field--error color-field--invalid custom')
257
+ })
7
258
  })
8
259
 
260
+ // ColorUtils Tests
261
+ describe('ColorUtils', () => {
262
+ test('hexToRgb converts correctly', () => {
263
+ expect(ColorUtils.hexToRgb('#FF0000')).toEqual({ r: 255, g: 0, b: 0 })
264
+ expect(ColorUtils.hexToRgb('#00FF00')).toEqual({ r: 0, g: 255, b: 0 })
265
+ expect(ColorUtils.hexToRgb('#0000FF')).toEqual({ r: 0, g: 0, b: 255 })
266
+ expect(ColorUtils.hexToRgb('#FFFFFF')).toEqual({ r: 255, g: 255, b: 255 })
267
+ expect(ColorUtils.hexToRgb('#000000')).toEqual({ r: 0, g: 0, b: 0 })
268
+ expect(ColorUtils.hexToRgb('invalid')).toBeNull()
269
+ })
270
+
271
+ test('rgbToHex converts correctly', () => {
272
+ expect(ColorUtils.rgbToHex(255, 0, 0)).toBe('#ff0000')
273
+ expect(ColorUtils.rgbToHex(0, 255, 0)).toBe('#00ff00')
274
+ expect(ColorUtils.rgbToHex(0, 0, 255)).toBe('#0000ff')
275
+ expect(ColorUtils.rgbToHex(255, 255, 255)).toBe('#ffffff')
276
+ expect(ColorUtils.rgbToHex(0, 0, 0)).toBe('#000000')
277
+ })
278
+
279
+ test('isLight determines brightness correctly', () => {
280
+ expect(ColorUtils.isLight('#FFFFFF')).toBe(true)
281
+ expect(ColorUtils.isLight('#FFFF00')).toBe(true)
282
+ expect(ColorUtils.isLight('#000000')).toBe(false)
283
+ expect(ColorUtils.isLight('#FF0000')).toBe(false)
284
+ expect(ColorUtils.isLight('invalid')).toBe(false)
285
+ })
286
+
287
+ test('getContrastRatio calculates correctly', () => {
288
+ const ratio1 = ColorUtils.getContrastRatio('#FFFFFF', '#000000')
289
+ expect(ratio1).toBeGreaterThan(20) // High contrast
290
+
291
+ const ratio2 = ColorUtils.getContrastRatio('#FFFFFF', '#FFFFFF')
292
+ expect(ratio2).toBe(1) // Same color
293
+
294
+ const ratio3 = ColorUtils.getContrastRatio('#FF0000', '#00FF00')
295
+ expect(ratio3).toBeGreaterThan(1) // Some contrast
296
+ })
297
+
298
+ test('generatePalette creates color variations', () => {
299
+ const palette = ColorUtils.generatePalette('#FF0000', 3)
300
+ expect(palette).toHaveLength(3)
301
+ expect(palette.every(color => typeof color === 'string')).toBe(true)
302
+ expect(palette.every(color => color.startsWith('#'))).toBe(true)
303
+
304
+ const emptyPalette = ColorUtils.generatePalette('invalid', 3)
305
+ expect(emptyPalette).toEqual([])
306
+ })
307
+ })
308
+
309
+ // ColorPicker Component Tests
310
+ describe('ColorPicker Component', () => {
311
+ test('component has correct PropTypes', () => {
312
+ expect(ColorPicker.propTypes).toBeDefined()
313
+ expect(ColorPicker.propTypes.value).toBeDefined()
314
+ expect(ColorPicker.propTypes.onChange).toBeDefined()
315
+ expect(ColorPicker.propTypes.presetColors).toBeDefined()
316
+ expect(ColorPicker.propTypes.disabled).toBeDefined()
317
+ expect(ColorPicker.propTypes.className).toBeDefined()
318
+ })
319
+
320
+ test('handles color selection correctly', () => {
321
+ const mockOnChange = jest.fn()
322
+ const mockSetIsOpen = jest.fn()
323
+
324
+ const handleColorSelect = (color, onChange, setIsOpen) => {
325
+ if (onChange) onChange(color)
326
+ setIsOpen(false)
327
+ }
328
+
329
+ handleColorSelect('#FF0000', mockOnChange, mockSetIsOpen)
330
+ expect(mockOnChange).toHaveBeenCalledWith('#FF0000')
331
+ expect(mockSetIsOpen).toHaveBeenCalledWith(false)
332
+
333
+ mockOnChange.mockClear()
334
+
335
+ // No onChange callback
336
+ handleColorSelect('#FF0000', null, mockSetIsOpen)
337
+ expect(mockOnChange).not.toHaveBeenCalled()
338
+ expect(mockSetIsOpen).toHaveBeenCalledWith(false)
339
+ })
340
+
341
+ test('handles toggle correctly', () => {
342
+ const mockSetIsOpen = jest.fn()
343
+
344
+ const handleToggle = (isOpen, setIsOpen) => {
345
+ setIsOpen(!isOpen)
346
+ }
347
+
348
+ // Open picker
349
+ handleToggle(false, mockSetIsOpen)
350
+ expect(mockSetIsOpen).toHaveBeenCalledWith(true)
351
+
352
+ mockSetIsOpen.mockClear()
353
+
354
+ // Close picker
355
+ handleToggle(true, mockSetIsOpen)
356
+ expect(mockSetIsOpen).toHaveBeenCalledWith(false)
357
+ })
358
+ })
359
+ })
360
+
361
+ // Original test component (maintaining compatibility)
362
+ const ColorFieldTest = (prop) => {
363
+ const [form, setForm] = useState({})
364
+
9
365
  function change(id, value) {
10
366
  const next = Object.assign({}, form, { [id] : value })
11
367
  setForm(next)
@@ -16,4 +372,6 @@ const ColorFieldTest = (prop) => {
16
372
  <ColorField id="color1" onChange={change} value={form.color1} />
17
373
  </>
18
374
  )
19
- }
375
+ }
376
+
377
+ export default ColorFieldTest