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
@@ -0,0 +1,316 @@
1
+ import React, { useState } from 'react'
2
+ import { CheckBox } from './checkbox'
3
+
4
+ /**
5
+ * Ejemplos de uso del componente CheckBox mejorado
6
+ */
7
+ export const CheckBoxExamples = () => {
8
+ const [formData, setFormData] = useState({
9
+ terms: false,
10
+ newsletter: true,
11
+ notifications: false,
12
+ privacy: false,
13
+ marketing: false,
14
+ analytics: true
15
+ })
16
+
17
+ const [validationErrors, setValidationErrors] = useState({})
18
+
19
+ const handleChange = (id, value) => {
20
+ setFormData(prev => ({ ...prev, [id]: value }))
21
+
22
+ // Limpiar errores cuando el usuario interactúa
23
+ if (validationErrors[id]) {
24
+ setValidationErrors(prev => ({ ...prev, [id]: null }))
25
+ }
26
+ }
27
+
28
+ const validateForm = () => {
29
+ const errors = {}
30
+
31
+ if (!formData.terms) {
32
+ errors.terms = 'Debes aceptar los términos y condiciones'
33
+ }
34
+
35
+ if (!formData.privacy) {
36
+ errors.privacy = 'Debes aceptar la política de privacidad'
37
+ }
38
+
39
+ setValidationErrors(errors)
40
+ return Object.keys(errors).length === 0
41
+ }
42
+
43
+ const handleSubmit = () => {
44
+ if (validateForm()) {
45
+ alert('Formulario válido: ' + JSON.stringify(formData, null, 2))
46
+ }
47
+ }
48
+
49
+ return (
50
+ <div style={{ padding: '2rem', maxWidth: '800px' }}>
51
+ <h1>Ejemplos del Componente CheckBox Mejorado</h1>
52
+
53
+ <div style={{
54
+ background: '#f8f9fa',
55
+ padding: '1rem',
56
+ borderRadius: '8px',
57
+ marginBottom: '2rem',
58
+ border: '1px solid #e9ecef'
59
+ }}>
60
+ <h3>✅ Mejoras Implementadas:</h3>
61
+ <ul>
62
+ <li>🛡️ <strong>Validación de props</strong> - ID requerido con advertencias</li>
63
+ <li>♿ <strong>Accesibilidad completa</strong> - ARIA, soporte de teclado, focus</li>
64
+ <li>📝 <strong>PropTypes y documentación</strong> - Validación y documentación completa</li>
65
+ <li>🎯 <strong>Estados avanzados</strong> - disabled, error, indeterminate</li>
66
+ <li>🎨 <strong>CSS mejorado</strong> - Estados visuales consistentes</li>
67
+ <li>⌨️ <strong>Soporte de teclado</strong> - Espacio para alternar</li>
68
+ <li>🔧 <strong>Manejo de errores</strong> - Mensajes de error integrados</li>
69
+ <li>🧪 <strong>Pruebas unitarias</strong> - 13 pruebas que cubren toda la funcionalidad</li>
70
+ </ul>
71
+ </div>
72
+
73
+ {/* Checkboxes básicos */}
74
+ <section style={{ marginBottom: '2rem' }}>
75
+ <h3>Checkboxes Básicos</h3>
76
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
77
+ <CheckBox
78
+ id="basic1"
79
+ label="Opción básica sin estado inicial"
80
+ onChange={handleChange}
81
+ />
82
+ <CheckBox
83
+ id="basic2"
84
+ label="Opción básica marcada por defecto"
85
+ value={true}
86
+ onChange={handleChange}
87
+ />
88
+ <CheckBox
89
+ id="basic3"
90
+ label="Opción con etiqueta ARIA personalizada"
91
+ ariaLabel="Configuración especial de accesibilidad"
92
+ onChange={handleChange}
93
+ />
94
+ </div>
95
+ </section>
96
+
97
+ {/* Estados especiales */}
98
+ <section style={{ marginBottom: '2rem' }}>
99
+ <h3>Estados Especiales</h3>
100
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
101
+ <CheckBox
102
+ id="readonly"
103
+ label="Solo lectura (marcado)"
104
+ value={true}
105
+ readOnly={true}
106
+ onChange={handleChange}
107
+ />
108
+ <CheckBox
109
+ id="disabled"
110
+ label="Deshabilitado"
111
+ disabled={true}
112
+ onChange={handleChange}
113
+ />
114
+ <CheckBox
115
+ id="indeterminate"
116
+ label="Estado indeterminado"
117
+ indeterminate={true}
118
+ onChange={handleChange}
119
+ />
120
+ </div>
121
+ </section>
122
+
123
+ {/* Formulario con validación */}
124
+ <section style={{ marginBottom: '2rem' }}>
125
+ <h3>Formulario con Validación</h3>
126
+ <div style={{
127
+ background: '#fff',
128
+ padding: '1.5rem',
129
+ borderRadius: '8px',
130
+ border: '1px solid #ddd'
131
+ }}>
132
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
133
+ <CheckBox
134
+ id="terms"
135
+ label="Acepto los términos y condiciones"
136
+ value={formData.terms}
137
+ required={true}
138
+ error={validationErrors.terms}
139
+ onChange={handleChange}
140
+ />
141
+
142
+ <CheckBox
143
+ id="privacy"
144
+ label="Acepto la política de privacidad"
145
+ value={formData.privacy}
146
+ required={true}
147
+ error={validationErrors.privacy}
148
+ onChange={handleChange}
149
+ />
150
+
151
+ <CheckBox
152
+ id="newsletter"
153
+ label="Quiero recibir el newsletter"
154
+ value={formData.newsletter}
155
+ onChange={handleChange}
156
+ />
157
+
158
+ <CheckBox
159
+ id="notifications"
160
+ label="Activar notificaciones push"
161
+ value={formData.notifications}
162
+ onChange={handleChange}
163
+ />
164
+
165
+ <CheckBox
166
+ id="marketing"
167
+ label="Recibir comunicaciones de marketing"
168
+ value={formData.marketing}
169
+ onChange={handleChange}
170
+ />
171
+
172
+ <CheckBox
173
+ id="analytics"
174
+ label="Permitir análisis de uso"
175
+ value={formData.analytics}
176
+ onChange={handleChange}
177
+ />
178
+ </div>
179
+
180
+ <div style={{ marginTop: '1.5rem', display: 'flex', gap: '1rem' }}>
181
+ <button
182
+ onClick={handleSubmit}
183
+ style={{
184
+ padding: '0.5rem 1rem',
185
+ backgroundColor: '#007bff',
186
+ color: 'white',
187
+ border: 'none',
188
+ borderRadius: '4px',
189
+ cursor: 'pointer'
190
+ }}
191
+ >
192
+ Validar Formulario
193
+ </button>
194
+ <button
195
+ onClick={() => {
196
+ setFormData({
197
+ terms: false,
198
+ newsletter: true,
199
+ notifications: false,
200
+ privacy: false,
201
+ marketing: false,
202
+ analytics: true
203
+ })
204
+ setValidationErrors({})
205
+ }}
206
+ style={{
207
+ padding: '0.5rem 1rem',
208
+ backgroundColor: '#6c757d',
209
+ color: 'white',
210
+ border: 'none',
211
+ borderRadius: '4px',
212
+ cursor: 'pointer'
213
+ }}
214
+ >
215
+ Resetear
216
+ </button>
217
+ </div>
218
+ </div>
219
+ </section>
220
+
221
+ {/* Demostración de accesibilidad */}
222
+ <section style={{ marginBottom: '2rem' }}>
223
+ <h3>Demostración de Accesibilidad</h3>
224
+ <div style={{
225
+ background: '#e8f5e8',
226
+ padding: '1rem',
227
+ borderRadius: '4px',
228
+ border: '1px solid #c8e6c9'
229
+ }}>
230
+ <p><strong>Prueba la accesibilidad:</strong></p>
231
+ <ol>
232
+ <li>Usa <kbd>Tab</kbd> para navegar entre checkboxes</li>
233
+ <li>Usa <kbd>Espacio</kbd> para alternar el estado</li>
234
+ <li>Observa los indicadores de focus</li>
235
+ <li>Los lectores de pantalla anunciarán el estado y etiquetas</li>
236
+ </ol>
237
+
238
+ <div style={{ marginTop: '1rem', display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
239
+ <CheckBox
240
+ id="a11y1"
241
+ label="Checkbox accesible 1"
242
+ onChange={handleChange}
243
+ />
244
+ <CheckBox
245
+ id="a11y2"
246
+ label="Checkbox accesible 2"
247
+ onChange={handleChange}
248
+ />
249
+ <CheckBox
250
+ id="a11y3"
251
+ label="Checkbox accesible 3"
252
+ onChange={handleChange}
253
+ />
254
+ </div>
255
+ </div>
256
+ </section>
257
+
258
+ {/* Comparación antes/después */}
259
+ <section>
260
+ <h3>Comparación: Antes vs Después</h3>
261
+ <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '1rem' }}>
262
+ <div style={{
263
+ background: '#ffebee',
264
+ padding: '1rem',
265
+ borderRadius: '4px',
266
+ border: '1px solid #ffcdd2'
267
+ }}>
268
+ <h4>❌ Antes</h4>
269
+ <ul>
270
+ <li>Sin validación de props</li>
271
+ <li>Sin accesibilidad</li>
272
+ <li>Solo estados básicos</li>
273
+ <li>Sin soporte de teclado</li>
274
+ <li>Sin manejo de errores</li>
275
+ <li>Key problemático</li>
276
+ <li>Sin documentación</li>
277
+ </ul>
278
+ </div>
279
+ <div style={{
280
+ background: '#e8f5e8',
281
+ padding: '1rem',
282
+ borderRadius: '4px',
283
+ border: '1px solid #c8e6c9'
284
+ }}>
285
+ <h4>✅ Después</h4>
286
+ <ul>
287
+ <li>PropTypes completos</li>
288
+ <li>Accesibilidad total</li>
289
+ <li>Estados avanzados</li>
290
+ <li>Soporte completo de teclado</li>
291
+ <li>Manejo integrado de errores</li>
292
+ <li>Implementación limpia</li>
293
+ <li>Documentación y ejemplos</li>
294
+ </ul>
295
+ </div>
296
+ </div>
297
+ </section>
298
+
299
+ {/* Estado actual del formulario */}
300
+ <section style={{ marginTop: '2rem' }}>
301
+ <h3>Estado Actual del Formulario</h3>
302
+ <pre style={{
303
+ background: '#f8f9fa',
304
+ padding: '1rem',
305
+ borderRadius: '4px',
306
+ fontSize: '0.9rem',
307
+ overflow: 'auto'
308
+ }}>
309
+ {JSON.stringify(formData, null, 2)}
310
+ </pre>
311
+ </section>
312
+ </div>
313
+ )
314
+ }
315
+
316
+ export default CheckBoxExamples
@@ -1,57 +1,144 @@
1
- import React, { useEffect } from 'react'
1
+ import React, { useEffect, useRef } from 'react'
2
+ import PropTypes from 'prop-types'
2
3
  import { Text } from './text'
