Tree Grid
Tree Grid is a component for displaying hierarchical tabular data grouped into expandable nodes.
- Usage
- Styling
Tree Grid is a component for displaying hierarchical tabular data grouped into expandable nodes.
Open in a
new tab
new tab
async function 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);
}
function Example() {
return (
<Grid itemHasChildrenPath="manager" dataProvider={dataProvider}>
<GridTreeColumn path="firstName" />
<GridColumn path="lastName" />
<GridColumn path="email" />
</Grid>
);
}
Note
|
Features Shared with Grid
Tree Grid is an extension of the Grid component. Therefore, all of Grid’s features are available in Tree Grid.
|
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
<HorizontalLayout
style={{ alignItems: 'center', height: 'var(--lumo-size-xl)' }}
theme="spacing"
>
<h3 style={{ flexGrow: 1, margin: 0 }}>Employee</h3>
<Button onClick={expandAll}>Expand All</Button>
<Button onClick={collapseAll}>Collapse All</Button>
</HorizontalLayout>
<Grid
dataProvider={dataProvider}
itemIdPath="id"
itemHasChildrenPath="manager"
expandedItems={expandedItems}
>
<GridTreeColumn path="firstName" />
<GridColumn path="lastName" />
<GridColumn path="email" />
</Grid>
Rich Content
Like Grid, Tree Grid supports rich content.
Open in a
new tab
new tab
const [expandedItems, setExpandedItems] = useState<Person[]>([]);
return (
<Grid dataProvider={dataProvider} expandedItems={expandedItems}>
<GridColumn autoWidth header="Employee">
{({ item: person, model }) => (
<GridTreeToggle
leaf={!person.manager}
level={model?.level ?? 0}
expanded={!!model?.expanded}
onClick={(e) => {
// The click listener needs to check if the event gets canceled (by
// vaadin-grid-tree-toggle) and only continue if it does.
// vaadin-grid-tree-toggle will cancel the event if the user clicks on
// a non-focusable element inside the toggle.
if (!e.defaultPrevented) {
return;
}
if (e.currentTarget.expanded) {
setExpandedItems([...expandedItems, person]);
} else {
setExpandedItems(expandedItems.filter((p) => p.id !== person.id));
}
}}
>
<HorizontalLayout style={{ alignItems: 'center' }} theme="spacing">
<Avatar img={person.pictureUrl} name={`${person.firstName} ${person.lastName}`} />
<VerticalLayout style={{ lineHeight: 'var(--lumo-line-height-m)' }}>
<span>
{person.firstName} {person.lastName}
</span>
<span
style={{
fontSize: 'var(--lumo-font-size-s)',
color: 'var(--lumo-secondary-text-color)',
}}
>
{person.profession}
</span>
</VerticalLayout>
</HorizontalLayout>
</GridTreeToggle>
)}
</GridColumn>
<GridColumn autoWidth header="Contact">
{({ item: person }) => (
<VerticalLayout
style={{
fontSize: 'var(--lumo-font-size-s)',
lineHeight: 'var(--lumo-line-height-m)',
}}
>
<a href={`mailto:${person.email}`} style={{ display: 'flex', alignItems: 'center' }}>
<Icon
icon="vaadin:envelope"
style={{
height: 'var(--lumo-icon-size-s)',
marginInlineEnd: 'var(--lumo-space-s)',
width: 'var(--lumo-icon-size-s)',
}}
/>
<span>{person.email}</span>
</a>
<a
href={`tel:${person.address.phone}`}
style={{ display: 'flex', alignItems: 'center' }}
>
<Icon
icon="vaadin:phone"
style={{
height: 'var(--lumo-icon-size-s)',
marginInlineEnd: 'var(--lumo-space-s)',
width: 'var(--lumo-icon-size-s)',
}}
/>
<span>{person.address.phone}</span>
</a>
</VerticalLayout>
)}
</GridColumn>
</Grid>
);