Tree Plugin
The Tree plugin transforms your flat grid into a hierarchical tree view with expandable parent-child relationships. Great for file explorers, organizational charts, nested categories, or any data with a natural hierarchy.
Installation
Section titled “Installation”import '@toolbox-web/grid/features/tree';Basic Usage
Section titled “Basic Usage”Just point the feature at the field containing child items (defaults to children) and the grid handles all the expand/collapse behavior, indentation, and icons automatically.
import { queryGrid } from '@toolbox-web/grid';
const grid = queryGrid('tbw-grid');grid.gridConfig = { columns: [ { field: 'name', header: 'Name' }, { field: 'type', header: 'Type' }, { field: 'size', header: 'Size' } ], features: { tree: { childrenField: 'children', indentWidth: 24, }, },};
grid.rows = [ { id: 1, name: 'Documents', type: 'folder', children: [ { id: 2, name: 'Work', type: 'folder', children: [ { id: 3, name: 'Report.docx', type: 'file', size: '24 KB' } ]}, { id: 4, name: 'Personal', type: 'folder', children: [] } ] },];import '@toolbox-web/grid-react/features/tree';import { DataGrid } from '@toolbox-web/grid-react';
function FileExplorer({ files }) { return ( <DataGrid rows={files} columns={[ { field: 'name', header: 'Name' }, { field: 'type', header: 'Type' }, { field: 'size', header: 'Size' } ]} tree={{ childrenField: 'children', indentWidth: 24 }} /> );}<script setup>import '@toolbox-web/grid-vue/features/tree';import { TbwGrid, TbwGridColumn } from '@toolbox-web/grid-vue';
const files = [ { id: 1, name: 'Documents', type: 'folder', children: [ { id: 2, name: 'Work', type: 'folder', children: [{ id: 3, name: 'Report.docx', type: 'file', size: '24 KB' }] }, { id: 4, name: 'Personal', type: 'folder', children: [] }, ], },];</script>
<template> <TbwGrid :rows="files" :tree="{ childrenField: 'children', indentWidth: 24 }"> <TbwGridColumn field="name" header="Name" /> <TbwGridColumn field="type" header="Type" /> <TbwGridColumn field="size" header="Size" /> </TbwGrid></template>// Feature import - enables the [tree] inputimport '@toolbox-web/grid-angular/features/tree';
import { Component } from '@angular/core';import { Grid } from '@toolbox-web/grid-angular';import type { ColumnConfig } from '@toolbox-web/grid';
@Component({ selector: 'app-file-explorer', imports: [Grid], template: ` <tbw-grid [rows]="files" [columns]="columns" [tree]="{ childrenField: 'children', indentWidth: 24 }" style="height: 400px; display: block;"> </tbw-grid> `,})export class FileExplorerComponent { files = [/* hierarchical data */];
columns: ColumnConfig[] = [ { field: 'name', header: 'Name' }, { field: 'type', header: 'Type' }, { field: 'size', header: 'Size' } ];}Toggle the controls to explore animation, indentation, and expand behavior.
<tbw-grid style="height: 400px;"></tbw-grid>import '@toolbox-web/grid';import { queryGrid } from '@toolbox-web/grid';import '@toolbox-web/grid/features/tree';
const fileSystemData = [ { name: 'Documents', type: 'folder', size: '-', children: [ { name: 'Resume.pdf', type: 'file', size: '2.4 MB' }, { name: 'Cover Letter.docx', type: 'file', size: '156 KB' }, { name: 'Projects', type: 'folder', size: '-', children: [ { name: 'Project A', type: 'folder', size: '-', children: [{ name: 'notes.txt', type: 'file', size: '12 KB' }] }, { name: 'Project B', type: 'folder', size: '-' }, ], }, ], }, { name: 'Pictures', type: 'folder', size: '-', children: [ { name: 'vacation.jpg', type: 'file', size: '4.2 MB' }, { name: 'family.png', type: 'file', size: '3.1 MB' }, ], }, { name: 'readme.md', type: 'file', size: '1 KB' },];const columns = [ { field: 'name', header: 'Name' }, { field: 'type', header: 'Type' }, { field: 'size', header: 'Size' },];
const grid = queryGrid('tbw-grid')!;
function rebuild(opts: Record<string, unknown>) { grid.gridConfig = { columns, features: { tree: { animation: opts.animation === 'false' ? false : (opts.animation as string) ?? 'slide', childrenField: 'children', defaultExpanded: opts.defaultExpanded as boolean ?? false, indentWidth: (opts.indentWidth as number) ?? 20, showExpandIcons: opts.showExpandIcons as boolean ?? true, } as any, }, }; grid.rows = fileSystemData;}
rebuild({ animation: 'slide', defaultExpanded: false, indentWidth: 20, showExpandIcons: true });Configuration Options
Section titled “Configuration Options”See TreeConfig for the full list of options and defaults.
Animation Options
Section titled “Animation Options”The animation option controls how child nodes appear/disappear:
// Slide animation (default)features: { tree: { animation: 'slide', ... } }
// Fade animationfeatures: { tree: { animation: 'fade', ... } }
// No animationfeatures: { tree: { animation: false, ... } }Programmatic API
Section titled “Programmatic API”const plugin = grid.getPluginByName('tree');
plugin.expand(key); // Expand a node by keyplugin.collapse(key); // Collapse a node by keyplugin.toggle(key); // Toggle a node's expanded stateplugin.expandAll(); // Expand all nodesplugin.collapseAll(); // Collapse all nodesplugin.expandToKey(key); // Expand all ancestors to reveal a nodeconst keys = plugin.getExpandedKeys(); // Get currently expanded node keysconst expanded = plugin.isExpanded(key); // Check if a node is expandedconst rows = plugin.getFlattenedRows(); // Get flattened tree rows with metadataconst row = plugin.getRowByKey(key); // Find a row by its keyEvents
Section titled “Events”tree-expand
Section titled “tree-expand”Fired when a node is expanded or collapsed (via click or keyboard):
grid.on('tree-expand', ({ key, row, expanded, depth }) => { console.log(`${expanded ? 'Expanded' : 'Collapsed'} node ${key} at depth ${depth}`);});See TreeExpandDetail for the full event payload type.
tree-state-change
Section titled “tree-state-change”Fired when the overall expansion state changes (via toggle(), expandAll(), or collapseAll()):
grid.on('tree-state-change', ({ expandedKeys }) => { console.log(`${expandedKeys.length} nodes expanded`);});Styling
Section titled “Styling”The tree plugin supports CSS custom properties for theming. Override these on tbw-grid or a parent container:
CSS Custom Properties
Section titled “CSS Custom Properties”| Property | Default | Description |
|---|---|---|
--tbw-tree-toggle-size | 1.25em (~20px) | Toggle icon and spacer width |
--tbw-tree-indent-width | var(--tbw-tree-toggle-size) | Indentation per level (must be ≥ toggle size) |
--tbw-tree-accent | var(--tbw-color-accent) | Toggle icon hover color |
--tbw-animation-duration | 200ms | Expand/collapse animation |
--tbw-animation-easing | ease-out | Animation curve |
Example
Section titled “Example”tbw-grid { /* Custom tree styling */ --tbw-tree-toggle-size: 1.5em; /* Larger toggle icons */ --tbw-tree-indent-width: 1.75em; /* Slightly wider indent */ --tbw-tree-accent: #10b981; --tbw-animation-duration: 150ms;}CSS Classes
Section titled “CSS Classes”The tree plugin uses these class names:
| Class | Element |
|---|---|
.tree-cell-wrapper | Cell content wrapper with indentation |
.tree-expander | Expander cell container |
.tree-toggle | Expand/collapse icon |
.tree-spacer | Indent spacer element |
.tbw-tree-slide-in | Child row slide animation |
.tbw-tree-fade-in | Child row fade animation |
See Also
Section titled “See Also”- Row Grouping — Group rows by field values
- Master-Detail — Expandable detail panels
- Pivot — Pivot table with row grouping