ywana-core8 0.1.83 → 0.1.85

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 (76) hide show
  1. package/__previewjs__/Wrapper.tsx +8 -5
  2. package/build-doc.sh +10 -0
  3. package/dist/index.cjs +627 -194
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.css +353 -105
  6. package/dist/index.css.map +1 -1
  7. package/dist/index.modern.js +628 -196
  8. package/dist/index.modern.js.map +1 -1
  9. package/dist/index.umd.js +629 -196
  10. package/dist/index.umd.js.map +1 -1
  11. package/doc/README.md +196 -0
  12. package/doc/craco.config.js +31 -0
  13. package/doc/generate-examples.cjs +310 -0
  14. package/doc/package-lock.json +17298 -0
  15. package/doc/package.json +33 -0
  16. package/doc/public/index.html +22 -0
  17. package/doc/src/App.css +171 -0
  18. package/doc/src/App.js +214 -0
  19. package/doc/src/components/ExamplePage.js +104 -0
  20. package/doc/src/components/WelcomePage.js +84 -0
  21. package/doc/src/examples/button.example.js +47 -0
  22. package/doc/src/examples/input.example.js +91 -0
  23. package/doc/src/index.css +237 -0
  24. package/doc/src/index.js +11 -0
  25. package/package.json +9 -2
  26. package/preview.config.js +38 -0
  27. package/src/html/accordion.example.js +2 -2
  28. package/src/html/actions-cell.css +108 -0
  29. package/src/html/actions-cell.example.js +587 -0
  30. package/src/html/actions-cell.js +260 -0
  31. package/src/html/checkbox.example.js +2 -2
  32. package/src/html/chip.example.js +2 -2
  33. package/src/html/color.example.js +2 -2
  34. package/src/html/form.example.js +2 -2
  35. package/src/html/header2.example.js +2 -2
  36. package/src/html/index.js +1 -0
  37. package/src/html/menu.css +9 -2
  38. package/src/html/menu.js +14 -2
  39. package/src/html/progress.example.js +2 -2
  40. package/src/html/property.example.js +2 -2
  41. package/src/html/radio.example.js +2 -2
  42. package/src/html/switch.example.js +2 -2
  43. package/src/html/tab.example.js +2 -2
  44. package/src/html/table.css +47 -1
  45. package/src/html/table.example.js +1012 -0
  46. package/src/html/table.js +12 -7
  47. package/src/html/table2-actions-test.js +138 -0
  48. package/src/html/table2.css +40 -3
  49. package/src/html/table2.example.js +330 -0
  50. package/src/html/table2.js +56 -13
  51. package/src/html/textfield.css +17 -4
  52. package/src/html/tokenfield.example.js +2 -2
  53. package/src/html/tree.css +42 -7
  54. package/src/html/tree.example.js +169 -7
  55. package/src/html/tree.js +216 -93
  56. package/src/widgets/calendar/Calendar.js +1 -1
  57. /package/{ACCORDION_EVALUATION.md → doc/evalulations/ACCORDION_EVALUATION.md} +0 -0
  58. /package/{CHECKBOX_EVALUATION.md → doc/evalulations/CHECKBOX_EVALUATION.md} +0 -0
  59. /package/{CHIP_EVALUATION.md → doc/evalulations/CHIP_EVALUATION.md} +0 -0
  60. /package/{COLOR_EVALUATION.md → doc/evalulations/COLOR_EVALUATION.md} +0 -0
  61. /package/{COMPONENTS_EVALUATION.md → doc/evalulations/COMPONENTS_EVALUATION.md} +0 -0
  62. /package/{FORM_EVALUATION.md → doc/evalulations/FORM_EVALUATION.md} +0 -0
  63. /package/{HEADER_EVALUATION.md → doc/evalulations/HEADER_EVALUATION.md} +0 -0
  64. /package/{ICON_EVALUATION.md → doc/evalulations/ICON_EVALUATION.md} +0 -0
  65. /package/{LIST_EVALUATION.md → doc/evalulations/LIST_EVALUATION.md} +0 -0
  66. /package/{PROGRESS_EVALUATION.md → doc/evalulations/PROGRESS_EVALUATION.md} +0 -0
  67. /package/{RADIO_EVALUATION.md → doc/evalulations/RADIO_EVALUATION.md} +0 -0
  68. /package/{RADIO_VISUAL_FIX.md → doc/evalulations/RADIO_VISUAL_FIX.md} +0 -0
  69. /package/{SECTION_IMPROVEMENTS.md → doc/evalulations/SECTION_IMPROVEMENTS.md} +0 -0
  70. /package/{SWITCH_EVALUATION.md → doc/evalulations/SWITCH_EVALUATION.md} +0 -0
  71. /package/{SWITCH_VISUAL_FIX.md → doc/evalulations/SWITCH_VISUAL_FIX.md} +0 -0
  72. /package/{TAB_EVALUATION.md → doc/evalulations/TAB_EVALUATION.md} +0 -0
  73. /package/{TEXTFIELD_EVALUATION.md → doc/evalulations/TEXTFIELD_EVALUATION.md} +0 -0
  74. /package/{TOOLTIP_FIX.md → doc/evalulations/TOOLTIP_FIX.md} +0 -0
  75. /package/{TREE_EVALUATION.md → doc/evalulations/TREE_EVALUATION.md} +0 -0
  76. /package/src/incubator/{PDFViewer.js → pdfViewer.js} +0 -0
