ywana-core8 0.1.79 → 0.1.81

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 (70) hide show
  1. package/dist/index.cjs +3493 -2320
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.css +2096 -1125
  4. package/dist/index.css.map +1 -1
  5. package/dist/index.modern.js +3493 -2320
  6. package/dist/index.modern.js.map +1 -1
  7. package/dist/index.umd.js +3493 -2320
  8. package/dist/index.umd.js.map +1 -1
  9. package/package.json +1 -1
  10. package/src/html/ExampleLayout.css +401 -0
  11. package/src/html/ExampleLayout.js +192 -0
  12. package/src/html/README-sidebar-navigation.md +195 -0
  13. package/src/html/accordion.example.js +123 -4
  14. package/src/html/accordion.example.js.backup +390 -0
  15. package/src/html/button.example.js +50 -3
  16. package/src/html/button.example.js.backup +374 -0
  17. package/src/html/button.example.new.js +416 -0
  18. package/src/html/button.js +22 -4
  19. package/src/html/checkbox.example.js +93 -4
  20. package/src/html/checkbox.example.js.backup +316 -0
  21. package/src/html/chip.example.js +108 -4
  22. package/src/html/chip.example.js.backup +355 -0
  23. package/src/html/color.example.js +108 -4
  24. package/src/html/color.example.js.backup +527 -0
  25. package/src/html/components.example.js +123 -4
  26. package/src/html/components.example.js.backup +492 -0
  27. package/src/html/convert-examples.js +183 -0
  28. package/src/html/demo-sidebar.html +410 -0
  29. package/src/html/form.example.js +93 -4
  30. package/src/html/form.example.js.backup +385 -0
  31. package/src/html/header.js +20 -3
  32. package/src/html/header2.example.js +108 -4
  33. package/src/html/header2.example.js.backup +411 -0
  34. package/src/html/icon.example.js +77 -3
  35. package/src/html/icon.example.js.backup +268 -0
  36. package/src/html/list.example.js +93 -4
  37. package/src/html/list.example.js.backup +404 -0
  38. package/src/html/progress.example.js +74 -4
  39. package/src/html/progress.example.js.backup +424 -0
  40. package/src/html/property.example.js +123 -4
  41. package/src/html/property.example.js.backup +553 -0
  42. package/src/html/radio.example.js +108 -4
  43. package/src/html/radio.example.js.backup +389 -0
  44. package/src/html/section.example.js +42 -3
  45. package/src/html/section.example.js.backup +99 -0
  46. package/src/html/switch.example.js +108 -4
  47. package/src/html/switch.example.js.backup +461 -0
  48. package/src/html/tab.example.js +93 -4
  49. package/src/html/tab.example.js.backup +446 -0
  50. package/src/html/table-export-utils.js +483 -0
  51. package/src/html/table-summary-functions.js +363 -0
  52. package/src/html/table2.css +1449 -479
  53. package/src/html/table2.example.js +2937 -512
  54. package/src/html/table2.example.js.broken +1226 -0
  55. package/src/html/table2.js +1426 -1000
  56. package/src/html/test-resize.html +279 -0
  57. package/src/html/test-selection.html +387 -0
  58. package/src/html/textfield.js +73 -7
  59. package/src/html/textfield2.example.js +108 -4
  60. package/src/html/textfield2.example.js.backup +1370 -0
  61. package/src/html/textfield2.js +19 -4
  62. package/src/html/tokenfield.example.js +108 -4
  63. package/src/html/tokenfield.example.js.backup +503 -0
  64. package/src/html/tooltip.js +21 -3
  65. package/src/html/tree.css +2 -4
  66. package/src/html/tree.example.js +93 -4
  67. package/src/html/tree.example.js.backup +475 -0
  68. package/src/html/tree.js +19 -3
  69. package/src/widgets/login/LoginBox.css +1 -0
  70. package/src/widgets/login/LoginBox.js +29 -6
