ywana-core8 0.1.79 → 0.1.80
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.
- package/dist/index.cjs +3244 -2215
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +2095 -1125
- package/dist/index.css.map +1 -1
- package/dist/index.modern.js +3244 -2215
- package/dist/index.modern.js.map +1 -1
- package/dist/index.umd.js +3244 -2215
- package/dist/index.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/html/ExampleLayout.css +401 -0
- package/src/html/ExampleLayout.js +192 -0
- package/src/html/README-sidebar-navigation.md +195 -0
- package/src/html/accordion.example.js +123 -4
- package/src/html/accordion.example.js.backup +390 -0
- package/src/html/button.example.js +50 -3
- package/src/html/button.example.js.backup +374 -0
- package/src/html/button.example.new.js +416 -0
- package/src/html/checkbox.example.js +93 -4
- package/src/html/checkbox.example.js.backup +316 -0
- package/src/html/chip.example.js +108 -4
- package/src/html/chip.example.js.backup +355 -0
- package/src/html/color.example.js +108 -4
- package/src/html/color.example.js.backup +527 -0
- package/src/html/components.example.js +123 -4
- package/src/html/components.example.js.backup +492 -0
- package/src/html/convert-examples.js +183 -0
- package/src/html/demo-sidebar.html +410 -0
- package/src/html/form.example.js +93 -4
- package/src/html/form.example.js.backup +385 -0
- package/src/html/header2.example.js +108 -4
- package/src/html/header2.example.js.backup +411 -0
- package/src/html/icon.example.js +77 -3
- package/src/html/icon.example.js.backup +268 -0
- package/src/html/list.example.js +93 -4
- package/src/html/list.example.js.backup +404 -0
- package/src/html/progress.example.js +74 -4
- package/src/html/progress.example.js.backup +424 -0
- package/src/html/property.example.js +123 -4
- package/src/html/property.example.js.backup +553 -0
- package/src/html/radio.example.js +108 -4
- package/src/html/radio.example.js.backup +389 -0
- package/src/html/section.example.js +42 -3
- package/src/html/section.example.js.backup +99 -0
- package/src/html/switch.example.js +108 -4
- package/src/html/switch.example.js.backup +461 -0
- package/src/html/tab.example.js +93 -4
- package/src/html/tab.example.js.backup +446 -0
- package/src/html/table-export-utils.js +483 -0
- package/src/html/table-summary-functions.js +363 -0
- package/src/html/table2.css +1449 -479
- package/src/html/table2.example.js +2937 -512
- package/src/html/table2.example.js.broken +1226 -0
- package/src/html/table2.js +1426 -1000
- package/src/html/test-resize.html +279 -0
- package/src/html/test-selection.html +387 -0
- package/src/html/textfield2.example.js +108 -4
- package/src/html/textfield2.example.js.backup +1370 -0
- package/src/html/tokenfield.example.js +108 -4
- package/src/html/tokenfield.example.js.backup +503 -0
- package/src/html/tree.css +2 -4
- package/src/html/tree.example.js +93 -4
- package/src/html/tree.example.js.backup +475 -0
- package/src/html/tree.js +19 -3
@@ -0,0 +1,1226 @@
|
|
1
|
+
import React, { useState } from 'react'
|
2
|
+
import { DataTable2 } from './table2'
|
3
|
+
import { Button } from './button'
|
4
|
+
import { Text } from './text'
|
5
|
+
import { ExampleLayout, ExampleSection, ExampleSubsection, CodeSnippet } from './ExampleLayout'
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Ejemplos del componente DataTable2 mejorado manteniendo 100% compatibilidad
|
9
|
+
*/
|
10
|
+
export const DataTable2Examples = () => {
|
11
|
+
const [isLoading, setIsLoading] = useState(false)
|
12
|
+
const [showAdvanced, setShowAdvanced] = useState(false)
|
13
|
+
const [selectedRows, setSelectedRows] = useState([])
|
14
|
+
|
15
|
+
// Datos de ejemplo
|
16
|
+
const columns = [
|
17
|
+
{
|
18
|
+
id: 'checked',
|
19
|
+
label: '',
|
20
|
+
type: 'CHECK',
|
21
|
+
sortable: false,
|
22
|
+
width: 50
|
23
|
+
},
|
24
|
+
{
|
25
|
+
id: 'id',
|
26
|
+
label: 'ID',
|
27
|
+
type: 'Number',
|
28
|
+
sortable: true,
|
29
|
+
resizable: true,
|
30
|
+
width: 80
|
31
|
+
},
|
32
|
+
{
|
33
|
+
id: 'name',
|
34
|
+
label: 'Name',
|
35
|
+
type: 'String',
|
36
|
+
sortable: true,
|
37
|
+
filterable: true,
|
38
|
+
editable: true,
|
39
|
+
resizable: true,
|
40
|
+
onChange: (rowId, fieldId, value) => console.log('Edit:', rowId, fieldId, value)
|
41
|
+
},
|
42
|
+
{
|
43
|
+
id: 'email',
|
44
|
+
label: 'Email',
|
45
|
+
type: 'String',
|
46
|
+
sortable: true,
|
47
|
+
filterable: true,
|
48
|
+
editable: true,
|
49
|
+
resizable: true,
|
50
|
+
onChange: (rowId, fieldId, value) => console.log('Edit:', rowId, fieldId, value)
|
51
|
+
},
|
52
|
+
{
|
53
|
+
id: 'age',
|
54
|
+
label: 'Age',
|
55
|
+
type: 'Number',
|
56
|
+
sortable: true,
|
57
|
+
editable: true,
|
58
|
+
resizable: true,
|
59
|
+
min: 0,
|
60
|
+
max: 120,
|
61
|
+
onChange: (rowId, fieldId, value) => console.log('Edit:', rowId, fieldId, value)
|
62
|
+
},
|
63
|
+
{
|
64
|
+
id: 'status',
|
65
|
+
label: 'Status',
|
66
|
+
type: 'SELECTION',
|
67
|
+
sortable: true,
|
68
|
+
filterable: true,
|
69
|
+
editable: true,
|
70
|
+
resizable: true,
|
71
|
+
options: [
|
72
|
+
{ label: 'Active', value: 'active' },
|
73
|
+
{ label: 'Inactive', value: 'inactive' },
|
74
|
+
{ label: 'Pending', value: 'pending' }
|
75
|
+
],
|
76
|
+
onChange: (rowId, fieldId, value) => console.log('Edit:', rowId, fieldId, value)
|
77
|
+
},
|
78
|
+
{
|
79
|
+
id: 'verified',
|
80
|
+
label: 'Verified',
|
81
|
+
type: 'Boolean',
|
82
|
+
sortable: true,
|
83
|
+
editable: true,
|
84
|
+
resizable: true,
|
85
|
+
onChange: (rowId, fieldId, value) => console.log('Edit:', rowId, fieldId, value)
|
86
|
+
}
|
87
|
+
]
|
88
|
+
|
89
|
+
const rows = [
|
90
|
+
{
|
91
|
+
id: 1,
|
92
|
+
name: 'John Doe',
|
93
|
+
email: 'john@example.com',
|
94
|
+
age: 30,
|
95
|
+
status: 'active',
|
96
|
+
verified: true,
|
97
|
+
info: () => <div>Additional info for John Doe</div>
|
98
|
+
},
|
99
|
+
{
|
100
|
+
id: 2,
|
101
|
+
name: 'Jane Smith',
|
102
|
+
email: 'jane@example.com',
|
103
|
+
age: 25,
|
104
|
+
status: 'pending',
|
105
|
+
verified: false,
|
106
|
+
info: 'Jane is a new user pending verification'
|
107
|
+
},
|
108
|
+
{
|
109
|
+
id: 3,
|
110
|
+
name: 'Bob Johnson',
|
111
|
+
email: 'bob@example.com',
|
112
|
+
age: 35,
|
113
|
+
status: 'active',
|
114
|
+
verified: true
|
115
|
+
},
|
116
|
+
{
|
117
|
+
id: 4,
|
118
|
+
name: 'Alice Brown',
|
119
|
+
email: 'alice@example.com',
|
120
|
+
age: 28,
|
121
|
+
status: 'inactive',
|
122
|
+
verified: true,
|
123
|
+
disabled: true
|
124
|
+
},
|
125
|
+
{
|
126
|
+
id: 5,
|
127
|
+
name: 'Charlie Wilson',
|
128
|
+
email: 'charlie@example.com',
|
129
|
+
age: 42,
|
130
|
+
status: 'active',
|
131
|
+
verified: true
|
132
|
+
}
|
133
|
+
]
|
134
|
+
|
135
|
+
// Generar datos grandes para virtual scrolling
|
136
|
+
const largeDataset = Array.from({ length: 1000 }, (_, i) => ({
|
137
|
+
id: i + 1,
|
138
|
+
name: `User ${i + 1}`,
|
139
|
+
email: `user${i + 1}@example.com`,
|
140
|
+
age: 20 + (i % 50),
|
141
|
+
status: ['active', 'inactive', 'pending'][i % 3],
|
142
|
+
verified: i % 2 === 0
|
143
|
+
}))
|
144
|
+
|
145
|
+
const handleRowSelection = (row, event) => {
|
146
|
+
console.log('Row selected:', row)
|
147
|
+
setSelectedRows(prev => [...prev, row.id])
|
148
|
+
}
|
149
|
+
|
150
|
+
const handleSort = (dragged, dropped) => {
|
151
|
+
console.log('Sort:', dragged, dropped)
|
152
|
+
}
|
153
|
+
|
154
|
+
const handleCheckAll = (ids, checked) => {
|
155
|
+
console.log('Check all:', ids, checked)
|
156
|
+
setSelectedRows(checked ? ids : [])
|
157
|
+
}
|
158
|
+
|
159
|
+
const handleExport = (rows, columns) => {
|
160
|
+
console.log('Export:', rows.length, 'rows')
|
161
|
+
// Custom export logic here
|
162
|
+
}
|
163
|
+
|
164
|
+
const handleSearch = (term) => {
|
165
|
+
console.log('Search:', term)
|
166
|
+
}
|
167
|
+
|
168
|
+
const simulateLoading = () => {
|
169
|
+
setIsLoading(true)
|
170
|
+
setTimeout(() => setIsLoading(false), 3000)
|
171
|
+
}
|
172
|
+
|
173
|
+
// Definir secciones para el menú lateral
|
174
|
+
const sections = [
|
175
|
+
{
|
176
|
+
id: 'overview',
|
177
|
+
title: 'Introducción',
|
178
|
+
icon: 'info'
|
179
|
+
},
|
180
|
+
{
|
181
|
+
id: 'basic-examples',
|
182
|
+
title: 'Ejemplos Básicos',
|
183
|
+
icon: 'table_chart',
|
184
|
+
subsections: [
|
185
|
+
{ id: 'simple-table', title: 'Tabla Simple' },
|
186
|
+
{ id: 'sortable-table', title: 'Tabla Ordenable' },
|
187
|
+
{ id: 'filterable-table', title: 'Tabla con Filtros' }
|
188
|
+
]
|
189
|
+
},
|
190
|
+
{
|
191
|
+
id: 'advanced-features',
|
192
|
+
title: 'Características Avanzadas',
|
193
|
+
icon: 'settings',
|
194
|
+
subsections: [
|
195
|
+
{ id: 'editable-cells', title: 'Celdas Editables' },
|
196
|
+
{ id: 'row-selection', title: 'Selección de Filas' },
|
197
|
+
{ id: 'column-resize', title: 'Redimensionar Columnas' }
|
198
|
+
]
|
199
|
+
},
|
200
|
+
{
|
201
|
+
id: 'expandable-rows',
|
202
|
+
title: 'Filas Expandibles',
|
203
|
+
icon: 'expand_more',
|
204
|
+
subsections: [
|
205
|
+
{ id: 'info-react-component', title: 'Info como Componente React' },
|
206
|
+
{ id: 'info-string-simple', title: 'Info como String Simple' },
|
207
|
+
{ id: 'info-custom-actions', title: 'Info con Acciones Personalizadas' }
|
208
|
+
]
|
209
|
+
},
|
210
|
+
{
|
211
|
+
id: 'themes-variants',
|
212
|
+
title: 'Temas y Variantes',
|
213
|
+
icon: 'palette',
|
214
|
+
subsections: [
|
215
|
+
{ id: 'density-variants', title: 'Variantes de Densidad' },
|
216
|
+
{ id: 'theme-variants', title: 'Variantes de Tema' },
|
217
|
+
{ id: 'style-variants', title: 'Variantes de Estilo' }
|
218
|
+
]
|
219
|
+
},
|
220
|
+
{
|
221
|
+
id: 'loading-states',
|
222
|
+
title: 'Estados de Carga',
|
223
|
+
icon: 'hourglass_empty'
|
224
|
+
},
|
225
|
+
{
|
226
|
+
id: 'empty-states',
|
227
|
+
title: 'Estados Vacíos',
|
228
|
+
icon: 'inbox'
|
229
|
+
},
|
230
|
+
{
|
231
|
+
id: 'api-reference',
|
232
|
+
title: 'Referencia API',
|
233
|
+
icon: 'code'
|
234
|
+
}
|
235
|
+
]
|
236
|
+
|
237
|
+
return (
|
238
|
+
<ExampleLayout title="DataTable2 Examples" sections={sections}>
|
239
|
+
<ExampleSection id="overview" title="DataTable2 - Versión Mejorada (100% Compatible)" icon="table_chart">
|
240
|
+
<div style={{
|
241
|
+
background: '#f8f9fa',
|
242
|
+
padding: '1rem',
|
243
|
+
borderRadius: '8px',
|
244
|
+
marginBottom: '2rem',
|
245
|
+
border: '1px solid #e9ecef'
|
246
|
+
}}>
|
247
|
+
<h3>✅ Mejoras Implementadas (100% Compatibilidad):</h3>
|
248
|
+
<ul style={{ columns: 2, columnGap: '2rem' }}>
|
249
|
+
<li>🛡️ <strong>PropTypes completos</strong> - Validación exhaustiva</li>
|
250
|
+
<li>🔍 <strong>Búsqueda integrada</strong> - Search en tiempo real</li>
|
251
|
+
<li>📊 <strong>Exportación CSV</strong> - Export automático o personalizado</li>
|
252
|
+
<li>📱 <strong>Virtual Scrolling</strong> - Rendimiento para miles de filas</li>
|
253
|
+
<li>🎨 <strong>Múltiples temas</strong> - default, dark, minimal</li>
|
254
|
+
<li>📐 <strong>Densidad variable</strong> - compact, normal, comfortable</li>
|
255
|
+
<li>🎯 <strong>Selección mejorada</strong> - single, multiple, none</li>
|
256
|
+
<li>🔄 <strong>Ordenamiento avanzado</strong> - single, multiple, none</li>
|
257
|
+
<li>📏 <strong>Columnas redimensionables</strong> - Resize interactivo</li>
|
258
|
+
<li>🎭 <strong>Estados avanzados</strong> - loading, skeleton, striped</li>
|
259
|
+
<li>♿ <strong>Accesibilidad total</strong> - WCAG 2.1 AA compliant</li>
|
260
|
+
<li>📱 <strong>Responsive completo</strong> - Mobile-first design</li>
|
261
|
+
</ul>
|
262
|
+
</div>
|
263
|
+
</ExampleSection>
|
264
|
+
|
265
|
+
<ExampleSection id="basic-examples" title="Ejemplos Básicos" icon="table_chart">
|
266
|
+
<ExampleSubsection id="simple-table" title="Controles de Demostración">
|
267
|
+
<div style={{
|
268
|
+
background: '#fff',
|
269
|
+
padding: '1rem',
|
270
|
+
borderRadius: '8px',
|
271
|
+
border: '1px solid #ddd',
|
272
|
+
display: 'flex',
|
273
|
+
gap: '1rem',
|
274
|
+
alignItems: 'center',
|
275
|
+
flexWrap: 'wrap'
|
276
|
+
}}>
|
277
|
+
<Button
|
278
|
+
label="Simulate Loading"
|
279
|
+
icon="refresh"
|
280
|
+
action={simulateLoading}
|
281
|
+
disabled={isLoading}
|
282
|
+
/>
|
283
|
+
<Button
|
284
|
+
label={showAdvanced ? "Hide Advanced" : "Show Advanced"}
|
285
|
+
icon={showAdvanced ? "visibility_off" : "visibility"}
|
286
|
+
action={() => setShowAdvanced(!showAdvanced)}
|
287
|
+
/>
|
288
|
+
<span style={{ marginLeft: 'auto', color: '#666' }}>
|
289
|
+
Selected: {selectedRows.length} rows
|
290
|
+
</span>
|
291
|
+
</div>
|
292
|
+
</ExampleSubsection>
|
293
|
+
|
294
|
+
<ExampleSubsection id="sortable-table" title="DataTable Original (100% Compatible)">
|
295
|
+
<div style={{
|
296
|
+
background: '#fff',
|
297
|
+
padding: '1rem',
|
298
|
+
border: '1px solid #ddd',
|
299
|
+
borderRadius: '8px'
|
300
|
+
}}>
|
301
|
+
<DataTable2
|
302
|
+
columns={columns}
|
303
|
+
rows={rows}
|
304
|
+
onRowSelection={handleRowSelection}
|
305
|
+
onSort={handleSort}
|
306
|
+
onCheckAll={handleCheckAll}
|
307
|
+
editable={true}
|
308
|
+
outlined={true}
|
309
|
+
expanded={false}
|
310
|
+
multisort={true}
|
311
|
+
filterable={true}
|
312
|
+
emptyMessage="No users found"
|
313
|
+
emptyIcon="people_outline"
|
314
|
+
/>
|
315
|
+
<Text size="sm" color="muted" style={{ marginTop: '0.5rem' }}>
|
316
|
+
API original sin cambios - todas las props funcionan idéntico
|
317
|
+
</Text>
|
318
|
+
</div>
|
319
|
+
</ExampleSubsection>
|
320
|
+
|
321
|
+
<ExampleSubsection id="filterable-table" title="DataTable2 con Nuevas Características">
|
322
|
+
<div style={{
|
323
|
+
background: '#fff',
|
324
|
+
padding: '1rem',
|
325
|
+
border: '1px solid #ddd',
|
326
|
+
borderRadius: '8px'
|
327
|
+
}}>
|
328
|
+
<DataTable2
|
329
|
+
columns={columns}
|
330
|
+
rows={rows}
|
331
|
+
onRowSelection={handleRowSelection}
|
332
|
+
onSort={handleSort}
|
333
|
+
onCheckAll={handleCheckAll}
|
334
|
+
editable={true}
|
335
|
+
outlined={true}
|
336
|
+
// Nuevas características
|
337
|
+
loading={isLoading}
|
338
|
+
skeleton={isLoading}
|
339
|
+
striped={true}
|
340
|
+
hover={true}
|
341
|
+
bordered={true}
|
342
|
+
responsive={true}
|
343
|
+
stickyHeader={true}
|
344
|
+
selectionMode="multiple"
|
345
|
+
sortMode="multiple"
|
346
|
+
searchable={true}
|
347
|
+
searchPlaceholder="Search users..."
|
348
|
+
onSearch={handleSearch}
|
349
|
+
exportable={true}
|
350
|
+
onExport={handleExport}
|
351
|
+
showRowNumbers={true}
|
352
|
+
rowHeight="medium"
|
353
|
+
density="normal"
|
354
|
+
theme="default"
|
355
|
+
accessibility={true}
|
356
|
+
onRowClick={(row) => console.log('Row clicked:', row)}
|
357
|
+
onRowDoubleClick={(row) => console.log('Row double-clicked:', row)}
|
358
|
+
onCellClick={(row, column, cell) => console.log('Cell clicked:', row, column, cell)}
|
359
|
+
footerContent={
|
360
|
+
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
361
|
+
<span>Total: {rows.length} users</span>
|
362
|
+
<span>Selected: {selectedRows.length}</span>
|
363
|
+
</div>
|
364
|
+
}
|
365
|
+
/>
|
366
|
+
</div>
|
367
|
+
</ExampleSubsection>
|
368
|
+
</ExampleSection>
|
369
|
+
|
370
|
+
<ExampleSection id="themes-variants" title="Temas y Variantes" icon="palette">
|
371
|
+
<ExampleSubsection id="density-variants" title="Variantes de Densidad">
|
372
|
+
<div style={{
|
373
|
+
background: '#fff',
|
374
|
+
padding: '1rem',
|
375
|
+
border: '1px solid #ddd',
|
376
|
+
borderRadius: '8px',
|
377
|
+
display: 'grid',
|
378
|
+
gridTemplateColumns: '1fr 1fr',
|
379
|
+
gap: '1rem'
|
380
|
+
}}>
|
381
|
+
<div>
|
382
|
+
<h4>Tema Dark</h4>
|
383
|
+
<DataTable2
|
384
|
+
columns={columns.slice(0, 4)}
|
385
|
+
rows={rows.slice(0, 3)}
|
386
|
+
theme="dark"
|
387
|
+
striped={true}
|
388
|
+
bordered={true}
|
389
|
+
compact={true}
|
390
|
+
/>
|
391
|
+
</div>
|
392
|
+
<div>
|
393
|
+
<h4>Tema Minimal</h4>
|
394
|
+
<DataTable2
|
395
|
+
columns={columns.slice(0, 4)}
|
396
|
+
rows={rows.slice(0, 3)}
|
397
|
+
theme="minimal"
|
398
|
+
hover={false}
|
399
|
+
density="comfortable"
|
400
|
+
/>
|
401
|
+
</div>
|
402
|
+
</div>
|
403
|
+
</ExampleSubsection>
|
404
|
+
|
405
|
+
<ExampleSubsection id="row-selection" title="Densidades y Tamaños (Redimensionables)">
|
406
|
+
<h3>📐 Densidades y Tamaños (Redimensionables)</h3>
|
407
|
+
<div style={{
|
408
|
+
background: '#fff',
|
409
|
+
padding: '1rem',
|
410
|
+
border: '1px solid #ddd',
|
411
|
+
borderRadius: '8px'
|
412
|
+
}}>
|
413
|
+
<div style={{ marginBottom: '2rem' }}>
|
414
|
+
<h4>🔧 Compact (Altura: 28px) - Arrastra los bordes de las columnas para redimensionar</h4>
|
415
|
+
<DataTable2
|
416
|
+
columns={columns.slice(1, 5)} // Sin checkbox para mejor visualización
|
417
|
+
rows={rows.slice(0, 3)}
|
418
|
+
density="compact"
|
419
|
+
rowHeight="small"
|
420
|
+
compact={true}
|
421
|
+
resizable={true}
|
422
|
+
bordered={true}
|
423
|
+
onColumnResize={(columnId, width) => console.log(`Column ${columnId} resized to ${width}px`)}
|
424
|
+
/>
|
425
|
+
</div>
|
426
|
+
<div style={{ marginBottom: '2rem' }}>
|
427
|
+
<h4>📏 Normal (Altura: 40px) - Redimensionamiento habilitado</h4>
|
428
|
+
<DataTable2
|
429
|
+
columns={columns.slice(1, 5)}
|
430
|
+
rows={rows.slice(0, 3)}
|
431
|
+
density="normal"
|
432
|
+
rowHeight="medium"
|
433
|
+
resizable={true}
|
434
|
+
bordered={true}
|
435
|
+
onColumnResize={(columnId, width) => console.log(`Column ${columnId} resized to ${width}px`)}
|
436
|
+
/>
|
437
|
+
</div>
|
438
|
+
<div>
|
439
|
+
<h4>🛋️ Comfortable (Altura: 52px) - Máximo espacio</h4>
|
440
|
+
<DataTable2
|
441
|
+
columns={columns.slice(1, 5)}
|
442
|
+
rows={rows.slice(0, 3)}
|
443
|
+
density="comfortable"
|
444
|
+
rowHeight="large"
|
445
|
+
resizable={true}
|
446
|
+
bordered={true}
|
447
|
+
onColumnResize={(columnId, width) => console.log(`Column ${columnId} resized to ${width}px`)}
|
448
|
+
/>
|
449
|
+
</div>
|
450
|
+
<div style={{
|
451
|
+
marginTop: '1rem',
|
452
|
+
padding: '0.75rem',
|
453
|
+
background: '#e3f2fd',
|
454
|
+
borderRadius: '4px',
|
455
|
+
border: '1px solid #bbdefb'
|
456
|
+
}}>
|
457
|
+
<Text size="sm" color="prima">
|
458
|
+
💡 <strong>Tip:</strong> Pasa el mouse sobre el borde derecho de cualquier columna para ver el cursor de redimensionamiento.
|
459
|
+
Arrastra para cambiar el ancho. Los cambios se registran en la consola.
|
460
|
+
</Text>
|
461
|
+
</div>
|
462
|
+
</div>
|
463
|
+
</ExampleSubsection>
|
464
|
+
|
465
|
+
<ExampleSubsection id="column-resize" title="Virtual Scrolling (1000 filas)">
|
466
|
+
{showAdvanced && (
|
467
|
+
<div style={{ marginBottom: '2rem' }}>
|
468
|
+
<h3>📱 Virtual Scrolling (1000 filas)</h3>
|
469
|
+
<div style={{
|
470
|
+
background: '#fff',
|
471
|
+
padding: '1rem',
|
472
|
+
border: '1px solid #ddd',
|
473
|
+
borderRadius: '8px'
|
474
|
+
}}>
|
475
|
+
<DataTable2
|
476
|
+
columns={columns.slice(1, 6)} // Sin checkbox para simplificar
|
477
|
+
rows={largeDataset}
|
478
|
+
virtualScrolling={true}
|
479
|
+
pageSize={50}
|
480
|
+
searchable={true}
|
481
|
+
exportable={true}
|
482
|
+
stickyHeader={true}
|
483
|
+
showRowNumbers={true}
|
484
|
+
striped={true}
|
485
|
+
onSearch={handleSearch}
|
486
|
+
onExport={handleExport}
|
487
|
+
/>
|
488
|
+
<Text size="sm" color="muted" style={{ marginTop: '0.5rem' }}>
|
489
|
+
Rendimiento optimizado para grandes datasets con paginación virtual
|
490
|
+
</Text>
|
491
|
+
</div>
|
492
|
+
</section>
|
493
|
+
)}
|
494
|
+
|
495
|
+
{/* Estados especiales */}
|
496
|
+
{showAdvanced && (
|
497
|
+
<section style={{ marginBottom: '2rem' }}>
|
498
|
+
<h3>⚠️ Estados Especiales</h3>
|
499
|
+
<div style={{
|
500
|
+
background: '#fff',
|
501
|
+
padding: '1rem',
|
502
|
+
border: '1px solid #ddd',
|
503
|
+
borderRadius: '8px',
|
504
|
+
display: 'grid',
|
505
|
+
gridTemplateColumns: '1fr 1fr',
|
506
|
+
gap: '1rem'
|
507
|
+
}}>
|
508
|
+
<div>
|
509
|
+
<h4>Loading State</h4>
|
510
|
+
<DataTable2
|
511
|
+
columns={columns.slice(0, 4)}
|
512
|
+
rows={rows.slice(0, 3)}
|
513
|
+
loading={true}
|
514
|
+
skeleton={false}
|
515
|
+
/>
|
516
|
+
</div>
|
517
|
+
<div>
|
518
|
+
<h4>Skeleton State</h4>
|
519
|
+
<DataTable2
|
520
|
+
columns={columns.slice(0, 4)}
|
521
|
+
rows={[]}
|
522
|
+
loading={false}
|
523
|
+
skeleton={true}
|
524
|
+
/>
|
525
|
+
</div>
|
526
|
+
</div>
|
527
|
+
</section>
|
528
|
+
)}
|
529
|
+
|
530
|
+
{/* Comparación antes/después */}
|
531
|
+
<section style={{ marginBottom: '2rem' }}>
|
532
|
+
<h3>Comparación: DataTable Original vs DataTable2</h3>
|
533
|
+
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '1rem' }}>
|
534
|
+
<div style={{
|
535
|
+
background: '#ffebee',
|
536
|
+
padding: '1rem',
|
537
|
+
borderRadius: '4px',
|
538
|
+
border: '1px solid #ffcdd2'
|
539
|
+
}}>
|
540
|
+
<h4>❌ DataTable Original</h4>
|
541
|
+
<ul>
|
542
|
+
<li>Funcionalidad básica de tabla</li>
|
543
|
+
<li>Sorting y filtering básico</li>
|
544
|
+
<li>Edición inline limitada</li>
|
545
|
+
<li>Selección de filas básica</li>
|
546
|
+
<li>Sin PropTypes ni validación</li>
|
547
|
+
<li>Sin búsqueda integrada</li>
|
548
|
+
<li>Sin exportación</li>
|
549
|
+
<li>Sin virtual scrolling</li>
|
550
|
+
<li>Sin temas ni variantes</li>
|
551
|
+
<li>Sin accesibilidad</li>
|
552
|
+
<li>CSS básico sin responsive</li>
|
553
|
+
<li>Rendimiento limitado</li>
|
554
|
+
</ul>
|
555
|
+
</div>
|
556
|
+
<div style={{
|
557
|
+
background: '#e8f5e8',
|
558
|
+
padding: '1rem',
|
559
|
+
borderRadius: '4px',
|
560
|
+
border: '1px solid #c8e6c9'
|
561
|
+
}}>
|
562
|
+
<h4>✅ DataTable2 Mejorado</h4>
|
563
|
+
<ul>
|
564
|
+
<li>Mantiene funcionalidad original</li>
|
565
|
+
<li>PropTypes completos y validación</li>
|
566
|
+
<li>Búsqueda integrada en tiempo real</li>
|
567
|
+
<li>Exportación CSV automática/custom</li>
|
568
|
+
<li>Virtual scrolling para performance</li>
|
569
|
+
<li>Múltiples temas y variantes</li>
|
570
|
+
<li>Estados loading y skeleton</li>
|
571
|
+
<li>Accesibilidad total (WCAG 2.1 AA)</li>
|
572
|
+
<li>Selección avanzada (single/multiple)</li>
|
573
|
+
<li>Columnas redimensionables</li>
|
574
|
+
<li>CSS responsive con dark mode</li>
|
575
|
+
<li>Optimizado para miles de filas</li>
|
576
|
+
</ul>
|
577
|
+
</div>
|
578
|
+
</div>
|
579
|
+
</section>
|
580
|
+
|
581
|
+
{/* Garantía de compatibilidad */}
|
582
|
+
<section style={{ marginBottom: '2rem' }}>
|
583
|
+
<h3>🔒 Garantía de Compatibilidad 100%</h3>
|
584
|
+
<div style={{
|
585
|
+
background: '#fff3cd',
|
586
|
+
padding: '1rem',
|
587
|
+
borderRadius: '4px',
|
588
|
+
border: '1px solid #ffeaa7'
|
589
|
+
}}>
|
590
|
+
<p><strong>Migración Sin Riesgo:</strong></p>
|
591
|
+
<ul>
|
592
|
+
<li>✅ <strong>Props originales</strong> - columns, rows, onRowSelection, onSort, onCheckAll, editable, outlined, expanded, multisort, filterable funcionan idéntico</li>
|
593
|
+
<li>✅ <strong>Callbacks sin cambios</strong> - Misma firma y comportamiento</li>
|
594
|
+
<li>✅ <strong>Estructura de datos</strong> - Columns y rows mantienen formato exacto</li>
|
595
|
+
<li>✅ <strong>CSS compatible</strong> - Clases originales preservadas (.datatable8)</li>
|
596
|
+
<li>✅ <strong>Nuevas características opcionales</strong> - Todas las mejoras son opt-in</li>
|
597
|
+
<li>✅ <strong>Cero breaking changes</strong> - No se rompe código existente</li>
|
598
|
+
<li>✅ <strong>Migración gradual</strong> - Puedes adoptar nuevas características cuando quieras</li>
|
599
|
+
</ul>
|
600
|
+
|
601
|
+
<div style={{
|
602
|
+
background: '#d4edda',
|
603
|
+
padding: '1rem',
|
604
|
+
borderRadius: '4px',
|
605
|
+
marginTop: '1rem',
|
606
|
+
border: '1px solid #c3e6cb'
|
607
|
+
}}>
|
608
|
+
<h4>📋 Pasos de Migración:</h4>
|
609
|
+
<ol>
|
610
|
+
<li><strong>Reemplaza el import:</strong> <code>import {`{DataTable2}`} from './table2'</code></li>
|
611
|
+
<li><strong>Cambia el componente:</strong> <code><DataTable2 .../></code></li>
|
612
|
+
<li><strong>¡Listo!</strong> Todo funciona igual + nuevas características disponibles</li>
|
613
|
+
<li><strong>Opcional:</strong> Agrega nuevas props cuando las necesites</li>
|
614
|
+
</ol>
|
615
|
+
</div>
|
616
|
+
</div>
|
617
|
+
</section>
|
618
|
+
|
619
|
+
{/* Casos de uso */}
|
620
|
+
<section style={{ marginBottom: '2rem' }}>
|
621
|
+
<h3>🎯 Casos de Uso Recomendados</h3>
|
622
|
+
<div style={{
|
623
|
+
background: '#fff',
|
624
|
+
padding: '1rem',
|
625
|
+
border: '1px solid #ddd',
|
626
|
+
borderRadius: '8px',
|
627
|
+
display: 'grid',
|
628
|
+
gridTemplateColumns: '1fr 1fr',
|
629
|
+
gap: '1rem'
|
630
|
+
}}>
|
631
|
+
<div>
|
632
|
+
<h4>📊 Dashboards Administrativos</h4>
|
633
|
+
<ul>
|
634
|
+
<li>Búsqueda en tiempo real</li>
|
635
|
+
<li>Exportación de reportes</li>
|
636
|
+
<li>Edición inline</li>
|
637
|
+
<li>Selección múltiple</li>
|
638
|
+
<li>Filtros avanzados</li>
|
639
|
+
</ul>
|
640
|
+
|
641
|
+
<h4>📱 Aplicaciones Móviles</h4>
|
642
|
+
<ul>
|
643
|
+
<li>Responsive design</li>
|
644
|
+
<li>Touch-friendly</li>
|
645
|
+
<li>Virtual scrolling</li>
|
646
|
+
<li>Densidad compacta</li>
|
647
|
+
</ul>
|
648
|
+
</div>
|
649
|
+
<div>
|
650
|
+
<h4>🏢 Sistemas Empresariales</h4>
|
651
|
+
<ul>
|
652
|
+
<li>Miles de registros</li>
|
653
|
+
<li>Accesibilidad completa</li>
|
654
|
+
<li>Temas corporativos</li>
|
655
|
+
<li>Estados de carga</li>
|
656
|
+
<li>Validación robusta</li>
|
657
|
+
</ul>
|
658
|
+
|
659
|
+
<h4>🎨 Aplicaciones Modernas</h4>
|
660
|
+
<ul>
|
661
|
+
<li>Dark mode</li>
|
662
|
+
<li>Animaciones suaves</li>
|
663
|
+
<li>UX optimizada</li>
|
664
|
+
<li>Performance superior</li>
|
665
|
+
</ul>
|
666
|
+
</div>
|
667
|
+
</div>
|
668
|
+
</section>
|
669
|
+
|
670
|
+
{/* Performance */}
|
671
|
+
<section style={{ marginBottom: '2rem' }}>
|
672
|
+
<h3>⚡ Mejoras de Performance</h3>
|
673
|
+
<div style={{
|
674
|
+
background: '#fff',
|
675
|
+
padding: '1rem',
|
676
|
+
border: '1px solid #ddd',
|
677
|
+
borderRadius: '8px'
|
678
|
+
}}>
|
679
|
+
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: '1rem', textAlign: 'center' }}>
|
680
|
+
<div style={{ padding: '1rem', background: '#f8f9fa', borderRadius: '4px' }}>
|
681
|
+
<h4>🚀 Virtual Scrolling</h4>
|
682
|
+
<p><strong>10,000+ filas</strong></p>
|
683
|
+
<p>Renderizado solo de elementos visibles</p>
|
684
|
+
</div>
|
685
|
+
<div style={{ padding: '1rem', background: '#f8f9fa', borderRadius: '4px' }}>
|
686
|
+
<h4>🔍 Búsqueda Optimizada</h4>
|
687
|
+
<p><strong>Tiempo real</strong></p>
|
688
|
+
<p>Filtrado eficiente con debounce</p>
|
689
|
+
</div>
|
690
|
+
<div style={{ padding: '1rem', background: '#f8f9fa', borderRadius: '4px' }}>
|
691
|
+
<h4>💾 Gestión de Estado</h4>
|
692
|
+
<p><strong>React Hooks</strong></p>
|
693
|
+
<p>useCallback y useMemo optimizados</p>
|
694
|
+
</div>
|
695
|
+
</div>
|
696
|
+
</div>
|
697
|
+
</section>
|
698
|
+
|
699
|
+
{/* API Reference */}
|
700
|
+
<section style={{ marginBottom: '2rem' }}>
|
701
|
+
<h3>📚 API Reference - Nuevas Props</h3>
|
702
|
+
<div style={{
|
703
|
+
background: '#fff',
|
704
|
+
padding: '1rem',
|
705
|
+
border: '1px solid #ddd',
|
706
|
+
borderRadius: '8px'
|
707
|
+
}}>
|
708
|
+
<table style={{ width: '100%', borderCollapse: 'collapse' }}>
|
709
|
+
<thead>
|
710
|
+
<tr style={{ background: '#f8f9fa' }}>
|
711
|
+
<th style={{ padding: '0.5rem', border: '1px solid #ddd', textAlign: 'left' }}>Prop</th>
|
712
|
+
<th style={{ padding: '0.5rem', border: '1px solid #ddd', textAlign: 'left' }}>Tipo</th>
|
713
|
+
<th style={{ padding: '0.5rem', border: '1px solid #ddd', textAlign: 'left' }}>Default</th>
|
714
|
+
<th style={{ padding: '0.5rem', border: '1px solid #ddd', textAlign: 'left' }}>Descripción</th>
|
715
|
+
</tr>
|
716
|
+
</thead>
|
717
|
+
<tbody>
|
718
|
+
<tr>
|
719
|
+
<td style={{ padding: '0.5rem', border: '1px solid #ddd' }}><code>searchable</code></td>
|
720
|
+
<td style={{ padding: '0.5rem', border: '1px solid #ddd' }}>boolean</td>
|
721
|
+
<td style={{ padding: '0.5rem', border: '1px solid #ddd' }}>false</td>
|
722
|
+
<td style={{ padding: '0.5rem', border: '1px solid #ddd' }}>Habilita búsqueda en tiempo real</td>
|
723
|
+
</tr>
|
724
|
+
<tr>
|
725
|
+
<td style={{ padding: '0.5rem', border: '1px solid #ddd' }}><code>exportable</code></td>
|
726
|
+
<td style={{ padding: '0.5rem', border: '1px solid #ddd' }}>boolean</td>
|
727
|
+
<td style={{ padding: '0.5rem', border: '1px solid #ddd' }}>false</td>
|
728
|
+
<td style={{ padding: '0.5rem', border: '1px solid #ddd' }}>Habilita exportación CSV</td>
|
729
|
+
</tr>
|
730
|
+
<tr>
|
731
|
+
<td style={{ padding: '0.5rem', border: '1px solid #ddd' }}><code>virtualScrolling</code></td>
|
732
|
+
<td style={{ padding: '0.5rem', border: '1px solid #ddd' }}>boolean</td>
|
733
|
+
<td style={{ padding: '0.5rem', border: '1px solid #ddd' }}>false</td>
|
734
|
+
<td style={{ padding: '0.5rem', border: '1px solid #ddd' }}>Habilita virtual scrolling para performance</td>
|
735
|
+
</tr>
|
736
|
+
<tr>
|
737
|
+
<td style={{ padding: '0.5rem', border: '1px solid #ddd' }}><code>selectionMode</code></td>
|
738
|
+
<td style={{ padding: '0.5rem', border: '1px solid #ddd' }}>string</td>
|
739
|
+
<td style={{ padding: '0.5rem', border: '1px solid #ddd' }}>single</td>
|
740
|
+
<td style={{ padding: '0.5rem', border: '1px solid #ddd' }}>Modo de selección: single, multiple, none</td>
|
741
|
+
</tr>
|
742
|
+
<tr>
|
743
|
+
<td style={{ padding: '0.5rem', border: '1px solid #ddd' }}><code>theme</code></td>
|
744
|
+
<td style={{ padding: '0.5rem', border: '1px solid #ddd' }}>string</td>
|
745
|
+
<td style={{ padding: '0.5rem', border: '1px solid #ddd' }}>default</td>
|
746
|
+
<td style={{ padding: '0.5rem', border: '1px solid #ddd' }}>Tema visual: default, dark, minimal</td>
|
747
|
+
</tr>
|
748
|
+
<tr>
|
749
|
+
<td style={{ padding: '0.5rem', border: '1px solid #ddd' }}><code>density</code></td>
|
750
|
+
<td style={{ padding: '0.5rem', border: '1px solid #ddd' }}>string</td>
|
751
|
+
<td style={{ padding: '0.5rem', border: '1px solid #ddd' }}>normal</td>
|
752
|
+
<td style={{ padding: '0.5rem', border: '1px solid #ddd' }}>Densidad: compact, normal, comfortable</td>
|
753
|
+
</tr>
|
754
|
+
</tbody>
|
755
|
+
</table>
|
756
|
+
</div>
|
757
|
+
</section>
|
758
|
+
|
759
|
+
{/* Filas Expandibles */}
|
760
|
+
<section style={{ marginBottom: '2rem' }}>
|
761
|
+
<h3>🔽 Filas Expandibles con Info</h3>
|
762
|
+
<p>Ejemplos de filas que se pueden expandir para mostrar información adicional usando el campo <code>info</code>.</p>
|
763
|
+
|
764
|
+
<div style={{
|
765
|
+
background: '#fff',
|
766
|
+
padding: '1.5rem',
|
767
|
+
borderRadius: '8px',
|
768
|
+
border: '1px solid #ddd',
|
769
|
+
marginBottom: '1rem'
|
770
|
+
}}>
|
771
|
+
<h4>Ejemplo 1: Info como Componente React</h4>
|
772
|
+
<DataTable2
|
773
|
+
id="expandable-table-1"
|
774
|
+
columns={[
|
775
|
+
{ id: 'id', label: 'ID', sortable: true, width: 80 },
|
776
|
+
{ id: 'product', label: 'Producto', sortable: true, filterable: true },
|
777
|
+
{ id: 'price', label: 'Precio', sortable: true },
|
778
|
+
{ id: 'stock', label: 'Stock', sortable: true },
|
779
|
+
{ id: 'category', label: 'Categoría', filterable: true }
|
780
|
+
]}
|
781
|
+
rows={[
|
782
|
+
{
|
783
|
+
id: 1,
|
784
|
+
product: 'MacBook Pro 16"',
|
785
|
+
price: '$2,499',
|
786
|
+
stock: 15,
|
787
|
+
category: 'Laptops',
|
788
|
+
info: {
|
789
|
+
action: () => console.log('Expandir producto 1'),
|
790
|
+
content: (
|
791
|
+
<div style={{ padding: '1rem', background: '#f8f9fa', border: '1px solid #e9ecef', borderRadius: '4px' }}>
|
792
|
+
<h5 style={{ margin: '0 0 0.5rem 0', color: '#495057' }}>Detalles del Producto</h5>
|
793
|
+
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '1rem', fontSize: '0.875rem' }}>
|
794
|
+
<div>
|
795
|
+
<strong>Especificaciones:</strong>
|
796
|
+
<ul style={{ margin: '0.25rem 0', paddingLeft: '1rem' }}>
|
797
|
+
<li>Chip M2 Pro</li>
|
798
|
+
<li>16GB RAM</li>
|
799
|
+
<li>512GB SSD</li>
|
800
|
+
<li>16" Liquid Retina XDR</li>
|
801
|
+
</ul>
|
802
|
+
</div>
|
803
|
+
<div>
|
804
|
+
<strong>Disponibilidad:</strong>
|
805
|
+
<ul style={{ margin: '0.25rem 0', paddingLeft: '1rem' }}>
|
806
|
+
<li>En stock: 15 unidades</li>
|
807
|
+
<li>Próximo envío: 24h</li>
|
808
|
+
<li>Garantía: 1 año</li>
|
809
|
+
<li>Devoluciones: 30 días</li>
|
810
|
+
</ul>
|
811
|
+
</div>
|
812
|
+
</div>
|
813
|
+
</div>
|
814
|
+
)
|
815
|
+
}
|
816
|
+
},
|
817
|
+
{
|
818
|
+
id: 2,
|
819
|
+
product: 'iPhone 15 Pro',
|
820
|
+
price: '$999',
|
821
|
+
stock: 42,
|
822
|
+
category: 'Smartphones',
|
823
|
+
info: {
|
824
|
+
action: () => console.log('Expandir producto 2'),
|
825
|
+
content: (
|
826
|
+
<div style={{ padding: '1rem', background: '#f8f9fa', border: '1px solid #e9ecef', borderRadius: '4px' }}>
|
827
|
+
<h5 style={{ margin: '0 0 0.5rem 0', color: '#495057' }}>Información del iPhone</h5>
|
828
|
+
<div style={{ display: 'flex', gap: '2rem', fontSize: '0.875rem' }}>
|
829
|
+
<div>
|
830
|
+
<strong>Colores disponibles:</strong>
|
831
|
+
<div style={{ display: 'flex', gap: '0.5rem', marginTop: '0.25rem' }}>
|
832
|
+
<span style={{ width: '20px', height: '20px', background: '#1d1d1f', borderRadius: '50%', border: '1px solid #ccc' }}></span>
|
833
|
+
<span style={{ width: '20px', height: '20px', background: '#f5f5dc', borderRadius: '50%', border: '1px solid #ccc' }}></span>
|
834
|
+
<span style={{ width: '20px', height: '20px', background: '#4169e1', borderRadius: '50%', border: '1px solid #ccc' }}></span>
|
835
|
+
<span style={{ width: '20px', height: '20px', background: '#c0c0c0', borderRadius: '50%', border: '1px solid #ccc' }}></span>
|
836
|
+
</div>
|
837
|
+
</div>
|
838
|
+
<div>
|
839
|
+
<strong>Capacidades:</strong> 128GB, 256GB, 512GB, 1TB<br/>
|
840
|
+
<strong>Cámara:</strong> Sistema Pro de 48MP<br/>
|
841
|
+
<strong>Pantalla:</strong> 6.1" Super Retina XDR
|
842
|
+
</div>
|
843
|
+
</div>
|
844
|
+
</div>
|
845
|
+
)
|
846
|
+
}
|
847
|
+
},
|
848
|
+
{
|
849
|
+
id: 3,
|
850
|
+
product: 'iPad Air',
|
851
|
+
price: '$599',
|
852
|
+
stock: 8,
|
853
|
+
category: 'Tablets',
|
854
|
+
info: {
|
855
|
+
action: () => console.log('Expandir producto 3'),
|
856
|
+
content: (
|
857
|
+
<div style={{ padding: '1rem', background: '#fff3cd', border: '1px solid #ffeaa7', borderRadius: '4px' }}>
|
858
|
+
<h5 style={{ margin: '0 0 0.5rem 0', color: '#856404' }}>⚠️ Stock Bajo</h5>
|
859
|
+
<p style={{ margin: '0', fontSize: '0.875rem', color: '#856404' }}>
|
860
|
+
Quedan solo 8 unidades en stock. Se recomienda realizar pedido pronto.
|
861
|
+
El próximo lote llegará en 2 semanas.
|
862
|
+
</p>
|
863
|
+
<div style={{ marginTop: '0.5rem', fontSize: '0.875rem' }}>
|
864
|
+
<strong>Accesorios incluidos:</strong> Cable USB-C, Adaptador de corriente 20W
|
865
|
+
</div>
|
866
|
+
</div>
|
867
|
+
)
|
868
|
+
}
|
869
|
+
}
|
870
|
+
]}
|
871
|
+
expanded={true}
|
872
|
+
density="normal"
|
873
|
+
striped={true}
|
874
|
+
hover={true}
|
875
|
+
resizable={true}
|
876
|
+
filterable={true}
|
877
|
+
/>
|
878
|
+
</div>
|
879
|
+
|
880
|
+
<div style={{
|
881
|
+
background: '#f8f9fa',
|
882
|
+
padding: '1rem',
|
883
|
+
borderRadius: '4px',
|
884
|
+
border: '1px solid #e9ecef',
|
885
|
+
marginBottom: '1rem'
|
886
|
+
}}>
|
887
|
+
<h5 style={{ margin: '0 0 0.5rem 0' }}>📋 Código del Ejemplo 1:</h5>
|
888
|
+
<pre style={{
|
889
|
+
background: '#ffffff',
|
890
|
+
padding: '1rem',
|
891
|
+
borderRadius: '4px',
|
892
|
+
border: '1px solid #dee2e6',
|
893
|
+
fontSize: '0.75rem',
|
894
|
+
overflow: 'auto',
|
895
|
+
margin: '0'
|
896
|
+
}}>
|
897
|
+
{`<DataTable2
|
898
|
+
id="expandable-table-1"
|
899
|
+
columns={[
|
900
|
+
{ id: 'product', label: 'Producto', sortable: true, filterable: true },
|
901
|
+
{ id: 'price', label: 'Precio', sortable: true },
|
902
|
+
{ id: 'stock', label: 'Stock', sortable: true }
|
903
|
+
]}
|
904
|
+
rows={[
|
905
|
+
{
|
906
|
+
id: 1,
|
907
|
+
product: 'MacBook Pro 16"',
|
908
|
+
price: '$2,499',
|
909
|
+
stock: 15,
|
910
|
+
info: {
|
911
|
+
action: () => console.log('Expandir producto 1'),
|
912
|
+
content: (
|
913
|
+
<div style={{ padding: '1rem', background: '#f8f9fa' }}>
|
914
|
+
<h5>Detalles del Producto</h5>
|
915
|
+
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr' }}>
|
916
|
+
<div>
|
917
|
+
<strong>Especificaciones:</strong>
|
918
|
+
<ul>
|
919
|
+
<li>Chip M2 Pro</li>
|
920
|
+
<li>16GB RAM</li>
|
921
|
+
<li>512GB SSD</li>
|
922
|
+
</ul>
|
923
|
+
</div>
|
924
|
+
<div>
|
925
|
+
<strong>Disponibilidad:</strong>
|
926
|
+
<ul>
|
927
|
+
<li>En stock: 15 unidades</li>
|
928
|
+
<li>Próximo envío: 24h</li>
|
929
|
+
</ul>
|
930
|
+
</div>
|
931
|
+
</div>
|
932
|
+
</div>
|
933
|
+
)
|
934
|
+
}
|
935
|
+
}
|
936
|
+
]}
|
937
|
+
expanded={true}
|
938
|
+
density="normal"
|
939
|
+
striped={true}
|
940
|
+
resizable={true}
|
941
|
+
filterable={true}
|
942
|
+
/>`}
|
943
|
+
</pre>
|
944
|
+
</div>
|
945
|
+
|
946
|
+
<div style={{
|
947
|
+
background: '#fff',
|
948
|
+
padding: '1.5rem',
|
949
|
+
borderRadius: '8px',
|
950
|
+
border: '1px solid #ddd',
|
951
|
+
marginBottom: '1rem'
|
952
|
+
}}>
|
953
|
+
<h4>Ejemplo 2: Info como String Simple</h4>
|
954
|
+
<DataTable2
|
955
|
+
id="expandable-table-2"
|
956
|
+
columns={[
|
957
|
+
{ id: 'id', label: 'ID', width: 60 },
|
958
|
+
{ id: 'user', label: 'Usuario', sortable: true },
|
959
|
+
{ id: 'email', label: 'Email', sortable: true },
|
960
|
+
{ id: 'role', label: 'Rol', filterable: true },
|
961
|
+
{ id: 'status', label: 'Estado', filterable: true }
|
962
|
+
]}
|
963
|
+
rows={[
|
964
|
+
{
|
965
|
+
id: 1,
|
966
|
+
user: 'Ana García',
|
967
|
+
email: 'ana.garcia@empresa.com',
|
968
|
+
role: 'Admin',
|
969
|
+
status: 'Activo',
|
970
|
+
info: 'Administradora principal del sistema. Acceso completo a todas las funcionalidades. Última conexión: hace 2 horas.'
|
971
|
+
},
|
972
|
+
{
|
973
|
+
id: 2,
|
974
|
+
user: 'Carlos López',
|
975
|
+
email: 'carlos.lopez@empresa.com',
|
976
|
+
role: 'Editor',
|
977
|
+
status: 'Activo',
|
978
|
+
info: 'Editor de contenido con permisos de publicación. Especializado en marketing digital. Miembro del equipo desde 2022.'
|
979
|
+
},
|
980
|
+
{
|
981
|
+
id: 3,
|
982
|
+
user: 'María Rodríguez',
|
983
|
+
email: 'maria.rodriguez@empresa.com',
|
984
|
+
role: 'Viewer',
|
985
|
+
status: 'Inactivo',
|
986
|
+
info: 'Usuario con permisos de solo lectura. Cuenta suspendida temporalmente por inactividad. Último acceso: hace 3 meses.'
|
987
|
+
}
|
988
|
+
]}
|
989
|
+
expanded={true}
|
990
|
+
density="comfortable"
|
991
|
+
bordered={true}
|
992
|
+
resizable={true}
|
993
|
+
/>
|
994
|
+
</div>
|
995
|
+
|
996
|
+
<div style={{
|
997
|
+
background: '#f8f9fa',
|
998
|
+
padding: '1rem',
|
999
|
+
borderRadius: '4px',
|
1000
|
+
border: '1px solid #e9ecef',
|
1001
|
+
marginBottom: '1rem'
|
1002
|
+
}}>
|
1003
|
+
<h5 style={{ margin: '0 0 0.5rem 0' }}>📋 Código del Ejemplo 2:</h5>
|
1004
|
+
<pre style={{
|
1005
|
+
background: '#ffffff',
|
1006
|
+
padding: '1rem',
|
1007
|
+
borderRadius: '4px',
|
1008
|
+
border: '1px solid #dee2e6',
|
1009
|
+
fontSize: '0.75rem',
|
1010
|
+
overflow: 'auto',
|
1011
|
+
margin: '0'
|
1012
|
+
}}>
|
1013
|
+
{`<DataTable2
|
1014
|
+
id="expandable-table-2"
|
1015
|
+
columns={[
|
1016
|
+
{ id: 'user', label: 'Usuario', sortable: true },
|
1017
|
+
{ id: 'email', label: 'Email', sortable: true },
|
1018
|
+
{ id: 'role', label: 'Rol', filterable: true },
|
1019
|
+
{ id: 'status', label: 'Estado', filterable: true }
|
1020
|
+
]}
|
1021
|
+
rows={[
|
1022
|
+
{
|
1023
|
+
id: 1,
|
1024
|
+
user: 'Ana García',
|
1025
|
+
email: 'ana.garcia@empresa.com',
|
1026
|
+
role: 'Admin',
|
1027
|
+
status: 'Activo',
|
1028
|
+
info: 'Administradora principal del sistema. Acceso completo a todas las funcionalidades. Última conexión: hace 2 horas.'
|
1029
|
+
},
|
1030
|
+
{
|
1031
|
+
id: 2,
|
1032
|
+
user: 'Carlos López',
|
1033
|
+
email: 'carlos.lopez@empresa.com',
|
1034
|
+
role: 'Editor',
|
1035
|
+
status: 'Activo',
|
1036
|
+
info: 'Editor de contenido con permisos de publicación. Especializado en marketing digital.'
|
1037
|
+
}
|
1038
|
+
]}
|
1039
|
+
expanded={true}
|
1040
|
+
density="comfortable"
|
1041
|
+
bordered={true}
|
1042
|
+
resizable={true}
|
1043
|
+
/>`}
|
1044
|
+
</pre>
|
1045
|
+
</div>
|
1046
|
+
|
1047
|
+
<div style={{
|
1048
|
+
background: '#fff',
|
1049
|
+
padding: '1.5rem',
|
1050
|
+
borderRadius: '8px',
|
1051
|
+
border: '1px solid #ddd',
|
1052
|
+
marginBottom: '1rem'
|
1053
|
+
}}>
|
1054
|
+
<h4>Ejemplo 3: Info con Acciones Personalizadas</h4>
|
1055
|
+
<DataTable2
|
1056
|
+
id="expandable-table-3"
|
1057
|
+
columns={[
|
1058
|
+
{ id: 'ticket', label: 'Ticket #', width: 100 },
|
1059
|
+
{ id: 'title', label: 'Título', sortable: true },
|
1060
|
+
{ id: 'priority', label: 'Prioridad', filterable: true },
|
1061
|
+
{ id: 'assignee', label: 'Asignado a', filterable: true },
|
1062
|
+
{ id: 'created', label: 'Creado', sortable: true }
|
1063
|
+
]}
|
1064
|
+
rows={[
|
1065
|
+
{
|
1066
|
+
id: 1,
|
1067
|
+
ticket: 'TK-001',
|
1068
|
+
title: 'Error en login de usuarios',
|
1069
|
+
priority: 'Alta',
|
1070
|
+
assignee: 'Juan Pérez',
|
1071
|
+
created: '2024-01-15',
|
1072
|
+
info: {
|
1073
|
+
action: () => alert('Abriendo ticket TK-001 en nueva ventana'),
|
1074
|
+
content: (
|
1075
|
+
<div style={{ padding: '1rem', background: '#f8f9fa', border: '1px solid #e9ecef', borderRadius: '4px' }}>
|
1076
|
+
<div style={{ marginBottom: '1rem' }}>
|
1077
|
+
<strong>Descripción:</strong>
|
1078
|
+
<p style={{ margin: '0.25rem 0', fontSize: '0.875rem' }}>
|
1079
|
+
Los usuarios reportan problemas al intentar iniciar sesión.
|
1080
|
+
El error aparece intermitentemente y afecta aproximadamente al 15% de los intentos.
|
1081
|
+
</p>
|
1082
|
+
</div>
|
1083
|
+
<div style={{ display: 'flex', gap: '1rem', marginBottom: '1rem' }}>
|
1084
|
+
<div style={{ fontSize: '0.875rem' }}>
|
1085
|
+
<strong>Pasos para reproducir:</strong>
|
1086
|
+
<ol style={{ margin: '0.25rem 0', paddingLeft: '1rem' }}>
|
1087
|
+
<li>Ir a la página de login</li>
|
1088
|
+
<li>Introducir credenciales válidas</li>
|
1089
|
+
<li>Hacer clic en "Iniciar sesión"</li>
|
1090
|
+
<li>Error aparece aleatoriamente</li>
|
1091
|
+
</ol>
|
1092
|
+
</div>
|
1093
|
+
<div style={{ fontSize: '0.875rem' }}>
|
1094
|
+
<strong>Información técnica:</strong><br/>
|
1095
|
+
<code style={{ background: '#f1f3f4', padding: '0.25rem', borderRadius: '2px' }}>
|
1096
|
+
Error 500 - Internal Server Error
|
1097
|
+
</code><br/>
|
1098
|
+
<strong>Navegadores afectados:</strong> Chrome, Firefox<br/>
|
1099
|
+
<strong>Dispositivos:</strong> Desktop y móvil
|
1100
|
+
</div>
|
1101
|
+
</div>
|
1102
|
+
<div style={{ display: 'flex', gap: '0.5rem' }}>
|
1103
|
+
<button style={{ padding: '0.25rem 0.5rem', fontSize: '0.75rem', border: '1px solid #007bff', background: '#007bff', color: 'white', borderRadius: '3px', cursor: 'pointer' }}>
|
1104
|
+
Ver detalles completos
|
1105
|
+
</button>
|
1106
|
+
<button style={{ padding: '0.25rem 0.5rem', fontSize: '0.75rem', border: '1px solid #28a745', background: '#28a745', color: 'white', borderRadius: '3px', cursor: 'pointer' }}>
|
1107
|
+
Asignar a mí
|
1108
|
+
</button>
|
1109
|
+
<button style={{ padding: '0.25rem 0.5rem', fontSize: '0.75rem', border: '1px solid #ffc107', background: '#ffc107', color: '#212529', borderRadius: '3px', cursor: 'pointer' }}>
|
1110
|
+
Cambiar prioridad
|
1111
|
+
</button>
|
1112
|
+
</div>
|
1113
|
+
</div>
|
1114
|
+
)
|
1115
|
+
}
|
1116
|
+
},
|
1117
|
+
{
|
1118
|
+
id: 2,
|
1119
|
+
ticket: 'TK-002',
|
1120
|
+
title: 'Mejora en el dashboard',
|
1121
|
+
priority: 'Media',
|
1122
|
+
assignee: 'Ana Martín',
|
1123
|
+
created: '2024-01-14',
|
1124
|
+
info: {
|
1125
|
+
action: () => alert('Abriendo ticket TK-002'),
|
1126
|
+
content: (
|
1127
|
+
<div style={{ padding: '1rem', background: '#e7f3ff', border: '1px solid #b3d9ff', borderRadius: '4px' }}>
|
1128
|
+
<strong>Solicitud de mejora:</strong>
|
1129
|
+
<p style={{ margin: '0.5rem 0', fontSize: '0.875rem' }}>
|
1130
|
+
Agregar gráficos interactivos al dashboard principal para mejorar la visualización de datos.
|
1131
|
+
</p>
|
1132
|
+
<div style={{ fontSize: '0.875rem' }}>
|
1133
|
+
<strong>Estado:</strong> En progreso (60% completado)<br/>
|
1134
|
+
<strong>Tiempo estimado:</strong> 3 días adicionales<br/>
|
1135
|
+
<strong>Última actualización:</strong> Hace 4 horas
|
1136
|
+
</div>
|
1137
|
+
</div>
|
1138
|
+
)
|
1139
|
+
}
|
1140
|
+
}
|
1141
|
+
]}
|
1142
|
+
expanded={true}
|
1143
|
+
density="normal"
|
1144
|
+
theme="default"
|
1145
|
+
resizable={true}
|
1146
|
+
searchable={true}
|
1147
|
+
/>
|
1148
|
+
</div>
|
1149
|
+
|
1150
|
+
<div style={{
|
1151
|
+
background: '#f8f9fa',
|
1152
|
+
padding: '1rem',
|
1153
|
+
borderRadius: '4px',
|
1154
|
+
border: '1px solid #e9ecef',
|
1155
|
+
marginBottom: '1rem'
|
1156
|
+
}}>
|
1157
|
+
<h5 style={{ margin: '0 0 0.5rem 0' }}>📋 Código del Ejemplo 3:</h5>
|
1158
|
+
<pre style={{
|
1159
|
+
background: '#ffffff',
|
1160
|
+
padding: '1rem',
|
1161
|
+
borderRadius: '4px',
|
1162
|
+
border: '1px solid #dee2e6',
|
1163
|
+
fontSize: '0.75rem',
|
1164
|
+
overflow: 'auto',
|
1165
|
+
margin: '0'
|
1166
|
+
}}>
|
1167
|
+
{`<DataTable2
|
1168
|
+
id="expandable-table-3"
|
1169
|
+
columns={[
|
1170
|
+
{ id: 'ticket', label: 'Ticket #', width: 100 },
|
1171
|
+
{ id: 'title', label: 'Título', sortable: true },
|
1172
|
+
{ id: 'priority', label: 'Prioridad', filterable: true }
|
1173
|
+
]}
|
1174
|
+
rows={[
|
1175
|
+
{
|
1176
|
+
id: 1,
|
1177
|
+
ticket: 'TK-001',
|
1178
|
+
title: 'Error en login de usuarios',
|
1179
|
+
priority: 'Alta',
|
1180
|
+
info: {
|
1181
|
+
action: () => alert('Abriendo ticket TK-001'),
|
1182
|
+
content: (
|
1183
|
+
<div style={{ padding: '1rem', background: '#f8f9fa' }}>
|
1184
|
+
<div style={{ marginBottom: '1rem' }}>
|
1185
|
+
<strong>Descripción:</strong>
|
1186
|
+
<p>Los usuarios reportan problemas al iniciar sesión.</p>
|
1187
|
+
</div>
|
1188
|
+
<div style={{ display: 'flex', gap: '0.5rem' }}>
|
1189
|
+
<button>Ver detalles completos</button>
|
1190
|
+
<button>Asignar a mí</button>
|
1191
|
+
<button>Cambiar prioridad</button>
|
1192
|
+
</div>
|
1193
|
+
</div>
|
1194
|
+
)
|
1195
|
+
}
|
1196
|
+
}
|
1197
|
+
]}
|
1198
|
+
expanded={true}
|
1199
|
+
density="normal"
|
1200
|
+
resizable={true}
|
1201
|
+
searchable={true}
|
1202
|
+
/>`}
|
1203
|
+
</pre>
|
1204
|
+
</div>
|
1205
|
+
|
1206
|
+
<div style={{
|
1207
|
+
background: '#f8f9fa',
|
1208
|
+
padding: '1rem',
|
1209
|
+
borderRadius: '4px',
|
1210
|
+
border: '1px solid #e9ecef'
|
1211
|
+
}}>
|
1212
|
+
<h5 style={{ margin: '0 0 0.5rem 0' }}>💡 Cómo usar filas expandibles:</h5>
|
1213
|
+
<ul style={{ margin: '0', paddingLeft: '1.5rem', fontSize: '0.875rem' }}>
|
1214
|
+
<li><strong>Campo info como string:</strong> Se muestra directamente como texto expandible</li>
|
1215
|
+
<li><strong>Campo info como objeto:</strong> Debe tener <code>content</code> (JSX) y opcionalmente <code>action</code> (función)</li>
|
1216
|
+
<li><strong>Prop expanded:</strong> Controla si las filas inician expandidas o colapsadas</li>
|
1217
|
+
<li><strong>Icono de expansión:</strong> Aparece automáticamente en la columna de acciones cuando hay info</li>
|
1218
|
+
<li><strong>Click en el icono:</strong> Ejecuta la función <code>action</code> si está definida, o expande/colapsa la fila</li>
|
1219
|
+
</ul>
|
1220
|
+
</div>
|
1221
|
+
</ExampleSection>
|
1222
|
+
</ExampleLayout>
|
1223
|
+
)
|
1224
|
+
}
|
1225
|
+
|
1226
|
+
export default DataTable2Examples
|