ywana-core8 0.1.78 → 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.
Files changed (63) hide show
  1. package/dist/index.cjs +3244 -2215
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.css +2127 -1063
  4. package/dist/index.css.map +1 -1
  5. package/dist/index.modern.js +3244 -2215
  6. package/dist/index.modern.js.map +1 -1
  7. package/dist/index.umd.js +3244 -2215
  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/checkbox.example.js +93 -4
  19. package/src/html/checkbox.example.js.backup +316 -0
  20. package/src/html/chip.example.js +108 -4
  21. package/src/html/chip.example.js.backup +355 -0
  22. package/src/html/color.example.js +108 -4
  23. package/src/html/color.example.js.backup +527 -0
  24. package/src/html/components.example.js +123 -4
  25. package/src/html/components.example.js.backup +492 -0
  26. package/src/html/convert-examples.js +183 -0
  27. package/src/html/demo-sidebar.html +410 -0
  28. package/src/html/form.example.js +93 -4
  29. package/src/html/form.example.js.backup +385 -0
  30. package/src/html/header2.example.js +108 -4
  31. package/src/html/header2.example.js.backup +411 -0
  32. package/src/html/icon.example.js +77 -3
  33. package/src/html/icon.example.js.backup +268 -0
  34. package/src/html/list.example.js +93 -4
  35. package/src/html/list.example.js.backup +404 -0
  36. package/src/html/progress.example.js +74 -4
  37. package/src/html/progress.example.js.backup +424 -0
  38. package/src/html/property.example.js +123 -4
  39. package/src/html/property.example.js.backup +553 -0
  40. package/src/html/radio.example.js +108 -4
  41. package/src/html/radio.example.js.backup +389 -0
  42. package/src/html/section.example.js +42 -3
  43. package/src/html/section.example.js.backup +99 -0
  44. package/src/html/switch.example.js +108 -4
  45. package/src/html/switch.example.js.backup +461 -0
  46. package/src/html/tab.example.js +93 -4
  47. package/src/html/tab.example.js.backup +446 -0
  48. package/src/html/table-export-utils.js +483 -0
  49. package/src/html/table-summary-functions.js +363 -0
  50. package/src/html/table2.css +1496 -432
  51. package/src/html/table2.example.js +2937 -512
  52. package/src/html/table2.example.js.broken +1226 -0
  53. package/src/html/table2.js +1426 -1000
  54. package/src/html/test-resize.html +279 -0
  55. package/src/html/test-selection.html +387 -0
  56. package/src/html/textfield2.example.js +108 -4
  57. package/src/html/textfield2.example.js.backup +1370 -0
  58. package/src/html/tokenfield.example.js +108 -4
  59. package/src/html/tokenfield.example.js.backup +503 -0
  60. package/src/html/tree.css +2 -4
  61. package/src/html/tree.example.js +93 -4
  62. package/src/html/tree.example.js.backup +475 -0
  63. package/src/html/tree.js +19 -3