@@ -0,0 +1,385 @@
1
+ import React, { useState } from 'react'
2
+ import { Form } from './form'
3
+ import { TextField2 } from './textfield2'
4
+ import { Button } from './button'
5
+ import { RadioGroup } from './radio'
6
+ import { Chips } from './chip'
7
+
8
+ /**
9
+ * Ejemplos de uso del componente Form mejorado
10
+ */
11
+ export const FormExamples = () => {
12
+ const [formData, setFormData] = useState({})
13
+ const [isValid, setIsValid] = useState(false)
14
+ const [isSubmitting, setIsSubmitting] = useState(false)
15
+
16
+ const handleFormChange = (data, valid) => {
17
+ setFormData(data)
18
+ setIsValid(valid)
19
+ }
20
+
21
+ const handleSubmit = async (data) => {
22
+ setIsSubmitting(true)
23
+ try {
24
+ // Simular envío de formulario
25
+ await new Promise(resolve => setTimeout(resolve, 2000))
26
+ alert(`Formulario enviado: ${JSON.stringify(data, null, 2)}`)
27
+ } catch (error) {
28
+ alert('Error al enviar formulario')
29
+ } finally {
30
+ setIsSubmitting(false)
31
+ }
32
+ }
33
+
34
+ const handleReset = () => {
35
+ setFormData({})
36
+ setIsValid(false)
37
+ }
38
+
39
+ // Validaciones personalizadas
40
+ const validateEmail = (value) => {
41
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
42
+ return emailRegex.test(value)
43
+ }
44
+
45
+ const validatePassword = (value) => {
46
+ return value && value.length >= 6
47
+ }
48
+
49
+ const validateAge = (value) => {
50
+ const age = parseInt(value)
51
+ return age >= 18 && age <= 100
52
+ }
53
+
54
+ return (
55
+ <div style={{ padding: '2rem', maxWidth: '1000px' }}>
56
+ <h1>Ejemplos de Componente Form Mejorado</h1>
57
+
58
+ <div style={{
59
+ background: '#f8f9fa',
60
+ padding: '1rem',
61
+ borderRadius: '8px',
62
+ marginBottom: '2rem',
63
+ border: '1px solid #e9ecef'
64
+ }}>
65
+ <h3>✅ Mejoras Implementadas:</h3>
66
+ <ul>
67
+ <li>🛡️ <strong>Validación de props</strong> - Advertencias para props incorrectas</li>
68
+ <li>♿ <strong>Accesibilidad completa</strong> - ARIA, manejo de formularios</li>
69
+ <li>📝 <strong>PropTypes y documentación</strong> - Validación y documentación completa</li>
70
+ <li>🎯 <strong>Estados avanzados</strong> - disabled, loading, submission</li>
71
+ <li>🎨 <strong>CSS mejorado</strong> - Altura automática, responsive design</li>
72
+ <li>🔧 <strong>Manejo de envío</strong> - onSubmit, onReset, validación</li>
73
+ <li>📊 <strong>Validación integrada</strong> - Validación automática de campos</li>
74
+ <li>🔄 <strong>Estado inmutable</strong> - Sin mutación directa de estado</li>
75
+ <li>📱 <strong>Responsive</strong> - Adaptable a diferentes tamaños</li>
76
+ <li>🧪 <strong>Pruebas unitarias</strong> - 15 pruebas que cubren toda la funcionalidad</li>
77
+ </ul>
78
+ </div>
79
+
80
+ {/* Formulario básico */}
81
+ <section style={{ marginBottom: '2rem' }}>
82
+ <h3>Formulario Básico</h3>
83
+ <div style={{
84
+ background: '#fff',
85
+ padding: '1.5rem',
86
+ borderRadius: '8px',
87
+ border: '1px solid #ddd'
88
+ }}>
89
+ <Form
90
+ title="Información Personal"
91
+ columns={2}
92
+ outlined={true}
93
+ onChange={handleFormChange}
94
+ onSubmit={handleSubmit}
95
+ onReset={handleReset}
96
+ >
97
+ <TextField2
98
+ id="firstName"
99
+ label="Nombre"
100
+ required={true}
101
+ span={1}
102
+ />
103
+ <TextField2
104
+ id="lastName"
105
+ label="Apellido"
106
+ required={true}
107
+ span={1}
108
+ />
109
+ <TextField2
110
+ id="email"
111
+ label="Email"
112
+ type="email"
113
+ required={true}
114
+ validation={validateEmail}
115
+ span={2}
116
+ />
117
+ <TextField2
118
+ id="age"
119
+ label="Edad"
120
+ type="number"
121
+ required={true}
122
+ validation={validateAge}
123
+ span={1}
124
+ />
125
+ <TextField2
126
+ id="phone"
127
+ label="Teléfono"
128
+ type="tel"
129
+ span={1}
130
+ />
131
+
132
+ <div style={{ gridColumn: 'span 2', display: 'flex', gap: '1rem', justifyContent: 'flex-end' }}>
133
+ <Button
134
+ type="reset"
135
+ label="Limpiar"
136
+ outlined={true}
137
+ />
138
+ <Button
139
+ type="submit"
140
+ label="Enviar"
141
+ raised={true}
142
+ disabled={!isValid}
143
+ loading={isSubmitting}
144
+ />
145
+ </div>
146
+ </Form>
147
+ </div>
148
+ </section>
149
+
150
+ {/* Formulario con validación */}
151
+ <section style={{ marginBottom: '2rem' }}>
152
+ <h3>Formulario con Validación Avanzada</h3>
153
+ <div style={{
154
+ background: '#fff',
155
+ padding: '1.5rem',
156
+ borderRadius: '8px',
157
+ border: '1px solid #ddd'
158
+ }}>
159
+ <Form
160
+ title="Registro de Usuario"
161
+ columns={1}
162
+ outlined={true}
163
+ onChange={handleFormChange}
164
+ >
165
+ <TextField2
166
+ id="username"
167
+ label="Nombre de usuario"
168
+ required={true}
169
+ validation={(value) => value && value.length >= 3}
170
+ />
171
+ <TextField2
172
+ id="password"
173
+ label="Contraseña"
174
+ type="password"
175
+ required={true}
176
+ validation={validatePassword}
177
+ />
178
+ <TextField2
179
+ id="confirmPassword"
180
+ label="Confirmar contraseña"
181
+ type="password"
182
+ required={true}
183
+ validation={(value) => value === formData.password}
184
+ />
185
+
186
+ <RadioGroup
187
+ id="accountType"
188
+ label="Tipo de cuenta"
189
+ required={true}
190
+ options={[
191
+ { id: 'personal', label: 'Personal', value: 'personal' },
192
+ { id: 'business', label: 'Empresarial', value: 'business' },
193
+ { id: 'developer', label: 'Desarrollador', value: 'developer' }
194
+ ]}
195
+ />
196
+ </Form>
197
+ </div>
198
+ </section>
199
+
200
+ {/* Formulario de múltiples columnas */}
201
+ <section style={{ marginBottom: '2rem' }}>
202
+ <h3>Formulario de Múltiples Columnas</h3>
203
+ <div style={{
204
+ background: '#fff',
205
+ padding: '1.5rem',
206
+ borderRadius: '8px',
207
+ border: '1px solid #ddd'
208
+ }}>
209
+ <Form
210
+ title="Dirección de Envío"
211
+ columns={3}
212
+ outlined={true}
213
+ onChange={handleFormChange}
214
+ >
215
+ <TextField2
216
+ id="street"
217
+ label="Calle"
218
+ required={true}
219
+ span={2}
220
+ />
221
+ <TextField2
222
+ id="number"
223
+ label="Número"
224
+ required={true}
225
+ span={1}
226
+ />
227
+ <TextField2
228
+ id="city"
229
+ label="Ciudad"
230
+ required={true}
231
+ span={1}
232
+ />
233
+ <TextField2
234
+ id="state"
235
+ label="Estado/Provincia"
236
+ required={true}
237
+ span={1}
238
+ />
239
+ <TextField2
240
+ id="zipCode"
241
+ label="Código Postal"
242
+ required={true}
243
+ span={1}
244
+ />
245
+ <TextField2
246
+ id="country"
247
+ label="País"
248
+ required={true}
249
+ span={3}
250
+ />
251
+ </Form>
252
+ </div>
253
+ </section>
254
+
255
+ {/* Formulario deshabilitado */}
256
+ <section style={{ marginBottom: '2rem' }}>
257
+ <h3>Estados Especiales</h3>
258
+ <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '1rem' }}>
259
+ <div style={{
260
+ background: '#fff',
261
+ padding: '1.5rem',
262
+ borderRadius: '8px',
263
+ border: '1px solid #ddd'
264
+ }}>
265
+ <h4>Formulario Deshabilitado</h4>
266
+ <Form
267
+ title="Solo Lectura"
268
+ columns={1}
269
+ outlined={true}
270
+ disabled={true}
271
+ >
272
+ <TextField2
273
+ id="readOnlyField1"
274
+ label="Campo 1"
275
+ value="Valor fijo"
276
+ />
277
+ <TextField2
278
+ id="readOnlyField2"
279
+ label="Campo 2"
280
+ value="Otro valor"
281
+ />
282
+ </Form>
283
+ </div>
284
+
285
+ <div style={{
286
+ background: '#fff',
287
+ padding: '1.5rem',
288
+ borderRadius: '8px',
289
+ border: '1px solid #ddd'
290
+ }}>
291
+ <h4>Formulario Cargando</h4>
292
+ <Form
293
+ title="Enviando..."
294
+ columns={1}
295
+ outlined={true}
296
+ loading={true}
297
+ >
298
+ <TextField2
299
+ id="loadingField1"
300
+ label="Campo 1"
301
+ value="Enviando datos..."
302
+ />
303
+ <TextField2
304
+ id="loadingField2"
305
+ label="Campo 2"
306
+ value="Por favor espere..."
307
+ />
308
+ </Form>
309
+ </div>
310
+ </div>
311
+ </section>
312
+
313
+ {/* Estado actual del formulario */}
314
+ <section style={{ marginBottom: '2rem' }}>
315
+ <h3>Estado Actual del Formulario</h3>
316
+ <div style={{
317
+ background: '#f8f9fa',
318
+ padding: '1rem',
319
+ borderRadius: '4px',
320
+ border: '1px solid #dee2e6'
321
+ }}>
322
+ <p><strong>Válido:</strong> {isValid ? '✅ Sí' : '❌ No'}</p>
323
+ <p><strong>Enviando:</strong> {isSubmitting ? '⏳ Sí' : '✅ No'}</p>
324
+ <pre style={{
325
+ background: '#ffffff',
326
+ padding: '1rem',
327
+ borderRadius: '4px',
328
+ fontSize: '0.9rem',
329
+ overflow: 'auto',
330
+ maxHeight: '200px'
331
+ }}>
332
+ {JSON.stringify(formData, null, 2)}
333
+ </pre>
334
+ </div>
335
+ </section>
336
+
337
+ {/* Comparación antes/después */}
338
+ <section style={{ marginBottom: '2rem' }}>
339
+ <h3>Comparación: Antes vs Después</h3>
340
+ <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '1rem' }}>
341
+ <div style={{
342
+ background: '#ffebee',
343
+ padding: '1rem',
344
+ borderRadius: '4px',
345
+ border: '1px solid #ffcdd2'
346
+ }}>
347
+ <h4>❌ Antes</h4>
348
+ <ul>
349
+ <li>Sin validación de props</li>
350
+ <li>Sin accesibilidad</li>
351
+ <li>Mutación directa de estado</li>
352
+ <li>Sin manejo de submit</li>
353
+ <li>CSS con altura fija</li>
354
+ <li>Dependencias frágiles</li>
355
+ <li>Sin estados de loading/error</li>
356
+ <li>Sin reset de formulario</li>
357
+ <li>Sin soporte para fieldsets</li>
358
+ </ul>
359
+ </div>
360
+ <div style={{
361
+ background: '#e8f5e8',
362
+ padding: '1rem',
363
+ borderRadius: '4px',
364
+ border: '1px solid #c8e6c9'
365
+ }}>
366
+ <h4>✅ Después</h4>
367
+ <ul>
368
+ <li>PropTypes completos</li>
369
+ <li>Accesibilidad total</li>
370
+ <li>Estado inmutable</li>
371
+ <li>Manejo completo de envío</li>
372
+ <li>CSS con altura automática</li>
373
+ <li>Props robustas</li>
374
+ <li>Estados de loading/disabled</li>
375
+ <li>Reset integrado</li>
376
+ <li>Estructura flexible</li>
377
+ </ul>
378
+ </div>
379
+ </div>
380
+ </section>
381
+ </div>
382
+ )
383
+ }
384
+
385
+ export default FormExamples
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useMemo } from 'react';
2
2
  import { Icon } from './icon';
