Tree Grid
- Usage
- Styling
Tree Grid is a component for displaying hierarchical tabular data grouped into expandable nodes.
new tab
async dataProvider(
params: GridDataProviderParams<Person>,
callback: GridDataProviderCallback<Person>
) {
// The requested page and the full length of the corresponding
// hierarchy level is requested from the data service
const { people, hierarchyLevelSize } = await getPeople({
count: params.pageSize,
startIndex: params.page * params.pageSize,
managerId: params.parentItem ? params.parentItem.id : null,
});
callback(people, hierarchyLevelSize);
}
protected override render() {
return html`
<vaadin-grid .itemHasChildrenPath="${'manager'}" .dataProvider="${this.dataProvider}">
<vaadin-grid-tree-column path="firstName"></vaadin-grid-tree-column>
<vaadin-grid-column path="lastName"></vaadin-grid-column>
<vaadin-grid-column path="email"></vaadin-grid-column>
</vaadin-grid>
`;
}
Note
| Tree Grid is an extension of the Grid component. Therefore, all of Grid’s features are available in Tree Grid. However, Tree Grid isn’t meant to be used as a navigation menu. |
Tree Column
The tree column contains the toggles for expanding and collapsing nodes. Nodes are opened and closed by clicking a tree column’s cell. They can also be toggled programmatically.
new tab
@state()
private expandedItems: unknown[] = [];
protected override render() {
return html`
<vaadin-horizontal-layout
style="align-items: center; height: var(--lumo-size-xl);"
theme="spacing"
>
<h3 style="flex-grow: 1; margin: 0;">Employee</h3>
<vaadin-button @click="${this.expandAll}">Expand All</vaadin-button>
<vaadin-button @click="${this.collapseAll}">Collapse All</vaadin-button>
</vaadin-horizontal-layout>
<vaadin-grid
.dataProvider="${this.dataProvider}"
.itemIdPath="${'id'}"
.itemHasChildrenPath="${'manager'}"
.expandedItems="${this.expandedItems}"
>
<vaadin-grid-tree-column path="firstName"></vaadin-grid-tree-column>
<vaadin-grid-column path="lastName"></vaadin-grid-column>
<vaadin-grid-column path="email"></vaadin-grid-column>
</vaadin-grid>
`;
}
private expandAll() {
this.expandedItems = [...this.managers];
}
private collapseAll() {
this.expandedItems = [];
}
Rich Content
Like Grid, Tree Grid supports rich content.
new tab
private employeeRenderer: GridColumnBodyLitRenderer<Person> = (person, model) => html`
<vaadin-grid-tree-toggle
.leaf="${!person.manager}"
.level="${model.level ?? 0}"
@expanded-changed="${(e: GridTreeToggleExpandedChangedEvent) => {
if (e.detail.value) {
this.expandedItems = [...this.expandedItems, person];
} else {
this.expandedItems = this.expandedItems.filter((p) => p.id !== person.id);
}
}}"
.expanded="${!!model.expanded}"
>
<vaadin-horizontal-layout style="align-items: center;" theme="spacing">
<vaadin-avatar
img="${person.pictureUrl}"
name="${`${person.firstName} ${person.lastName}`}"
></vaadin-avatar>
<vaadin-vertical-layout style="line-height: var(--lumo-line-height-m);">
<span>${person.firstName} ${person.lastName}</span>
<span
style="font-size: var(--lumo-font-size-s); color: var(--lumo-secondary-text-color);"
>
${person.profession}
</span>
</vaadin-vertical-layout>
</vaadin-horizontal-layout>
</vaadin-grid-tree-toggle>
`;
private contactRenderer: GridColumnBodyLitRenderer<Person> = (person) => html`
<vaadin-vertical-layout
style="font-size: var(--lumo-font-size-s); line-height: var(--lumo-line-height-m);"
>
<a href="mailto:${person.email}" style="align-items: center; display: flex;">
<vaadin-icon
icon="vaadin:envelope"
style="height: var(--lumo-icon-size-s); margin-inline-end: var(--lumo-space-s); width: var(--lumo-icon-size-s);"
></vaadin-icon>
<span>${person.email}</span>
</a>
<a href="tel:${person.address.phone}" style="align-items: center; display: flex;">
<vaadin-icon
icon="vaadin:phone"
style="height: var(--lumo-icon-size-s); margin-inline-end: var(--lumo-space-s); width: var(--lumo-icon-size-s);"
></vaadin-icon>
<span>${person.address.phone}</span>
</a>
</vaadin-vertical-layout>
`;
protected override render() {
return html`
<vaadin-grid .dataProvider="${this.dataProvider}" .expandedItems="${this.expandedItems}">
<vaadin-grid-column
auto-width
header="Employee"
${columnBodyRenderer(this.employeeRenderer, [])}
></vaadin-grid-column>
<vaadin-grid-column
auto-width
header="Contact"
${columnBodyRenderer(this.contactRenderer, [])}
></vaadin-grid-column>
</vaadin-grid>
`;
}
Programmatic Scrolling
Grid supports programmatic navigation to a specific row. This is particularly useful when dealing with large data sets. It saves users from having to scroll through potentially hundreds or thousands of rows.
To use this feature, you need to specify the index of the row you want to view. The scroll position of the grid will then be adjusted to bring that row into view.
With multiple levels of hierarchy, you need to specify the row index for each level, separately. For example, to scroll to the second child-row (index 1) of the third root-level row (index 2), you would provide the indexes 2, 1.