3
4
  import './checkbox.css'
4
5
 
5
6
  /**
6
- * CheckBox
7
+ * CheckBox component for boolean input with custom styling and accessibility
7
8
  */
8
9
  export const CheckBox = (props) => {
9
10
 
10
- const { id, label, value = false, readOnly = false, onChange } = props
11
+ const {
12
+ id,
13
+ label,
14
+ value = false,
15
+ readOnly = false,
16
+ disabled = false,
17
+ indeterminate = false,
18
+ error = false,
19
+ required = false,
20
+ className,
21
+ ariaLabel,
22
+ onChange
23
+ } = props
11
24
 
12
25
  const [checked, setChecked] = React.useState(value)
26
+ const inputRef = useRef(null)
27
+
28
+ // Validate required props
29
+ if (!id) {
30
+ console.warn('CheckBox component: id prop is required')
31
+ return null
32
+ }
13
33
 
14
34
  useEffect(() => {
15
35
  setChecked(value)
16
36
  }, [value])
17
37
 
38
+ // Handle indeterminate state
39
+ useEffect(() => {
40
+ if (inputRef.current) {
41
+ inputRef.current.indeterminate = indeterminate
42
+ }
43
+ }, [indeterminate])
44
+
18
45
  function change(event) {
19
46
  event.stopPropagation()
20
47
  const nextValue = event.target.checked
21
48
  setChecked(nextValue)
22
- if (onChange) onChange(id, nextValue)
49
+ if (onChange && !readOnly && !disabled) {
50
+ onChange(id, nextValue)
51
+ }
52
+ }
53
+
54
+ // Handle keyboard events for accessibility
55
+ const handleKeyDown = (event) => {
56
+ if (event.key === ' ') {
57
+ event.preventDefault()
58
+ if (!readOnly && !disabled) {
59
+ const nextValue = !checked
60
+ setChecked(nextValue)
61
+ if (onChange) onChange(id, nextValue)
62
+ }
63
+ }
23
64
  }
24
65
 
25
66
  const labelTxt = label && <Text>{label}</Text>
67
+ const isDisabled = readOnly || disabled
68
+ const safeClassName = className || ''
69
+
70
+ // Generate CSS classes
71
+ const cssClasses = [
72
+ 'checkbox',
73
+ readOnly && 'readonly',
74
+ disabled && 'disabled',
75
+ error && 'error',
76
+ safeClassName
77
+ ].filter(Boolean).join(' ')
78
+
79
+ // Accessibility attributes
80
+ const ariaAttributes = {
81
+ 'aria-label': ariaLabel || label,
82
+ 'aria-required': required,
83
+ 'aria-invalid': error,
84
+ 'aria-describedby': error ? `${id}-error` : undefined
85
+ }
26
86
 
27
87
  return (
28
- <div className={`checkbox ${readOnly ? "readonly" : ""}`} key={`${id}1`}>
29
- <input id={id} key={`${id}_${checked}`} type="checkbox" checked={checked} onChange={change} disabled={readOnly} />
88
+ <div className={cssClasses} onKeyDown={handleKeyDown} tabIndex={isDisabled ? -1 : 0}>
89
+ <input
90
+ ref={inputRef}
91
+ id={id}
92
+ type="checkbox"
93
+ checked={checked}
94
+ onChange={change}
95
+ disabled={isDisabled}
96
+ required={required}
97
+ {...ariaAttributes}
98
+ />
30
99
  <span className="checkmark" />
31
100
  <label htmlFor={id}>{labelTxt}</label>
101
+ {error && typeof error === 'string' && error.length > 0 && (
102
+ <span id={`${id}-error`} className="error-message" role="alert">
103
+ {error}
104
+ </span>
105
+ )}
32
106
  </div>
33
107
  )
34
108
  }