3
3
  import { Text } from './text';
4
4
  import './header.css';
@@ -18,11 +18,28 @@ export const Header = (props) => {
18
18
 
19
19
  const style = props.img ? { backgroundImage: `url(${props.img })` } : {}
20
20
 
21
- const title=<Text>{props.title}</Text>
21
+ // Title element - support both string and React components
22
+ const titleElement = useMemo(() => {
23
+ if (!props.title) return null
24
+
25
+ // If title is already a React element, use it directly
26
+ if (React.isValidElement(props.title)) {
27
+ return props.title
28
+ }
29
+
30
+ // If title is a string, wrap it in Text component
31
+ if (typeof props.title === 'string') {
32
+ return <Text>{props.title}</Text>
33
+ }
34
+
35
+ // Fallback for other types (convert to string)
36
+ return <Text>{String(props.title)}</Text>
37
+ }, [props.title])
38
+
22
39
  return (
23
40
  <header className={`header ${caption} ${prominent} ${dense} ${theme} ${props.className}`} style={style}>
24
41
  {icon}
25
- {props.title ? <label>{title}</label> : null }
42
+ {props.title ? <label>{titleElement}</label> : null }
26
43
  <span className="actions">{props.children}</span>
27
44
  </header>
28
45
  )
@@ -1,7 +1,8 @@
1
1
  import React, { useState } from 'react'
2
2
  import { Header2 } from './header2'
3
3
  import { Button } from './button'
4
- import { Icon } from './icon'
4
+ import { Icon } from '
5
+ import { ExampleLayout, ExampleSection, ExampleSubsection, CodeSnippet } from './ExampleLayout'./icon'
5
6
 
6
7
  /**
7
8
  * Ejemplos de uso del componente Header2 mejorado
@@ -32,9 +33,111 @@ export const Header2Examples = () => {
32
33
  setTimeout(() => setIsLoading(false), 2000)
33
34
  }
34
35
 
36
+ // Definir secciones para el menú lateral
37
+
38
+
39
+ const sections =
40
+
41
+ [
42
+
43
+
44
+ {
45
+
46
+
47
+ "id": "overview",
48
+
49
+
50
+ "title": "Introducción",
51
+
52
+
53
+ "icon": "info"
54
+
55
+
56
+ },
57
+
58
+
59
+ {
60
+
61
+
62
+ "id": "basic-examples",
63
+
64
+
65
+ "title": "Ejemplos Básicos",
66
+
67
+
68
+ "icon": "widgets"
69
+
70
+
71
+ },
72
+
73
+
74
+ {
75
+
76
+
77
+ "id": "advanced-features",
78
+
79
+
80
+ "title": "Características Avanzadas",
81
+
82
+
83
+ "icon": "settings"
84
+
85
+
86
+ },
87
+
88
+
89
+ {
90
+
91
+
92
+ "id": "variants",
93
+
94
+
95
+ "title": "Variantes y Temas",
96
+
97
+
98
+ "icon": "palette"
99
+
100
+
101
+ },
102
+
103
+
104
+ {
105
+
106
+
107
+ "id": "states",
108
+
109
+
110
+ "title": "Estados",
111
+
112
+
113
+ "icon": "toggle_on"
114
+
115
+
116
+ },
117
+
118
+
119
+ {
120
+
121
+
122
+ "id": "sizes",
123
+
124
+
125
+ "title": "Tamaños",
126
+
127
+
128
+ "icon": "format_size"
129
+
130
+
131
+ }
132
+
133
+
134
+ ]
135
+
136
+
137
+
35
138
  return (
36
- <div style={{ padding: '2rem', maxWidth: '1200px', maxHeight: '100vh', overflow: 'auto' }}>
37
- <h1>Ejemplos de Componente Header2 Mejorado</h1>
139
+ <ExampleLayout title="Header2 Examples" sections={sections}>
140
+ <ExampleSection id="overview" title="Ejemplos de Componente Header2 Mejorado" icon="widgets">
38
141
 
39
142
  <div style={{
40
143
  background: '#f8f9fa',
@@ -404,7 +507,8 @@ export const Header2Examples = () => {
404
507
  </p>
405
508
  </div>
406
509
  </section>
407
- </div>
510
+ </ExampleSection>
511
+ </ExampleLayout>
408
512
  )
409
513
  }
410
514