0
# Data Components
1
2
Data components provide high-performance display and manipulation of large datasets. These components support virtualization, sorting, filtering, and advanced interactions for handling complex data scenarios.
3
4
## Capabilities
5
6
### Grid
7
8
Advanced data grid with comprehensive features for displaying and manipulating tabular data.
9
10
```typescript { .api }
11
/**
12
* High-performance data grid component
13
* Supports large datasets with virtual scrolling and advanced features
14
*/
15
interface Grid extends HTMLElement {
16
/** Array of data items to display */
17
items: object[];
18
/** Array of currently selected items */
19
selectedItems: object[];
20
/** Currently active (focused) item */
21
activeItem: object | null;
22
/** Array of items with expanded details */
23
detailsOpenedItems: object[];
24
/** Enable column reordering */
25
columnReorderingAllowed: boolean;
26
/** Enable multi-column sorting */
27
multiSort: boolean;
28
/** Height of each row in pixels */
29
itemHeight: number;
30
/** Enable all rows selection */
31
allRowsSelected: boolean;
32
33
/** Select a specific item */
34
selectItem(item: object): void;
35
/** Deselect a specific item */
36
deselectItem(item: object): void;
37
/** Select all visible items */
38
selectAll(): void;
39
/** Deselect all items */
40
deselectAll(): void;
41
/** Expand item details */
42
expandItem(item: object): void;
43
/** Collapse item details */
44
collapseItem(item: object): void;
45
/** Clear internal data cache */
46
clearCache(): void;
47
/** Scroll to specific item */
48
scrollToIndex(index: number): void;
49
/** Recalculate column widths */
50
recalculateColumnWidths(): void;
51
}
52
53
/**
54
* Grid column definition
55
* Defines display and behavior for a data column
56
*/
57
interface GridColumn extends HTMLElement {
58
/** Property path in data items */
59
path: string;
60
/** Column header text */
61
header: string;
62
/** Column width */
63
width: string;
64
/** Minimum column width */
65
minWidth: string;
66
/** Maximum column width */
67
maxWidth: string;
68
/** Column can be resized */
69
resizable: boolean;
70
/** Column is frozen (always visible) */
71
frozen: boolean;
72
/** Column is hidden */
73
hidden: boolean;
74
/** Text alignment */
75
textAlign: 'start' | 'center' | 'end';
76
/** Custom renderer function */
77
renderer: (root: HTMLElement, column: GridColumn, model: GridItemModel) => void;
78
}
79
80
/**
81
* Grid item model for renderers
82
*/
83
interface GridItemModel {
84
index: number;
85
item: object;
86
selected: boolean;
87
expanded: boolean;
88
level: number;
89
}
90
91
/**
92
* Sortable grid column
93
*/
94
interface GridSortColumn extends GridColumn {
95
/** Sort direction */
96
direction: 'asc' | 'desc' | null;
97
/** Sort priority for multi-sort */
98
sortPriority: number;
99
}
100
101
/**
102
* Selection column for row selection
103
*/
104
interface GridSelectionColumn extends GridColumn {
105
/** Auto-select rows on click */
106
autoSelect: boolean;
107
/** Show select all checkbox in header */
108
selectAll: boolean;
109
}
110
111
/**
112
* Tree column for hierarchical data
113
*/
114
interface GridTreeColumn extends GridColumn {
115
/** Path to child items property */
116
itemHasChildrenPath: string;
117
/** Path to expanded state property */
118
itemExpandedPath: string;
119
}
120
```
121
122
**Usage Examples:**
123
124
```typescript
125
import '@vaadin/grid';
126
import '@vaadin/grid/vaadin-grid-column';
127
import '@vaadin/grid/vaadin-grid-selection-column';
128
129
// Basic grid setup
130
const grid = document.createElement('vaadin-grid');
131
grid.items = [
132
{ name: 'John Doe', email: 'john@example.com', age: 30 },
133
{ name: 'Jane Smith', email: 'jane@example.com', age: 25 },
134
{ name: 'Bob Johnson', email: 'bob@example.com', age: 35 }
135
];
136
137
// Add selection column
138
const selectionColumn = document.createElement('vaadin-grid-selection-column');
139
selectionColumn.autoSelect = true;
140
grid.appendChild(selectionColumn);
141
142
// Add data columns
143
const nameColumn = document.createElement('vaadin-grid-column');
144
nameColumn.path = 'name';
145
nameColumn.header = 'Name';
146
nameColumn.width = '200px';
147
grid.appendChild(nameColumn);
148
149
const emailColumn = document.createElement('vaadin-grid-column');
150
emailColumn.path = 'email';
151
emailColumn.header = 'Email';
152
grid.appendChild(emailColumn);
153
154
// Custom renderer for actions
155
const actionColumn = document.createElement('vaadin-grid-column');
156
actionColumn.header = 'Actions';
157
actionColumn.renderer = (root, column, model) => {
158
if (!root.firstElementChild) {
159
const button = document.createElement('vaadin-button');
160
button.textContent = 'Edit';
161
button.addEventListener('click', () => {
162
console.log('Edit user:', model.item);
163
});
164
root.appendChild(button);
165
}
166
};
167
grid.appendChild(actionColumn);
168
169
// Handle selection changes
170
grid.addEventListener('active-item-changed', (e) => {
171
console.log('Active item:', e.detail.value);
172
});
173
```
174
175
### Virtual List
176
177
High-performance list component with virtual scrolling for large datasets.
178
179
```typescript { .api }
180
/**
181
* Virtualized list component for rendering large datasets
182
* Only renders visible items for optimal performance
183
*/
184
interface VirtualList extends HTMLElement {
185
/** Array of data items */
186
items: object[];
187
/** Custom renderer function for items */
188
renderer: (root: HTMLElement, list: VirtualList, index: number, item: object) => void;
189
/** Height of each list item */
190
itemHeight: number;
191
/** Number of items to render outside viewport */
192
overscan: number;
193
194
/** Scroll to specific item index */
195
scrollToIndex(index: number): void;
196
/** Get first visible item index */
197
getFirstVisibleIndex(): number;
198
/** Get last visible item index */
199
getLastVisibleIndex(): number;
200
}
201
```
202
203
**Usage Examples:**
204
205
```typescript
206
import '@vaadin/virtual-list';
207
208
// Large dataset virtual list
209
const virtualList = document.createElement('vaadin-virtual-list');
210
211
// Generate large dataset
212
const items = Array.from({ length: 100000 }, (_, index) => ({
213
id: index,
214
name: `Item ${index}`,
215
description: `Description for item ${index}`
216
}));
217
218
virtualList.items = items;
219
220
// Custom item renderer
221
virtualList.renderer = (root, list, index, item) => {
222
if (!root.firstElementChild) {
223
root.innerHTML = `
224
<div class="item">
225
<div class="name"></div>
226
<div class="description"></div>
227
</div>
228
`;
229
}
230
231
const nameEl = root.querySelector('.name');
232
const descEl = root.querySelector('.description');
233
234
nameEl.textContent = item.name;
235
descEl.textContent = item.description;
236
};
237
238
// Scroll to specific item
239
setTimeout(() => {
240
virtualList.scrollToIndex(50000); // Scroll to middle
241
}, 1000);
242
```
243
244
## Advanced Data Patterns
245
246
### Grid with Lazy Loading
247
248
```typescript
249
// Grid with server-side data loading
250
const setupLazyGrid = (grid: Grid) => {
251
let cachedItems: Map<number, object> = new Map();
252
let totalItems = 0;
253
254
// Set up data provider
255
grid.dataProvider = (params, callback) => {
256
const { page, pageSize, sortOrders, filters } = params;
257
258
// Check cache first
259
const cacheKey = `${page}-${pageSize}`;
260
if (cachedItems.has(cacheKey)) {
261
callback(cachedItems.get(cacheKey), totalItems);
262
return;
263
}
264
265
// Load from server
266
const queryParams = new URLSearchParams({
267
page: page.toString(),
268
size: pageSize.toString(),
269
sort: sortOrders.map(s => `${s.path},${s.direction}`).join(';'),
270
filter: JSON.stringify(filters)
271
});
272
273
fetch(`/api/data?${queryParams}`)
274
.then(response => response.json())
275
.then(data => {
276
cachedItems.set(cacheKey, data.items);
277
totalItems = data.totalCount;
278
callback(data.items, data.totalCount);
279
})
280
.catch(error => {
281
console.error('Failed to load data:', error);
282
callback([], 0);
283
});
284
};
285
};
286
```
287
288
### Grid with Custom Cell Editors
289
290
```typescript
291
// Grid with inline editing capabilities
292
const setupEditableGrid = (grid: Grid) => {
293
// Add edit column with custom renderer
294
const editColumn = document.createElement('vaadin-grid-column');
295
editColumn.header = 'Name (Editable)';
296
editColumn.renderer = (root, column, model) => {
297
if (!root.firstElementChild) {
298
const textField = document.createElement('vaadin-text-field');
299
textField.style.width = '100%';
300
301
textField.addEventListener('change', (e) => {
302
// Update the item
303
model.item[column.path] = e.target.value;
304
305
// Trigger update event
306
grid.dispatchEvent(new CustomEvent('item-changed', {
307
detail: { item: model.item, path: column.path, value: e.target.value }
308
}));
309
});
310
311
root.appendChild(textField);
312
}
313
314
const textField = root.firstElementChild as any;
315
textField.value = model.item[column.path] || '';
316
};
317
318
grid.appendChild(editColumn);
319
};
320
```
321
322
### Tree Grid Implementation
323
324
```typescript
325
// Hierarchical data grid
326
const setupTreeGrid = () => {
327
const grid = document.createElement('vaadin-grid');
328
329
// Hierarchical data
330
const treeData = [
331
{
332
name: 'Frontend',
333
children: [
334
{ name: 'React', size: '2.1MB' },
335
{ name: 'Vue', size: '1.8MB' },
336
{ name: 'Angular', size: '4.2MB' }
337
]
338
},
339
{
340
name: 'Backend',
341
children: [
342
{ name: 'Node.js', size: '15MB' },
343
{ name: 'Python', size: '25MB' }
344
]
345
}
346
];
347
348
// Flatten tree data for grid
349
const flattenTree = (items: any[], level = 0): any[] => {
350
return items.reduce((acc, item) => {
351
acc.push({ ...item, level, expanded: false });
352
if (item.children) {
353
acc.push(...flattenTree(item.children, level + 1));
354
}
355
return acc;
356
}, []);
357
};
358
359
grid.items = flattenTree(treeData);
360
361
// Tree column with expand/collapse
362
const treeColumn = document.createElement('vaadin-grid-tree-column');
363
treeColumn.path = 'name';
364
treeColumn.header = 'Name';
365
treeColumn.itemHasChildrenPath = 'children';
366
grid.appendChild(treeColumn);
367
368
const sizeColumn = document.createElement('vaadin-grid-column');
369
sizeColumn.path = 'size';
370
sizeColumn.header = 'Size';
371
grid.appendChild(sizeColumn);
372
373
return grid;
374
};
375
```
376
377
### Data Export Functionality
378
379
```typescript
380
// Export grid data to various formats
381
const addExportCapability = (grid: Grid) => {
382
// Export to CSV
383
const exportToCsv = () => {
384
const columns = Array.from(grid.querySelectorAll('vaadin-grid-column'));
385
const headers = columns.map(col => col.header).join(',');
386
387
const rows = grid.items.map(item =>
388
columns.map(col => item[col.path] || '').join(',')
389
);
390
391
const csv = [headers, ...rows].join('\n');
392
393
const blob = new Blob([csv], { type: 'text/csv' });
394
const url = URL.createObjectURL(blob);
395
396
const a = document.createElement('a');
397
a.href = url;
398
a.download = 'data.csv';
399
a.click();
400
401
URL.revokeObjectURL(url);
402
};
403
404
// Export to JSON
405
const exportToJson = () => {
406
const data = JSON.stringify(grid.items, null, 2);
407
const blob = new Blob([data], { type: 'application/json' });
408
const url = URL.createObjectURL(blob);
409
410
const a = document.createElement('a');
411
a.href = url;
412
a.download = 'data.json';
413
a.click();
414
415
URL.revokeObjectURL(url);
416
};
417
418
// Add export buttons
419
const toolbar = document.createElement('div');
420
toolbar.className = 'grid-toolbar';
421
422
const csvButton = document.createElement('vaadin-button');
423
csvButton.textContent = 'Export CSV';
424
csvButton.addEventListener('click', exportToCsv);
425
426
const jsonButton = document.createElement('vaadin-button');
427
jsonButton.textContent = 'Export JSON';
428
jsonButton.addEventListener('click', exportToJson);
429
430
toolbar.appendChild(csvButton);
431
toolbar.appendChild(jsonButton);
432
433
grid.parentElement?.insertBefore(toolbar, grid);
434
};
435
```