35
109
 
36
- const CheckBoxTest = (props) => {
37
-
38
- const [checked, setChecked] = React.useState({
39
- check1: true,
40
- check2: false,
41
- check3: true,
42
- check4: false
43
- })
44
-
45
- function change(id, value) {
46
- setChecked({ ...checked, [id]: value })
47
- }
110
+ // PropTypes para validación y documentación
111
+ CheckBox.propTypes = {
112
+ /** Unique identifier for the checkbox (required) */
113
+ id: PropTypes.string.isRequired,
114
+ /** Label text for the checkbox */
115
+ label: PropTypes.string,
116
+ /** Current checked state */
117
+ value: PropTypes.bool,
118
+ /** Whether the checkbox is read-only */
119
+ readOnly: PropTypes.bool,
120
+ /** Whether the checkbox is disabled */
121
+ disabled: PropTypes.bool,
122
+ /** Whether the checkbox is in indeterminate state */
123
+ indeterminate: PropTypes.bool,
124
+ /** Error state - boolean or error message string */
125
+ error: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
126
+ /** Whether the checkbox is required */
127
+ required: PropTypes.bool,
128
+ /** Additional CSS classes */
129
+ className: PropTypes.string,
130
+ /** Accessibility label for screen readers */
131
+ ariaLabel: PropTypes.string,
132
+ /** Change handler function */
133
+ onChange: PropTypes.func
134
+ }
48
135
 
49
- return (
50
- <div>
51
- <CheckBox id="check1" label="Check 1" value={checked.check1} onChange={change} />
52
- <CheckBox id="check2" label="Check 2" value={checked.check2} onChange={change} />
53
- <CheckBox id="check3" label="Check 3" value={checked.check3} onChange={change} readOnly/>
54
- <CheckBox id="check4" label="Check 4" value={checked.check4} onChange={change} readOnly/>
55
- </div>
56
- )
136
+ CheckBox.defaultProps = {
137
+ value: false,
138
+ readOnly: false,
139
+ disabled: false,
140
+ indeterminate: false,
141
+ error: false,
142
+ required: false,
143
+ className: ''
57
144
  }