@@ -156,7 +156,6 @@ export const DataTable2 = (props) => {
156
156
 
157
157
  // Handle tool selection
158
158
  const handleToolSelect = useCallback((toolId) => {
159
- console.log('handleToolSelect called with toolId:', toolId)
160
159
  setActiveTool(prev => {
161
160
  const newTool = prev === toolId ? null : toolId
162
161
  console.log('Tool changed from', prev, 'to', newTool)
@@ -173,13 +172,13 @@ export const DataTable2 = (props) => {
173
172
  const defaultTools = useMemo(() => [
174
173
  {
175
174
  id: 'columns',
176
- icon: 'person',
175
+ icon: 'view_column',
177
176
  title: 'Configurar columnas',
178
177
  component: ColumnsPanel
179
178
  },
180
179
  {
181
180
  id: 'export',
182
- icon: 'person',
181
+ icon: 'ios_share',
183
182
  title: 'Exportar datos',
184
183
  component: ExportPanel
185
184
  },
@@ -276,9 +275,13 @@ export const DataTable2 = (props) => {
276
275
  className
277
276
  ].filter(Boolean).join(' '), [size, density, theme, readability, striped, bordered, hover, loading, skeleton, className])
278
277
 
279
- // Check if any row has actions column
280
- const hasActionsColumn = useMemo(() =>
281
- rows.some(row => row.info) || filterable, [rows, filterable])
278
+ // Check if any row has actions column or if there's an actions column defined
279
+ const hasActionsColumn = useMemo(() => {
280
+ const hasActionsColumnDefined = columns.some(col => col.id === 'actions')
281
+ const hasRowsWithActions = rows.some(row => row.actions && Array.isArray(row.actions))
282
+ const hasRowsWithInfo = rows.some(row => row.info)
283
+ return hasActionsColumnDefined || hasRowsWithActions || hasRowsWithInfo || filterable
284
+ }, [columns, rows, filterable])
282
285
 
283
286
  // Función de ordenamiento (similar a table.js)
284
287
  const multiSort = useCallback((array, sortObject = {}) => {
@@ -782,8 +785,8 @@ const DataTableSummaryRow = ({ columns, rows, showRowNumbers, hasActionsColumn,
782
785
  )
783
786
  })}
784
787
 
785
- {/* Celda para acciones */}
786
- {hasActionsColumn && (
788
+ {/* Celda para acciones - solo cuando no hay columna actions definida */}
789
+ {hasActionsColumn && !columns.some(col => col.id === 'actions') && (
787
790
  <td className="datatable2__summary-cell datatable2__summary-cell--actions"></td>
788
791
  )}
789
792
  </tr>
@@ -1008,8 +1011,9 @@ const DataTableHeader = ({
1008
1011
  )
1009
1012
  })}
1010
1013
 
1011
- {hasActionsColumn && (
1012
- <th className="datatable2__actions-header">Actions</th>
1014
+ {/* Cabecera de acciones solo cuando no hay columna actions definida pero sí hay info o filterable */}
1015
+ {hasActionsColumn && !columns.some(col => col.id === 'actions') && (
1016
+ <th className="datatable2__actions-header"></th>
1013
1017
  )}
1014
1018
  </tr>
1015
1019
 
@@ -1299,6 +1303,42 @@ const DataTableRow = ({
1299
1303
  )
1300
1304
  }
1301
1305
 
1306
+ // Manejar columna "actions" de manera especial
1307
+ if (column.id === 'actions') {
1308
+ return (
1309
+ <td key={column.id} className="datatable2__actions-cell">
1310
+ {/* Renderizar componentes React del array actions */}
1311
+ {row.actions && Array.isArray(row.actions) && (
1312
+ <div className="datatable2__actions-container">
1313
+ {row.actions.map((action, index) => (
1314
+ <span key={index} className="datatable2__action-item">
1315
+ {action}
1316
+ </span>
1317
+ ))}
1318
+ </div>
1319
+ )}
1320
+
1321
+ {/* Icono de expansión para info (solo si no hay actions o si hay espacio) */}
1322
+ {row.info && (
1323
+ <Icon
1324
+ icon={isExpanded ? "expand_less" : "expand_more"}
1325
+ size="small"
1326
+ clickable
1327
+ action={() => {
1328
+ if (row.info && typeof row.info === 'object' && row.info.action) {
1329
+ row.info.action(row)
1330
+ }
1331
+ if (onRowExpand) {
1332
+ onRowExpand(row.id)
1333
+ }
1334
+ }}
1335
+ className="datatable2__expand-icon"
1336
+ />
1337
+ )}
1338
+ </td>
1339
+ )
1340
+ }
1341
+
1302
1342
  return (
1303
1343
  <DataTableCell
1304
1344
  key={column.id}
@@ -1314,8 +1354,10 @@ const DataTableRow = ({
1314
1354
  )
1315
1355
  })}
1316
1356
 
1317
- {hasActionsColumn && (
1357
+ {/* Celda de acciones adicional cuando no hay columna actions definida pero sí hay info o filterable */}
1358
+ {hasActionsColumn && !columns.some(col => col.id === 'actions') && (
1318
1359
  <td className="datatable2__actions-cell">
1360
+ {/* Icono de expansión para info */}
1319
1361
  {row.info && (
1320
1362
  <Icon
1321
1363
  icon={isExpanded ? "expand_less" : "expand_more"}
@@ -1329,6 +1371,7 @@ const DataTableRow = ({
1329
1371
  onRowExpand(row.id)
1330
1372
  }
1331
1373
  }}
1374
+ className="datatable2__expand-icon"
1332
1375
  />
1333
1376
  )}
1334
1377
  </td>
@@ -1513,8 +1556,8 @@ const DataTableFiltersRow = ({ columns, onClear, showRowNumbers, hasActionsColum
1513
1556
  </td>
1514
1557
  ))}
1515
1558
 
1516
- {/* Celda para acciones con botón de limpiar */}
1517
- {hasActionsColumn && (
1559
+ {/* Celda para acciones con botón de limpiar - solo cuando no hay columna actions definida */}
1560
+ {hasActionsColumn && !columns.some(col => col.id === 'actions') && (
1518
1561
  <td className="datatable2__filter-cell datatable2__filter-cell--actions">
1519
1562
  <Icon
1520
1563
  icon="close"
@@ -41,13 +41,18 @@
41
41
 
42
42
  .textfield>.icon {
43
43
  position: absolute;
44
- top: 1.5rem;
44
+ top: 50%;
45
45
  right: .2rem;
46
+ transform: translateY(-50%);
46
47
  color: rgba(150,150,150,1);
48
+ display: flex;
49
+ align-items: center;
50
+ justify-content: center;
47
51
  }
48
52
 
49
53
  .textfield-outlined.no-label > .icon {
50
- top: .5rem;
54
+ top: 50%;
55
+ transform: translateY(-50%);
51
56
  }
52
57
 
53
58
  .textfield-date>.icon,
@@ -147,8 +152,12 @@ input:read-only ~ label,
147
152
 
148
153
  .dropdown>.icon {
149
154
  position: absolute;
150
- top: 1.7rem;
155
+ top: 50%;
151
156
  right: .2rem;
157
+ transform: translateY(-50%);
158
+ display: flex;
159
+ align-items: center;
160
+ justify-content: center;
152
161
  }
153
162
 
154
163
  .dropdown>.decorator {
@@ -161,9 +170,13 @@ input:read-only ~ label,
161
170
  .dropdown>.textfield>.icon,
162
171
  .dropdown>.textfield-outlined>.icon {
163
172
  position: absolute;
164
- top: 1.7rem;
173
+ top: 50%;
165
174
  right: 2rem;
175
+ transform: translateY(-50%);
166
176
  color: rgba(150,150,150,1);
177
+ display: flex;
178
+ align-items: center;
179
+ justify-content: center;
167
180
  }
168
181
 
169
182
  .dropdown>menu {
@@ -1,8 +1,8 @@
1
1
  import React, { useState } from 'react'
2
2
  import { TokenField } from './tokenfield'
3
3
  import { Button } from './button'
4
- import { Text } from '
5
- import { ExampleLayout, ExampleSection, ExampleSubsection, CodeSnippet } from './ExampleLayout'./text'
4
+ import { Text } from './text'
5
+ import { ExampleLayout, ExampleSection, ExampleSubsection, CodeSnippet } from './ExampleLayout'
6
6
 
7
7
  /**
8
8
  * Ejemplos del componente TokenField mejorado manteniendo 100% compatibilidad
package/src/html/tree.css CHANGED
@@ -14,13 +14,16 @@
14
14
  align-items: center;
15
15
  font: 1rem;
16
16
  color: var(--text-color-light);
17
+ cursor: pointer;
18
+ width: 100%;
19
+ min-height: 2rem;
20
+ padding: 0.25rem 0;
17
21
  }
18
22
 
19
23
  .tree-item:hover {
20
- cursor: pointer;
21
24
  background-color: var(--background-color);
22
25
  font-weight: 500;
23
- }
26
+ }
24
27
 
25
28
  .tree-item.final {
26
29
  margin-left: 1rem;
@@ -35,6 +38,7 @@
35
38
 
36
39
  .tree-item>i {
37
40
  padding-left: .3rem;
41
+ pointer-events: none;
38
42
  }
39
43
 
40
44
  .tree-item>.label {
@@ -43,10 +47,10 @@
43
47
  display: flex;
44
48
  align-items: center;
45
49
  justify-content: space-between;
50
+ pointer-events: none;
46
51
  }
47
52
 
48
53
  .tree-item>.label.clickable:hover {
49
- cursor: pointer;
50
54
  color: var(--accent-color);
51
55
  }
52
56
 
@@ -56,11 +60,13 @@
56
60
  overflow: hidden;
57
61
  text-overflow: ellipsis;
58
62
  white-space: nowrap;
63
+ pointer-events: none;
59
64
  }
60
65
 
61
66
  .tree-item>.actions {
62
67
  padding: 0 .5rem;
63
68
  color: var(--text-color-lighter);
69
+ pointer-events: auto;
64
70
  }
65
71
 
66
72
  .tree-item>.actions .rmwc-icon {
@@ -95,14 +101,42 @@
95
101
  padding-left: 2rem;
96
102
  }
97
103
 
98
- /* Tree search */
99
- .tree__search {
100
- padding: 1rem;
104
+ /* Tree header */
105
+ .tree__header {
106
+ display: flex;
107
+ align-items: center;
108
+ justify-content: space-between;
109
+ padding: 0.5rem;
101
110
  border-bottom: 1px solid var(--divider-color, #e0e0e0);
102
111
  background-color: var(--background-color-light, #fafafa);
112
+ gap: 0.5rem;
103
113
  margin-bottom: 0.5rem;
104
114
  }
105
115
 
116
+ /* When only expand icon is present, align to right */
117
+ .tree__header:has(.tree__expand-control):not(:has(.tree__search)) {
118
+ justify-content: flex-end;
119
+ }
120
+
121
+ /* Alternative for browsers that don't support :has() */
122
+ .tree__header--expand-only {
123
+ justify-content: flex-end;
124
+ }
125
+
126
+ /* Tree search */
127
+ .tree__search {
128
+ flex: 1;
129
+ }
130
+
131
+ /* Tree expand control */
132
+ .tree__expand-control {
133
+ display: flex;
134
+ align-items: center;
135
+ justify-content: center;
136
+ min-width: 2rem;
137
+ height: 2rem;
138
+ }
139
+
106
140
  /* Tree controls */
107
141
  .tree__controls {
108
142
  display: flex;
@@ -203,6 +237,7 @@
203
237
  display: flex;
204
238
  align-items: center;
205
239
  margin-right: 0.5rem;
240
+ pointer-events: none;
206
241
  }
207
242
 
208
243
  /* TreeNode loading */
@@ -233,7 +268,7 @@
233
268
 
234
269
  /* TreeNode children */
235
270
  .tree-node__children {
236
- margin-left: 1.5rem;
271
+ margin-left: .8rem;
237
272
  border-left: 1px solid var(--divider-color, #e0e0e0);
238
273
  padding-left: 0.5rem;
239
274
  }
@@ -1,8 +1,8 @@
1
1
  import React, { useState } from 'react'
2
2
  import { Tree, TreeNode, TreeItem } from './tree'
3
3
  import { Button } from './button'
4
- import { Icon } from '
5
- import { ExampleLayout, ExampleSection, ExampleSubsection, CodeSnippet } from './ExampleLayout'./icon'
4
+ import { Icon } from './icon'
5
+ import { ExampleLayout, ExampleSection, ExampleSubsection, CodeSnippet } from './ExampleLayout'
6
6
 
7
7
  /**
8
8
  * Ejemplos de los componentes Tree mejorados manteniendo 100% compatibilidad
@@ -209,7 +209,7 @@ export const TreeExamples = () => {
209
209
  }}>
210
210
  <Tree>
211
211
  <TreeNode id="root" label="Root Folder" icon="folder" open={true}>
212
- <TreeNode id="documents" label="Documents" icon="folder" open={false}>
212
+ <TreeNode id="documents" label="Documents" icon="folder">
213
213
  <TreeItem id="doc1" label="Document 1.pdf" icon="picture_as_pdf" onSelect={handleSelect} selected={selectedItem === 'doc1'} />
214
214
  <TreeItem id="doc2" label="Document 2.docx" icon="description" onSelect={handleSelect} selected={selectedItem === 'doc2'} />
215
215
  </TreeNode>
@@ -221,6 +221,27 @@ export const TreeExamples = () => {
221
221
  </TreeNode>
222
222
  </Tree>
223
223
  </div>
224
+ <CodeSnippet
225
+ language="jsx"
226
+ code={`<Tree>
227
+ <TreeNode id="root" label="Root Folder" icon="folder" open={true}>
228
+ <TreeNode id="documents" label="Documents" icon="folder">
229
+ <TreeItem id="doc1" label="Document 1.pdf" icon="picture_as_pdf"
230
+ onSelect={handleSelect} selected={selectedItem === 'doc1'} />
231
+ <TreeItem id="doc2" label="Document 2.docx" icon="description"
232
+ onSelect={handleSelect} selected={selectedItem === 'doc2'} />
233
+ </TreeNode>
234
+ <TreeNode id="images" label="Images" icon="folder" open={true}>
235
+ <TreeItem id="img1" label="Photo 1.jpg" icon="image"
236
+ onSelect={handleSelect} selected={selectedItem === 'img1'} />
237
+ <TreeItem id="img2" label="Photo 2.png" icon="image"
238
+ onSelect={handleSelect} selected={selectedItem === 'img2'} />
239
+ </TreeNode>
240
+ <TreeItem id="readme" label="README.md" icon="description"
241
+ onSelect={handleSelect} selected={selectedItem === 'readme'} />
242
+ </TreeNode>
243
+ </Tree>`}
244
+ />
224
245
  </section>
225
246
 
226
247
  {/* Tree con búsqueda */}
@@ -252,6 +273,24 @@ export const TreeExamples = () => {
252
273
  </TreeNode>
253
274
  </Tree>
254
275
  </div>
276
+ <CodeSnippet
277
+ language="jsx"
278
+ code={`<Tree
279
+ searchable={true}
280
+ searchPlaceholder="Buscar archivos y carpetas..."
281
+ searchBy={['label']}
282
+ ariaLabel="Árbol de archivos con búsqueda"
283
+ >
284
+ <TreeNode id="projects" label="Projects" icon="work" open={true}>
285
+ <TreeNode id="project1" label="Website Project" icon="web">
286
+ <TreeItem id="index" label="index.html" icon="code"
287
+ onSelect={handleSelect} selected={selectedItem === 'index'} />
288
+ <TreeItem id="styles" label="styles.css" icon="palette"
289
+ onSelect={handleSelect} selected={selectedItem === 'styles'} />
290
+ </TreeNode>
291
+ </TreeNode>
292
+ </Tree>`}
293
+ />
255
294
  </section>
256
295
 
257
296
  {/* Tree con checkboxes y selección múltiple */}
@@ -300,6 +339,31 @@ export const TreeExamples = () => {
300
339
  </TreeNode>
301
340
  </Tree>
302
341
  </div>
342
+ <CodeSnippet
343
+ language="jsx"
344
+ code={`<Tree
345
+ multiSelect={true}
346
+ onMultiSelect={handleMultiSelect}
347
+ ariaLabel="Árbol con selección múltiple"
348
+ >
349
+ <TreeNode id="backup" label="Backup Files" icon="backup" open={true}>
350
+ <TreeItem
351
+ id="file1"
352
+ label="Config Backup"
353
+ icon="settings_backup_restore"
354
+ onSelect={handleSelect}
355
+ selected={selectedItems.includes('file1')}
356
+ />
357
+ <TreeItem
358
+ id="file2"
359
+ label="Database Backup"
360
+ icon="storage"
361
+ onSelect={handleSelect}
362
+ selected={selectedItems.includes('file2')}
363
+ />
364
+ </TreeNode>
365
+ </Tree>`}
366
+ />
303
367
  </section>
304
368
 
305
369
  {/* Tree con badges y drag & drop */}
@@ -371,11 +435,90 @@ export const TreeExamples = () => {
371
435
  </TreeNode>
372
436
  </Tree>
373
437
  </div>
438
+ <CodeSnippet
439
+ language="jsx"
440
+ code={`<Tree ariaLabel="Árbol con drag and drop">
441
+ <TreeNode
442
+ id="inbox"
443
+ label="Inbox"
444
+ icon="inbox"
445
+ open={true}
446
+ badge={5}
447
+ tooltip="5 unread messages"
448
+ draggable={true}
449
+ onDragStart={handleDragStart}
450
+ onDrop={handleDrop}
451
+ >
452
+ <TreeItem
453
+ id="msg1"
454
+ label="Important Message"
455
+ icon="priority_high"
456
+ badge="!"
457
+ tooltip="High priority message"
458
+ draggable={true}
459
+ onDragStart={handleDragStart}
460
+ onDrop={handleDrop}
461
+ />
462
+ </TreeNode>
463
+ </Tree>`}
464
+ />
465
+ </section>
466
+
467
+ {/* Tree con búsqueda y control de expansión */}
468
+ <section style={{ marginBottom: '2rem' }}>
469
+ <h3>Tree con Búsqueda y Control de Expansión</h3>
470
+ <div style={{
471
+ background: '#fff',
472
+ border: '1px solid #ddd',
473
+ borderRadius: '8px',
474
+ overflow: 'hidden',
475
+ maxHeight: '400px'
476
+ }}>
477
+ <Tree
478
+ searchable={true}
479
+ searchPlaceholder="Buscar en la estructura..."
480
+ searchBy={['label']}
481
+ showExpandIcon={true}
482
+ onExpandAll={() => console.log('Expand all')}
483
+ onCollapseAll={() => console.log('Collapse all')}
484
+ ariaLabel="Árbol con búsqueda y controles de expansión"
485
+ >
486
+ <TreeNode id="projects" label="Projects" icon="work" open={false}>
487
+ <TreeNode id="web-project" label="Web Project" icon="web" open={false}>
488
+ <TreeItem id="index-html" label="index.html" icon="code" onSelect={handleSelect} selected={selectedItem === 'index-html'} />
489
+ <TreeItem id="styles-css" label="styles.css" icon="palette" onSelect={handleSelect} selected={selectedItem === 'styles-css'} />
490
+ <TreeItem id="script-js" label="script.js" icon="javascript" onSelect={handleSelect} selected={selectedItem === 'script-js'} />
491
+ </TreeNode>
492
+ <TreeNode id="mobile-app" label="Mobile App" icon="phone_android" open={false}>
493
+ <TreeItem id="main-dart" label="main.dart" icon="code" onSelect={handleSelect} selected={selectedItem === 'main-dart'} />
494
+ <TreeItem id="pubspec" label="pubspec.yaml" icon="settings" onSelect={handleSelect} selected={selectedItem === 'pubspec'} />
495
+ </TreeNode>
496
+ </TreeNode>
497
+ </Tree>
498
+ </div>
499
+ <CodeSnippet
500
+ language="jsx"
501
+ code={`<Tree
502
+ searchable={true}
503
+ searchPlaceholder="Buscar en la estructura..."
504
+ searchBy={['label']}
505
+ showExpandIcon={true}
506
+ onExpandAll={() => console.log('Expand all')}
507
+ onCollapseAll={() => console.log('Collapse all')}
508
+ >
509
+ <TreeNode id="projects" label="Projects" icon="work">
510
+ <TreeNode id="web-project" label="Web Project" icon="web">
511
+ <TreeItem id="index-html" label="index.html" icon="code" />
512
+ <TreeItem id="styles-css" label="styles.css" icon="palette" />
513
+ </TreeNode>
514
+ </TreeNode>
515
+ </Tree>`}
516
+ />
374
517
  </section>
375
518
 
376
519
  {/* Tree con controles de expansión */}
377
520
  <section style={{ marginBottom: '2rem' }}>
378
- <h3>Tree con Controles de Expansión</h3>
521
+ <h3>Tree con Control de Expansión</h3>
379
522
  <div style={{
380
523
  background: '#fff',
381
524
  border: '1px solid #ddd',
@@ -383,9 +526,8 @@ export const TreeExamples = () => {
383
526
  overflow: 'hidden',
384
527
  maxHeight: '400px'
385
528
  }}>
386
- <Tree
387
- expandAll={true}
388
- collapseAll={true}
529
+ <Tree
530
+ showExpandIcon={true}
389
531
  onExpandAll={() => console.log('Expand all')}
390
532
  onCollapseAll={() => console.log('Collapse all')}
391
533
  ariaLabel="Árbol con controles de expansión"
@@ -408,6 +550,26 @@ export const TreeExamples = () => {
408
550
  </TreeNode>
409
551
  </Tree>
410
552
  </div>
553
+ <CodeSnippet
554
+ language="jsx"
555
+ code={`<Tree
556
+ showExpandIcon={true}
557
+ onExpandAll={() => console.log('Expand all')}
558
+ onCollapseAll={() => console.log('Collapse all')}
559
+ ariaLabel="Árbol con controles de expansión"
560
+ >
561
+ <TreeNode id="company" label="Company Structure" icon="business">
562
+ <TreeNode id="engineering" label="Engineering" icon="engineering">
563
+ <TreeNode id="frontend" label="Frontend Team" icon="web">
564
+ <TreeItem id="dev1" label="John Doe - Senior Developer"
565
+ icon="person" onSelect={handleSelect} />
566
+ <TreeItem id="dev2" label="Jane Smith - UI Designer"
567
+ icon="design_services" onSelect={handleSelect} />
568
+ </TreeNode>
569
+ </TreeNode>
570
+ </TreeNode>
571
+ </Tree>`}
572
+ />
411
573
  </section>
412
574
 
413
575
  {/* Estados especiales */}