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);
}
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[] = [];
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.expandedItems = [...this.managers])}">
Expand All
</vaadin-button>
<vaadin-button @click="${() => (this.expandedItems = [])}">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>
`;
}
Rich Content
Like Grid, Tree Grid supports rich content.
Open in a
new tab
new tab
private employeeRenderer = (
root: HTMLElement,
_column?: GridColumnElement,
model?: GridItemModel<Person>
) => {
if (model?.item) {
const person = model.item;
render(
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>
`,
root
);
}
};
contactRenderer(root: HTMLElement, _column?: GridColumnElement, model?: GridItemModel<Person>) {
if (model?.item) {
const person = model.item;
render(
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>
`,
root
);
}
}
render() {
return html`
<vaadin-grid .dataProvider="${this.dataProvider}" .expandedItems="${this.expandedItems}">
<vaadin-grid-column
auto-width
header="Employee"
.renderer="${this.employeeRenderer}"
></vaadin-grid-column>
<vaadin-grid-column
auto-width
header="Contact"
.renderer="${this.contactRenderer}"
></vaadin-grid-column>
</vaadin-grid>
`;
}