DOCUMENTATION / API
API reference.
Everything needed to build a tree, inspect a model and connect interaction to your application. Start with the guide for a working example.
TreeView
TreeView creates the canvas, filter control, editor and tooltip inside a host element. Give that element a height. The package is JavaScript ESM with bundled declarations for editor autocomplete. The element, canvas, controller and destroyed properties expose the mounted view state.
import { TreeView } from 'virtual-tree-canvas';
const view = new TreeView(host, { filter: true, initialExpandDepth: 2 });
view.setData(nodes);
view.on('selectionchange', ({ detail }) => console.log(detail.selection));
// On permanent unmount: view.destroy();| Method | What it does |
|---|---|
configure(options) / flush() | Apply a configuration patch. Changes are batched; flush() applies a pending patch immediately. |
setData(nodes) / setModel(model, meta?) | Install application rows or inspect a JavaScript value. Either call switches to the matching mode. |
setColumns(columns) / setTheme(theme) | Replace the columns or theme. Pass null to setColumns for the current presentation's defaults. |
setDynamicState(patches) | Patch live values by row ID without reinstalling the tree. |
setInspectorValue(path, value, options?) | Write a model value by property path. Returns whether the write was accepted; use { emit: false } to suppress edit events. |
on(type, listener) / off(type, listener) | Subscribe to component events or remove a listener. on returns an unsubscribe function. |
registerIcon(name, source) | Register an application SVG URL, SVG string, image or Canvas draw function. |
destroy() | Release observers, events, editors and rendering resources on permanent unmount. |
Configuration options
Pass these to the constructor or view.configure(options). The component defaults to one selected row, an editable tree and a visible filter.
| Option | Purpose |
|---|---|
mode, presentation | 'tree' or 'inspector'; inspector layout 'pane' or 'table'. |
nodes, model, meta | Initial row data or inspected value and metadata. Explicit setData and setModel calls are also available. |
columns, theme | Column definitions and a built-in theme name or theme object. |
filter, filterPlacement | Show the built-in filter (default true). Placement: 'auto', 'bar' or 'header'. Hiding it retains the current query; call clearFilter() to clear it. |
editable, multiSelect | Allow editing (default true) and multiple selected rows (default false). |
rowReorder, rowActions, rowDrag | Sibling order controls, row buttons and data drag payloads. Each is optional. |
initialExpandDepth, flatRoot, enforceMeta | Control initial expansion and inspector structure. Expansion depth applies when installing data. |
showHeader, headerHeight | Show or hide column headings and set their height. Hiding headings does not hide the filter bar. |
rowHeight, indentWidth, fontFamily | Layout metrics and text font. Explicit row and indent sizes override theme values. |
iconResolver, markUpdated | Map row icons without mutating nodes; mark changed inspector values. |
scrollChaining | Let wheel scrolling reach an ancestor at the tree's edges. Default false. |
iconsBaseUrl, iconRegistry, nativeScrollbars | Constructor-only icon and scrollbar options. Built-in icons need no asset URL. |
Rows, live values, search and filtering
For setData, each row needs a stable id. Use parentId for children. Optional row fields include label, type, icon, image, tags, data and reorderable. Dynamic patches have an id and a state object, such as { id: 'btc', state: { value: 42 } }.
The built-in filter is enabled by default and keeps matching descendants visible with their ancestors. Search highlights matches and can move focus. Use filtering to narrow the visible tree; use search to navigate results. Compare the bar above the large tree and the header filter in the units table.
view.setFilter('radar');
view.setFilter('radar', { caseSensitive: true, wholeWord: true });
view.setFilter((node, state) => state.status === 'warning');
view.clearFilter();
view.search('radar');
view.nextSearchResult();
view.clearSearch();| Method | What it does |
|---|---|
setFilter(queryOrPredicate, options?) / clearFilter() | Filter visible rows with text or a predicate; text options are caseSensitive and wholeWord. |
search(query, options?) / clearSearch() | Highlight matches and clear them. Search options include limit, fields, expand, focus and select. |
getSearchState() / nextSearchResult() / previousSearchResult() | Read the current query and results or navigate between them. |
focusNode(id, options?) / scrollToNode(id, align?) | Focus a row or scroll to it. Alignment is 'start', 'center', 'end' or 'nearest'. |
expandAll() / collapseAll() | Change expansion for the whole tree. |
Columns, sorting and themes
Use builtInColumns or define columns with id, label, width, minWidth, align, kind and sortable. Kinds include tree, status, value, progress, type, updated and text. value(node, state) supplies the raw value; format(value, node, state) changes displayed text and tooltips without changing sort order. render(ctx, cell) draws custom Canvas2D content.
Sorting orders siblings within their parent, preserving the hierarchy. Click a heading to cycle ascending, descending and unsorted, or use view.controller.sortBy(id, direction). The raw value is compared, so formatting a number as a string does not turn numeric sorting into lexical sorting.
import { builtInColumns, lightTheme } from 'virtual-tree-canvas';
view.setColumns([
builtInColumns.tree,
{
id: 'change', label: '24h %', kind: 'value', width: 90,
value: (_node, state) => state.change,
valueType: (value) => value > 0 ? 'positive' : value < 0 ? 'negative' : 'neutral',
format: (value) => `${value.toFixed(2)}%`
}
]);
view.setTheme({ ...lightTheme, valueColors: {
...lightTheme.valueColors, positive: '#15803d', negative: '#be123c'
} });valueType can be a fixed semantic name or a callback. Its colour comes from theme.valueColors; it does not change formatting or sorting. Built-in darkTheme and lightTheme are available, and theme.statuses customizes status pills.
Column helpers include builtInColumns, defaultTreeTableColumns() and inspectorColumns(). For icons, builtinIconNames lists bundled names. registerIcon() accepts a custom source; iconsBaseUrl points to a replacement SVG directory. Applications sharing icons across views can supply an IconRegistry and use its register(), get(), prepare() and draw() methods.
Object inspector metadata
setModel(model, meta?) makes property rows from an object or array. No IDs are required. Metadata keys are property paths such as 'sensor.range' or wildcard paths such as 'tracks.*.speed'. Use presentation: 'pane' for compact controls or 'table' for Property / Value columns.
| Metadata | Purpose |
|---|---|
min, max, step, integer | Numeric editor and range bounds. |
unit, precision | Display-only suffix and decimal places; the stored numeric value retains its precision. |
readonly, disabled, updated | Editing state and changed-value indication. |
options, color, button | Choice editor, colour editor or action button. |
label, description, type, icon | Property text and visual identity. |
itemType, itemTitle, itemFactory | Array item editor type, object summary and value used when adding an item. |
fullWidthButton | Span the available inspector row for a button. |
Array items use compact indexed rows; primitive values edit in the row, while objects and nested arrays expand. The inspector emits valuechange for a value edit, modelchange for model changes and action for metadata buttons.
Selection, order, actions and data drag
Selection is single row by default. With multiSelect: true, Ctrl/Command + click toggles rows, Shift + click selects a range, and Shift + drag selects a visible range. An ordinary click still selects one row.
| Method or option | What it does |
|---|---|
getSelection() / setSelection(ids) / clearSelection() | Read, replace or clear selected IDs. Single-selection mode keeps at most one ID. |
rowReorder: true | Add a dedicated handle to reorder siblings in setData trees. Sorting and filtering temporarily disable manual order. |
getRowOrder(parentId?) / moveRow(id, index) / moveRowBy(id, offset) | Read or change sibling order programmatically. moveRow and moveRowBy return whether a move occurred. |
rowActions | Accessible row buttons or checkboxes with id, label, optional icon, visible, disabled, pressed or checked. |
rowDrag(node, state) | Return a data payload or null to disable dragging for a row. A plain drag exports the source row or the selected group. |
The component emits drag events with the selected items, nodeIds and pointer event. Your application decides where a drop is valid and updates its data. See the two-tree transfer example.
Events
Subscribe with view.on(type, listener). Each listener receives an event whose payload is event.detail. Unsubscribe with the function returned by on, or use off.
| Events | When they fire |
|---|---|
selectionchange, focuschange | Selected IDs or focused row changes. |
filterchange, searchchange | Visible rows change due to filtering, or search results change. |
expand, collapse, sortchange | Tree expansion or column sort changes. |
nodeclick, nodedblclick, nodecontextmenu, nodehover | Pointer interaction with a row. |
valuechange, modelchange, action | Inspector edit, model update or metadata action. |
rowaction, rowreorder | Row button activation or sibling order change. |
rowdragstart, rowdragmove, rowdragend, rowdragcancel | Data drag lifecycle. The host handles destination and drop. |
columnschange, viewportchange, layoutchange | Column or viewport layout changes. |
Lower-level controller
Use TreeViewController when your application already owns the canvas and render loop. view.controller exposes the same controller inside a TreeView. Methods shared with TreeView work on both; the controller also provides the operations below.
import { TreeViewController } from 'virtual-tree-canvas';
const tree = new TreeViewController({ canvas, host, autoRender: true });
tree.setData(nodes);
tree.sortBy('value', 'asc');
// On permanent unmount: tree.destroy();| Method | What it does |
|---|---|
expand(id) / collapse(id) / toggle(id) | Change one branch; each returns whether its expansion state changed. |
sortBy(id, direction?) / clearSort() | Sort siblings by a column or restore their original order. Direction is 'asc', 'desc' or 'toggle'. |
resizeColumn(id, width) / moveColumn(id, index) | Change column geometry or order. |
setRowActions(actions) / setRowDrag(resolver) | Replace row actions or data drag resolver without rebuilding rows. |
setEditable(enabled) / setMultiSelect(enabled) / setRowReorder(enabled) | Change interaction modes directly on the controller. |
setInitialExpandDepth(depth) / setIconResolver(resolver) | Set defaults for future data installations and map row icons without changing input rows. |
setInspectorOptions(options) / setHeaderFilter(enabled) | Set inspector options or place its filter in the first column heading. |
setModel(model, meta?, options?) | Controller form of model inspection; the third argument accepts presentation and inspector options. |
updateInspectorValue(id, value) / closeEditor() | Update an inspector row by node ID or close its active editor. setInspectorValue(path, value) is easier when a property path is known. |
enableWorkers(url?) / disableWorkers() | Enable or stop optional worker processing for search and filtering. Enabling returns a promise. |
searchAsync(query, options?) / setFilterAsync(query, options?) | Use a worker when enabled; otherwise use the synchronous implementation. |
render() / requestRender() / getStats() | Draw immediately, schedule a draw or inspect component metrics. renderMeasured() returns timing details. |
resize(width, height) / setLayoutMetrics(options) | Update canvas size or row, indent and heading metrics. |
scrollTo(x, y) / hitTest(x, y) | Control scrolling or find the canvas element at client coordinates. getViewportState() reads current dimensions and offsets. |
initialize(canvas) / attachInput() / attachCellEditor() / attachTooltip() | Attach controller facilities when assembling a custom host. |
The large-tree demo exercises asynchronous filtering and exposes live render metrics. The inspector demo shows the pane and table presentations.