@@ -0,0 +1,279 @@
1
+ <!DOCTYPE html>
2
+ <html lang="es">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Test - Redimensionamiento de Columnas</title>
7
+ <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
8
+ <link rel="stylesheet" href="./table2.css">
9
+ <style>
10
+ body {
11
+ margin: 0;
12
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
13
+ background: #f5f5f5;
14
+ padding: 2rem;
15
+ }
16
+
17
+ .test-container {
18
+ background: white;
19
+ padding: 2rem;
20
+ border-radius: 8px;
21
+ border: 1px solid #e0e0e0;
22
+ max-width: 1200px;
23
+ margin: 0 auto;
24
+ }
25
+
26
+ .material-icons {
27
+ font-size: 18px;
28
+ vertical-align: middle;
29
+ }
30
+
31
+ .instructions {
32
+ background: #e3f2fd;
33
+ padding: 1rem;
34
+ border-radius: 4px;
35
+ margin-bottom: 2rem;
36
+ border-left: 4px solid #2196f3;
37
+ }
38
+
39
+ .instructions h3 {
40
+ margin: 0 0 0.5rem 0;
41
+ color: #1976d2;
42
+ }
43
+
44
+ .instructions p {
45
+ margin: 0;
46
+ color: #1565c0;
47
+ }
48
+ </style>
49
+ </head>
50
+ <body>
51
+ <div class="test-container">
52
+ <h1>🔧 Test de Redimensionamiento de Columnas</h1>
53
+
54
+ <div class="instructions">
55
+ <h3>📋 Instrucciones:</h3>
56
+ <p>1. Pasa el cursor sobre el borde derecho de cualquier columna</p>
57
+ <p>2. Verás que el cursor cambia a ↔️ (col-resize)</p>
58
+ <p>3. Haz click y arrastra para redimensionar la columna</p>
59
+ <p>4. Los anchos se guardan automáticamente en localStorage</p>
60
+ </div>
61
+
62
+ <div class="datatable2 datatable2--medium datatable2--normal datatable2--default">
63
+ <div class="datatable2__table-container">
64
+ <table>
65
+ <thead class="datatable2__header">
66
+ <tr>
67
+ <th class="datatable2__header-cell" style="width: 80px; min-width: 80px; position: relative;">
68
+ <div class="datatable2__header-content">
69
+ <span>ID</span>
70
+ <span class="material-icons">swap_vert</span>
71
+ </div>
72
+ <div class="datatable2__resize-handle" onmousedown="startResize(event, 'id')"></div>
73
+ </th>
74
+ <th class="datatable2__header-cell" style="width: 200px; min-width: 200px; position: relative;">
75
+ <div class="datatable2__header-content">
76
+ <span>Nombre</span>
77
+ <span class="material-icons">swap_vert</span>
78
+ </div>
79
+ <div class="datatable2__resize-handle" onmousedown="startResize(event, 'name')"></div>
80
+ </th>
81
+ <th class="datatable2__header-cell" style="width: 250px; min-width: 250px; position: relative;">
82
+ <div class="datatable2__header-content">
83
+ <span>Email</span>
84
+ <span class="material-icons">swap_vert</span>
85
+ </div>
86
+ <div class="datatable2__resize-handle" onmousedown="startResize(event, 'email')"></div>
87
+ </th>
88
+ <th class="datatable2__header-cell" style="width: 100px; min-width: 100px; position: relative;">
89
+ <div class="datatable2__header-content">
90
+ <span>Edad</span>
91
+ <span class="material-icons">swap_vert</span>
92
+ </div>
93
+ <div class="datatable2__resize-handle" onmousedown="startResize(event, 'age')"></div>
94
+ </th>
95
+ <th class="datatable2__header-cell" style="width: 120px; min-width: 120px; position: relative;">
96
+ <div class="datatable2__header-content">
97
+ <span>Estado</span>
98
+ <span class="material-icons">swap_vert</span>
99
+ </div>
100
+ <div class="datatable2__resize-handle" onmousedown="startResize(event, 'status')"></div>
101
+ </th>
102
+ </tr>
103
+ </thead>
104
+ <tbody>
105
+ <tr class="datatable2__row">
106
+ <td class="datatable2__cell">1</td>
107
+ <td class="datatable2__cell">Juan Pérez</td>
108
+ <td class="datatable2__cell">juan.perez@email.com</td>
109
+ <td class="datatable2__cell">30</td>
110
+ <td class="datatable2__cell">Activo</td>
111
+ </tr>
112
+ <tr class="datatable2__row">
113
+ <td class="datatable2__cell">2</td>
114
+ <td class="datatable2__cell">María García</td>
115
+ <td class="datatable2__cell">maria.garcia@email.com</td>
116
+ <td class="datatable2__cell">25</td>
117
+ <td class="datatable2__cell">Pendiente</td>
118
+ </tr>
119
+ <tr class="datatable2__row">
120
+ <td class="datatable2__cell">3</td>
121
+ <td class="datatable2__cell">Carlos López</td>
122
+ <td class="datatable2__cell">carlos.lopez@email.com</td>
123
+ <td class="datatable2__cell">35</td>
124
+ <td class="datatable2__cell">Inactivo</td>
125
+ </tr>
126
+ <tr class="datatable2__row">
127
+ <td class="datatable2__cell">4</td>
128
+ <td class="datatable2__cell">Ana Martínez</td>
129
+ <td class="datatable2__cell">ana.martinez@email.com</td>
130
+ <td class="datatable2__cell">28</td>
131
+ <td class="datatable2__cell">Activo</td>
132
+ </tr>
133
+ <tr class="datatable2__row">
134
+ <td class="datatable2__cell">5</td>
135
+ <td class="datatable2__cell">Roberto Silva</td>
136
+ <td class="datatable2__cell">roberto.silva@email.com</td>
137
+ <td class="datatable2__cell">42</td>
138
+ <td class="datatable2__cell">Activo</td>
139
+ </tr>
140
+ </tbody>
141
+ </table>
142
+ </div>
143
+ </div>
144
+
145
+ <div style="margin-top: 2rem; padding: 1rem; background: #f8f9fa; border-radius: 4px;">
146
+ <h4>📊 Anchos Actuales:</h4>
147
+ <div id="widths-display">
148
+ <p>ID: <span id="width-id">80px</span></p>
149
+ <p>Nombre: <span id="width-name">200px</span></p>
150
+ <p>Email: <span id="width-email">250px</span></p>
151
+ <p>Edad: <span id="width-age">100px</span></p>
152
+ <p>Estado: <span id="width-status">120px</span></p>
153
+ </div>
154
+ <button onclick="resetWidths()" style="margin-top: 1rem; padding: 0.5rem 1rem; background: #2196f3; color: white; border: none; border-radius: 4px; cursor: pointer;">
155
+ 🔄 Resetear Anchos
156
+ </button>
157
+ </div>
158
+ </div>
159
+
160
+ <script>
161
+ let isResizing = false;
162
+ let currentColumn = null;
163
+ let startX = 0;
164
+ let startWidth = 0;
165
+
166
+ function startResize(event, columnId) {
167
+ event.preventDefault();
168
+ event.stopPropagation();
169
+
170
+ isResizing = true;
171
+ currentColumn = columnId;
172
+ startX = event.clientX;
173
+
174
+ const th = event.target.parentElement;
175
+ startWidth = th.offsetWidth;
176
+
177
+ document.body.classList.add('datatable2-resizing');
178
+ document.addEventListener('mousemove', handleMouseMove);
179
+ document.addEventListener('mouseup', handleMouseUp);
180
+
181
+ console.log('Started resizing column:', columnId, 'from width:', startWidth);
182
+ }
183
+
184
+ function handleMouseMove(event) {
185
+ if (!isResizing) return;
186
+
187
+ const diff = event.clientX - startX;
188
+ const newWidth = Math.max(50, startWidth + diff);
189
+
190
+ // Update the column width
191
+ const th = document.querySelector(`th:nth-child(${getColumnIndex(currentColumn)})`);
192
+ if (th) {
193
+ th.style.width = newWidth + 'px';
194
+ th.style.minWidth = newWidth + 'px';
195
+ }
196
+
197
+ // Update display
198
+ const widthDisplay = document.getElementById(`width-${currentColumn}`);
199
+ if (widthDisplay) {
200
+ widthDisplay.textContent = newWidth + 'px';
201
+ }
202
+
203
+ // Save to localStorage
204
+ saveColumnWidth(currentColumn, newWidth);
205
+ }
206
+
207
+ function handleMouseUp() {
208
+ if (!isResizing) return;
209
+
210
+ isResizing = false;
211
+ currentColumn = null;
212
+
213
+ document.body.classList.remove('datatable2-resizing');
214
+ document.removeEventListener('mousemove', handleMouseMove);
215
+ document.removeEventListener('mouseup', handleMouseUp);
216
+
217
+ console.log('Finished resizing');
218
+ }
219
+
220
+ function getColumnIndex(columnId) {
221
+ const columns = ['id', 'name', 'email', 'age', 'status'];
222
+ return columns.indexOf(columnId) + 1;
223
+ }
224
+
225
+ function saveColumnWidth(columnId, width) {
226
+ const storageKey = 'datatable2-widths-test';
227
+ let widths = {};
228
+
229
+ try {
230
+ const saved = localStorage.getItem(storageKey);
231
+ if (saved) {
232
+ widths = JSON.parse(saved);
233
+ }
234
+ } catch (e) {
235
+ console.error('Error loading widths from localStorage:', e);
236
+ }
237
+
238
+ widths[columnId] = width;
239
+ localStorage.setItem(storageKey, JSON.stringify(widths));
240
+ }
241
+
242
+ function loadColumnWidths() {
243
+ const storageKey = 'datatable2-widths-test';
244
+
245
+ try {
246
+ const saved = localStorage.getItem(storageKey);
247
+ if (saved) {
248
+ const widths = JSON.parse(saved);
249
+
250
+ Object.keys(widths).forEach(columnId => {
251
+ const width = widths[columnId];
252
+ const th = document.querySelector(`th:nth-child(${getColumnIndex(columnId)})`);
253
+ if (th) {
254
+ th.style.width = width + 'px';
255
+ th.style.minWidth = width + 'px';
256
+ }
257
+
258
+ const widthDisplay = document.getElementById(`width-${columnId}`);
259
+ if (widthDisplay) {
260
+ widthDisplay.textContent = width + 'px';
261
+ }
262
+ });
263
+ }
264
+ } catch (e) {
265
+ console.error('Error loading widths from localStorage:', e);
266
+ }
267
+ }
268
+
269
+ function resetWidths() {
270
+ const storageKey = 'datatable2-widths-test';
271
+ localStorage.removeItem(storageKey);
272
+ location.reload();
273
+ }
274
+
275
+ // Load saved widths on page load
276
+ document.addEventListener('DOMContentLoaded', loadColumnWidths);
277
+ </script>
278
+ </body>
279
+ </html>
@@ -0,0 +1,387 @@
1
+ <!DOCTYPE html>
2
+ <html lang="es">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Test - Selección Múltiple DataTable2</title>
7
+ <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
8
+ <link rel="stylesheet" href="./table2.css">
9
+ <style>
10
+ body {
11
+ margin: 0;
12
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
13
+ background: #f5f5f5;
14
+ padding: 2rem;
15
+ }
16
+
17
+ .test-container {
18
+ background: white;
19
+ padding: 2rem;
20
+ border-radius: 8px;
21
+ border: 1px solid #e0e0e0;
22
+ max-width: 1200px;
23
+ margin: 0 auto;
24
+ }
25
+
26
+ .material-icons {
27
+ font-size: 18px;
28
+ vertical-align: middle;
29
+ }
30
+
31
+ .section {
32
+ margin-bottom: 3rem;
33
+ padding: 1.5rem;
34
+ border: 1px solid #e9ecef;
35
+ border-radius: 8px;
36
+ background: #fff;
37
+ }
38
+
39
+ .actions-bar {
40
+ display: flex;
41
+ gap: 1rem;
42
+ margin-bottom: 1rem;
43
+ padding: 1rem;
44
+ background: #f8f9fa;
45
+ border-radius: 4px;
46
+ align-items: center;
47
+ }
48
+
49
+ .btn {
50
+ padding: 0.5rem 1rem;
51
+ border: none;
52
+ border-radius: 4px;
53
+ cursor: pointer;
54
+ font-size: 0.875rem;
55
+ font-weight: 500;
56
+ }
57
+
58
+ .btn-danger {
59
+ background: #dc3545;
60
+ color: white;
61
+ }
62
+
63
+ .btn-primary {
64
+ background: #007bff;
65
+ color: white;
66
+ }
67
+
68
+ .btn-secondary {
69
+ background: #6c757d;
70
+ color: white;
71
+ }
72
+
73
+ .btn:disabled {
74
+ opacity: 0.5;
75
+ cursor: not-allowed;
76
+ }
77
+
78
+ .status-info {
79
+ background: #f8f9fa;
80
+ padding: 1rem;
81
+ border-radius: 4px;
82
+ border: 1px solid #e9ecef;
83
+ margin-top: 1rem;
84
+ }
85
+ </style>
86
+ </head>
87
+ <body>
88
+ <div class="test-container">
89
+ <h1>📋 Test de Selección Múltiple - DataTable2</h1>
90
+
91
+ <!-- Ejemplo 1: Selección con Checkboxes -->
92
+ <div class="section">
93
+ <h2>☑️ 1. Selección con Checkboxes</h2>
94
+ <p>Cada fila tiene un checkbox individual y hay un "Seleccionar todo" en el header.</p>
95
+
96
+ <div class="datatable2 datatable2--medium datatable2--normal datatable2--default">
97
+ <div class="datatable2__table-container">
98
+ <table>
99
+ <thead class="datatable2__header">
100
+ <tr>
101
+ <th class="datatable2__select-header">
102
+ <input type="checkbox" id="select-all" onchange="handleSelectAll(this.checked)">
103
+ </th>
104
+ <th class="datatable2__header-cell">ID</th>
105
+ <th class="datatable2__header-cell">Nombre</th>
106
+ <th class="datatable2__header-cell">Email</th>
107
+ <th class="datatable2__header-cell">Estado</th>
108
+ </tr>
109
+ </thead>
110
+ <tbody id="checkbox-table-body">
111
+ <!-- Se llena dinámicamente -->
112
+ </tbody>
113
+ </table>
114
+ </div>
115
+ </div>
116
+
117
+ <div class="status-info">
118
+ <strong>Estado actual:</strong> <span id="selected-count">0</span> elementos seleccionados
119
+ <br>
120
+ <strong>IDs seleccionados:</strong> <span id="selected-ids">Ninguno</span>
121
+ </div>
122
+ </div>
123
+
124
+ <!-- Ejemplo 2: Selección por Click -->
125
+ <div class="section">
126
+ <h2>👆 2. Selección por Click en Fila</h2>
127
+ <p>Haz click en cualquier fila para seleccionarla/deseleccionarla.</p>
128
+
129
+ <div class="datatable2 datatable2--medium datatable2--comfortable datatable2--default">
130
+ <div class="datatable2__table-container">
131
+ <table>
132
+ <thead class="datatable2__header">
133
+ <tr>
134
+ <th class="datatable2__header-cell">ID</th>
135
+ <th class="datatable2__header-cell">Nombre</th>
136
+ <th class="datatable2__header-cell">Email</th>
137
+ <th class="datatable2__header-cell">Estado</th>
138
+ </tr>
139
+ </thead>
140
+ <tbody id="click-table-body">
141
+ <!-- Se llena dinámicamente -->
142
+ </tbody>
143
+ </table>
144
+ </div>
145
+ </div>
146
+
147
+ <div class="status-info">
148
+ <strong>Filas seleccionadas:</strong> <span id="click-selected-count">0</span>
149
+ <br>
150
+ <strong>IDs:</strong> <span id="click-selected-ids">Ninguna</span>
151
+ </div>
152
+ </div>
153
+
154
+ <!-- Ejemplo 3: Acciones en Lote -->
155
+ <div class="section">
156
+ <h2>⚡ 3. Acciones en Lote</h2>
157
+ <p>Selecciona elementos y ejecuta acciones masivas.</p>
158
+
159
+ <div class="actions-bar">
160
+ <span style="font-weight: bold;">
161
+ Seleccionados: <span id="bulk-selected-count">0</span>
162
+ </span>
163
+ <button class="btn btn-danger" id="delete-btn" onclick="handleBulkAction('delete')" disabled>
164
+ 🗑️ Eliminar
165
+ </button>
166
+ <button class="btn btn-primary" id="activate-btn" onclick="handleBulkAction('activate')" disabled>
167
+ ✅ Activar
168
+ </button>
169
+ <button class="btn btn-secondary" id="export-btn" onclick="handleBulkAction('export')" disabled>
170
+ 📤 Exportar
171
+ </button>
172
+ </div>
173
+
174
+ <div class="datatable2 datatable2--medium datatable2--compact datatable2--default">
175
+ <div class="datatable2__table-container">
176
+ <table>
177
+ <thead class="datatable2__header">
178
+ <tr>
179
+ <th class="datatable2__select-header">
180
+ <input type="checkbox" id="bulk-select-all" onchange="handleBulkSelectAll(this.checked)">
181
+ </th>
182
+ <th class="datatable2__header-cell">ID</th>
183
+ <th class="datatable2__header-cell">Nombre</th>
184
+ <th class="datatable2__header-cell">Email</th>
185
+ <th class="datatable2__header-cell">Estado</th>
186
+ </tr>
187
+ </thead>
188
+ <tbody id="bulk-table-body">
189
+ <!-- Se llena dinámicamente -->
190
+ </tbody>
191
+ </table>
192
+ </div>
193
+ </div>
194
+ </div>
195
+ </div>
196
+
197
+ <script>
198
+ // Datos de ejemplo
199
+ const sampleData = [
200
+ { id: 1, name: 'Juan Pérez', email: 'juan@example.com', status: 'Activo' },
201
+ { id: 2, name: 'María García', email: 'maria@example.com', status: 'Pendiente' },
202
+ { id: 3, name: 'Carlos López', email: 'carlos@example.com', status: 'Activo' },
203
+ { id: 4, name: 'Ana Martínez', email: 'ana@example.com', status: 'Inactivo' },
204
+ { id: 5, name: 'Roberto Silva', email: 'roberto@example.com', status: 'Activo' }
205
+ ];
206
+
207
+ // Estado de selección
208
+ let checkedRows = {};
209
+ let clickSelectedRows = [];
210
+ let bulkCheckedRows = {};
211
+
212
+ // Funciones de utilidad
213
+ function getStatusClass(status) {
214
+ switch (status) {
215
+ case 'Activo': return 'status-active';
216
+ case 'Pendiente': return 'status-pending';
217
+ case 'Inactivo': return 'status-inactive';
218
+ default: return '';
219
+ }
220
+ }
221
+
222
+ function updateSelectedDisplay() {
223
+ const selectedIds = Object.keys(checkedRows).filter(id => checkedRows[id]);
224
+ document.getElementById('selected-count').textContent = selectedIds.length;
225
+ document.getElementById('selected-ids').textContent = selectedIds.length > 0 ? selectedIds.join(', ') : 'Ninguno';
226
+ }
227
+
228
+ function updateClickSelectedDisplay() {
229
+ document.getElementById('click-selected-count').textContent = clickSelectedRows.length;
230
+ document.getElementById('click-selected-ids').textContent = clickSelectedRows.length > 0 ? clickSelectedRows.join(', ') : 'Ninguna';
231
+ }
232
+
233
+ function updateBulkDisplay() {
234
+ const selectedIds = Object.keys(bulkCheckedRows).filter(id => bulkCheckedRows[id]);
235
+ const count = selectedIds.length;
236
+
237
+ document.getElementById('bulk-selected-count').textContent = count;
238
+
239
+ // Habilitar/deshabilitar botones
240
+ const buttons = ['delete-btn', 'activate-btn', 'export-btn'];
241
+ buttons.forEach(btnId => {
242
+ document.getElementById(btnId).disabled = count === 0;
243
+ });
244
+ }
245
+
246
+ // Renderizar tablas
247
+ function renderCheckboxTable() {
248
+ const tbody = document.getElementById('checkbox-table-body');
249
+ tbody.innerHTML = sampleData.map(row => `
250
+ <tr class="datatable2__row ${checkedRows[row.id] ? 'datatable2__row--selected' : ''}">
251
+ <td class="datatable2__cell">
252
+ <input type="checkbox" ${checkedRows[row.id] ? 'checked' : ''}
253
+ onchange="handleRowCheck(${row.id}, this.checked)">
254
+ </td>
255
+ <td class="datatable2__cell">${row.id}</td>
256
+ <td class="datatable2__cell">${row.name}</td>
257
+ <td class="datatable2__cell">${row.email}</td>
258
+ <td class="datatable2__cell">
259
+ <span class="status-badge ${getStatusClass(row.status)}">${row.status}</span>
260
+ </td>
261
+ </tr>
262
+ `).join('');
263
+ }
264
+
265
+ function renderClickTable() {
266
+ const tbody = document.getElementById('click-table-body');
267
+ tbody.innerHTML = sampleData.slice(0, 3).map(row => `
268
+ <tr class="datatable2__row ${clickSelectedRows.includes(row.id) ? 'datatable2__row--selected' : ''}"
269
+ onclick="handleRowClick(${row.id})" style="cursor: pointer;">
270
+ <td class="datatable2__cell">${row.id}</td>
271
+ <td class="datatable2__cell">${row.name}</td>
272
+ <td class="datatable2__cell">${row.email}</td>
273
+ <td class="datatable2__cell">
274
+ <span class="status-badge ${getStatusClass(row.status)}">${row.status}</span>
275
+ </td>
276
+ </tr>
277
+ `).join('');
278
+ }
279
+
280
+ function renderBulkTable() {
281
+ const tbody = document.getElementById('bulk-table-body');
282
+ tbody.innerHTML = sampleData.map(row => `
283
+ <tr class="datatable2__row ${bulkCheckedRows[row.id] ? 'datatable2__row--selected' : ''}">
284
+ <td class="datatable2__cell">
285
+ <input type="checkbox" ${bulkCheckedRows[row.id] ? 'checked' : ''}
286
+ onchange="handleBulkRowCheck(${row.id}, this.checked)">
287
+ </td>
288
+ <td class="datatable2__cell">${row.id}</td>
289
+ <td class="datatable2__cell">${row.name}</td>
290
+ <td class="datatable2__cell">${row.email}</td>
291
+ <td class="datatable2__cell">
292
+ <span class="status-badge ${getStatusClass(row.status)}">${row.status}</span>
293
+ </td>
294
+ </tr>
295
+ `).join('');
296
+ }
297
+
298
+ // Event handlers
299
+ function handleRowCheck(rowId, checked) {
300
+ checkedRows[rowId] = checked;
301
+ if (!checked) delete checkedRows[rowId];
302
+
303
+ renderCheckboxTable();
304
+ updateSelectedDisplay();
305
+
306
+ // Actualizar select all
307
+ const allChecked = sampleData.every(row => checkedRows[row.id]);
308
+ document.getElementById('select-all').checked = allChecked;
309
+ }
310
+
311
+ function handleSelectAll(checked) {
312
+ if (checked) {
313
+ sampleData.forEach(row => {
314
+ checkedRows[row.id] = true;
315
+ });
316
+ } else {
317
+ checkedRows = {};
318
+ }
319
+
320
+ renderCheckboxTable();
321
+ updateSelectedDisplay();
322
+ }
323
+
324
+ function handleRowClick(rowId) {
325
+ if (clickSelectedRows.includes(rowId)) {
326
+ clickSelectedRows = clickSelectedRows.filter(id => id !== rowId);
327
+ } else {
328
+ clickSelectedRows.push(rowId);
329
+ }
330
+
331
+ renderClickTable();
332
+ updateClickSelectedDisplay();
333
+ }
334
+
335
+ function handleBulkRowCheck(rowId, checked) {
336
+ bulkCheckedRows[rowId] = checked;
337
+ if (!checked) delete bulkCheckedRows[rowId];
338
+
339
+ renderBulkTable();
340
+ updateBulkDisplay();
341
+
342
+ // Actualizar select all
343
+ const allChecked = sampleData.every(row => bulkCheckedRows[row.id]);
344
+ document.getElementById('bulk-select-all').checked = allChecked;
345
+ }
346
+
347
+ function handleBulkSelectAll(checked) {
348
+ if (checked) {
349
+ sampleData.forEach(row => {
350
+ bulkCheckedRows[row.id] = true;
351
+ });
352
+ } else {
353
+ bulkCheckedRows = {};
354
+ }
355
+
356
+ renderBulkTable();
357
+ updateBulkDisplay();
358
+ }
359
+
360
+ function handleBulkAction(action) {
361
+ const selectedIds = Object.keys(bulkCheckedRows).filter(id => bulkCheckedRows[id]);
362
+
363
+ switch (action) {
364
+ case 'delete':
365
+ alert(`🗑️ Eliminar ${selectedIds.length} elementos: ${selectedIds.join(', ')}`);
366
+ break;
367
+ case 'activate':
368
+ alert(`✅ Activar ${selectedIds.length} elementos: ${selectedIds.join(', ')}`);
369
+ break;
370
+ case 'export':
371
+ alert(`📤 Exportar ${selectedIds.length} elementos: ${selectedIds.join(', ')}`);
372
+ break;
373
+ }
374
+ }
375
+
376
+ // Inicializar
377
+ document.addEventListener('DOMContentLoaded', function() {
378
+ renderCheckboxTable();
379
+ renderClickTable();
380
+ renderBulkTable();
381
+ updateSelectedDisplay();
382
+ updateClickSelectedDisplay();
383
+ updateBulkDisplay();
384
+ });
385
+ </script>
386
+ </body>
387
+ </html>