Tree Grid
API: TypeScript / Java
Source: TypeScript / Java
Tree Grid is a component for displaying hierarchical tabular data grouped into expandable and collapsible nodes.
Open in a
new tab
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 .dataProvider="${this.dataProvider}">
<vaadin-grid-tree-column
path="firstName"
item-has-children-path="manager"
></vaadin-grid-tree-column>
<vaadin-grid-column path="lastName"></vaadin-grid-column>
<vaadin-grid-column path="email"></vaadin-grid-column>
</vaadin-grid>
`;
}
Note
|
Features shared with Grid
Tree Grid is an extension of the Grid component and all Grid’s features are available in Tree Grid as well.
|
Tree Column
The tree column is a column that 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.
Open in a
new tab
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'}"
.expandedItems="${this.expandedItems}"
>
<vaadin-grid-tree-column
path="firstName"
item-has-children-path="manager"
></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.
Open in a
new tab
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>
`;
}
Best Practices
Tree Grid isn’t meant to be used as a navigation menu.
Caution
|
scrollToIndex() isn’t reliablescrollToIndex() method in Tree Grid isn’t deterministic due to lazy-loading hierarchical data.
It isn’t recommended to use this method.
|