
wunderbaum is a zero-dependency JavaScript tree and treegrid library for hierarchical data with multi-selection, filtering, sorting, inline node editing, drag and drop, lazy loading, and keyboard navigation.
Use it as a plain tree or define columns for a multi-column treegrid. Data can come from local node arrays or remote requests.
Features
- Tree and treegrid modes share one hierarchical node model.
- Static arrays and remote requests can populate the tree.
- Lazy loading defers child data until a branch opens.
- Single, multiple, and hierarchical selection modes.
- Fuzzy filtering, branch matching, highlighting, and hide or dim modes.
- Resizable treegrid columns with optional sort, filter, and menu controls.
- Inline node-title editing with configurable triggers and validation hooks.
- Drag-and-drop callbacks for before, after, and child insertion.
- Lazy row rendering for large hierarchical datasets.
- ESM and UMD builds with TypeScript declarations.
Use Cases
- File and folder explorers with lazy directory branches, keyboard navigation, and drag-and-drop moves.
- Administrative data trees that place owner, status, size, or other fields beside hierarchical titles.
- Permission and configuration panels with hierarchical checkboxes, radio groups, and non-selectable nodes.
- Large category, asset, or product hierarchies that need remote loading, filtering, sorting, and inline edits.
How to Use wunderbaum
Installation
Load the wunderbaum library directly in the HTML
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css" /> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/wunderbaum@0/dist/wunderbaum.css" /> <script src="https://cdn.jsdelivr.net/npm/wunderbaum@0/dist/wunderbaum.umd.min.js"></script>
Or Install it with npm
Install the package, import the Wunderbaum class, and load dist/wunderbaum.css through your stylesheet or bundler setup.
npm install wunderbaum
import { Wunderbaum } from "wunderbaum";
Basic Usage
Only element is mandatory during initialization. Each node needs a title.
<div id="demo-tree" style="height: 320px;"></div>
<script>
const tree = new mar10.Wunderbaum({
element: "#demo-tree",
source: [
{
title: "Documents",
key: "documents",
expanded: true,
children: [
{ title: "Invoices", key: "invoices" },
{ title: "Reports", key: "reports" },
],
},
{
title: "Media",
key: "media",
children: [
{ title: "Images", key: "images" },
{ title: "Videos", key: "videos" },
],
},
],
activate: (e) => {
console.log(e.node.key, e.node.title);
},
});
</script>
Data Sources And Node Format
Node Data
Nested source objects use these public node fields:
title(string, required): Node title. HTML is escaped.key(string): Unique node key. A sequence value is generated when omitted.refKey(string): Non-unique reference key used to identify clone nodes.children(WbNodeData[]): Nested child nodes.expanded(boolean): Initial expansion state.lazy(boolean): Marks a node for deferred child loading.selected(boolean): Initial selection state.checkbox(boolean | "radio"): Overrides the checkbox presentation for this node.radiogroup(boolean): Makes direct children behave as a radio group.unselectable(boolean): Prevents node selection.classes(string): Extra classes applied to the node row.colspan(boolean): Displays only the title cell across a treegrid row.icon(boolean | string): Overrides or hides the node icon.iconTooltip(boolean | string): Tooltip for the node icon.tooltip(boolean | string): Tooltip for the title.trueuses the node title.type(string): References an entry from the tree’stypesmap.statusNodeType: Status row type such asloading,error,noData, orpaging.
const tree = new mar10.Wunderbaum({
element: "#demo-tree",
source: [
{
title: "Quarterly Report",
key: "report-q3",
type: "document",
owner: "Alex",
size: 148000,
modified: "2026-09-10",
},
],
});
const node = tree.findKey("report-q3");
console.log(node.data.owner);
console.log(node.data.size);
Remote Source Object
A request source accepts:
url(string, required): Request URL.params: Query parameters.body: Request body. Supplying a body uses a POST request by default.options(RequestInit): Native Fetch request options.
const tree = new mar10.Wunderbaum({
element: "#demo-tree",
source: {
url: "/api/tree",
params: {
project: "frontend",
},
body: {
active: true,
},
options: {
headers: {
"X-App-Version": "2",
},
},
},
});
A string is the compact form for a simple remote source:
const tree = new mar10.Wunderbaum({
element: "#demo-tree",
source: "/api/tree",
});
Structured Source Objects
A source object can carry tree metadata beside its child data:
children: Node data.types: Shared node type definitions.columns: Treegrid column definitions._format("nested" | "flat"): Transfer format._version(number): Transfer format version._keyMap: Maps shortened JSON property names to node property names._valueMap: Maps numeric values to reusable string values._positional: Defines positional property order for the flat format.
The nested object form can place shared type and column definitions beside the node list:
const tree = new mar10.Wunderbaum({
element: "#demo-tree",
source: {
types: {
folder: {
icon: "bi bi-folder",
classes: "folder-row",
},
},
children: [
{
title: "Documents",
type: "folder",
},
],
},
});
Lazy Loading
Mark an unloaded branch with lazy: true and return its child source from lazyLoad.
const tree = new mar10.Wunderbaum({
element: "#demo-tree",
source: [
{
title: "Customers",
key: "customers",
lazy: true,
},
],
lazyLoad: (e) => {
return {
url: "/api/tree/children",
params: {
parentKey: e.node.key,
},
};
},
});
Methods that load lazy branches return Promises where asynchronous work is required:
await tree.expandAll();
const node = tree.findKey("customers");
if (node) {
await node.setExpanded(true);
}
Convert External API Data
Return converted node data from receive when an endpoint uses another response structure.
const tree = new mar10.Wunderbaum({
element: "#demo-tree",
source: {
url: "/api/categories",
},
receive: (e) => {
return e.response.map((item) => ({
title: item.name,
refKey: String(item.id),
lazy: item.hasChildren,
}));
},
});
Create A TreeGrid
Passing columns changes the control from a plain tree into a treegrid. The * column holds the hierarchical title.
Use render for additional cell content:
const tree = new mar10.Wunderbaum({
element: "#demo-tree",
columns: [
{
id: "*",
title: "Name",
width: 3,
resizable: true,
},
{
id: "owner",
title: "Owner",
width: 1,
},
{
id: "size",
title: "Size",
width: 1,
},
],
source: [
{
title: "Report.pdf",
owner: "Alex",
size: "148 KB",
},
{
title: "Budget.xlsx",
owner: "Sam",
size: "92 KB",
},
],
render: (e) => {
for (const col of Object.values(e.renderColInfosById)) {
col.elem.textContent = e.node.data[col.id] ?? "";
}
},
});
Column Definition Reference
id(string): Column identifier. Use"*"for the hierarchical title column.title(string): Header text.tooltip(string): Header tooltip.width(string | number): Pixel width or relative numeric weight.minWidth(string | number): Minimum width for a relative column.resizable(boolean): Displays the column resize handle.customWidthPx(number): Current custom width after a user resize.filterable(boolean): Displays a filter control.filterActive(boolean): Marks the filter control as active.sortable(boolean): Displays a sort control.sortOrder("asc" | "desc" | undefined): Current sort state.menu(boolean): Displays a column menu control.classes(string): Classes for header and data cells.headerClasses(string): Classes for the header cell only.html(string): HTML inserted into cells for that column.
Filter Nodes
filterNodes() accepts a search string, regular expression, or callback.
tree.filterNodes("report", {
mode: "hide",
fuzzy: true,
highlight: true,
});
Remove the active filter with:
tree.clearFilter();
Filter Options
autoApply(boolean, defaulttrue): Reapplies the filter after lazy data loads.autoExpand(boolean, defaultfalse): Expands branches that contain matches.matchBranch(boolean, defaultfalse): Includes descendants of matching branches.fuzzy(boolean, defaultfalse): Matches ordered characters such asfbagainstFooBar.hideExpanders(boolean, defaultfalse): Hides expanders when filtering removes all visible children.highlight(boolean, defaulttrue): Wraps matching text in<mark>for string filters.leavesOnly(boolean, defaultfalse): Matches end nodes only.mode(null | "mark" | "dim" | "hide", default"dim"): Unmatched-node presentation.noData(boolean | string, defaulttrue): Displays a status row when no nodes match.connect(FilterConnectType | null, defaultnull): Experimental connection to external filter controls.
filter.connect accepts:
inputElem: Search input element or selector.modeButton: Element or selector used to change filter mode.nextButton: Element or selector used to activate the next match.prevButton: Element or selector used to activate the previous match.matchInfoElem: Element or selector that displays match information.
Configure Selection
The selectMode option accepts:
"single": One selected node."multi": Independent multiple selection. This is the default."hier": Hierarchical selection with parent and descendant state propagation.
const tree = new mar10.Wunderbaum({
element: "#demo-tree",
checkbox: true,
selectMode: "hier",
source: treeData,
});
const selectedNodes = tree.getSelectedNodes();
console.log(selectedNodes.map((node) => node.key));
Edit Node Titles
Configure node-title editing through the edit option:
const tree = new mar10.Wunderbaum({
element: "#demo-tree",
edit: {
trigger: ["clickActive", "F2", "macEnter"],
apply: (e) => {
e.node.setTitle(e.inputElem.value);
},
},
source: treeData,
});
Edit Options
debounce(number, default100): Debounce interval for grid-cell change handling.minlength(number, default1): Minimum title length.maxlength(number | null, defaultnull): Maximum title length.trigger(string[], default[]): Edit triggers such as"clickActive","F2", and"macEnter".trim(boolean, defaulttrue): Trims whitespace before saving.select(boolean, defaulttrue): Selects the full title when editing begins.slowClickDelay(number, default1000): Maximum interval used byclickActive.validity(boolean, defaulttrue): Applies input validity feedback during editing.beforeEdit: Runs before edit mode and can cancel editing or return custom input markup.edit: Runs after the title input is created.apply: Handles the edited value.
Drag And Drop Nodes
Drag-and-drop callbacks describe the requested operation. Update the node model in drop when the operation should change the tree.
const tree = new mar10.Wunderbaum({
element: "#demo-tree",
dnd: {
dragStart: () => true,
dragEnter: () => true,
drop: (e) => {
e.sourceNode.moveTo(
e.node,
e.suggestedDropMode
);
},
},
source: treeData,
});
Drag And Drop Options
autoExpandMS(default1500): Hover delay before a collapsed node expands.multiSource(defaultfalse): Multi-node drag setting.effectAllowed(default"all"): Accepted values arenone,copy,copyLink,copyMove,link,linkMove,move, andall.dropEffectDefault(default"move"): Default copy, link, or move operation.guessDropEffect(boolean, defaulttrue): Resolves the operation from DnD settings and modifier keys.preventForeignNodes(boolean, defaultfalse): Rejects nodes from another wunderbaum instance.preventLazyParents(boolean, defaulttrue): Rejects unloaded lazy drop parents.preventNonNodes(boolean, defaultfalse): Rejects external non-node data.preventRecursion(boolean, defaulttrue): Blocks moves into a node’s descendants.preventSameParent(boolean, defaultfalse): Blocks drops under the current direct parent.preventVoidMoves(boolean, defaulttrue): Blocks no-op moves.serializeClipboardData(boolean | function, defaulttrue): Serializes node data intoDataTransfer.scroll(boolean, defaulttrue): Activates edge scrolling during dragging.scrollSensitivity(default20): Active top and bottom scroll area in pixels.scrollSpeed(default5): Scroll distance per update.sourceCopyHook(defaultnull): Hook passed to node serialization.dragStart: Runs when dragging begins. Returntrueto accept the drag.drag: Runs during dragging.dragEnd: Runs when dragging finishes.dragEnter: Defines accepted drop regions.dragOver: Runs while the pointer moves over a drop node.dragExpand: Can cancel automatic branch expansion.drop: Handles an accepted drop.dragLeave: Runs when the dragged object leaves a node.
All Configuration Options
Initialization Options
element(string | HTMLDivElement, required): Tree container or selector.id(string): Tree identifier.source(SourceType, default[]): Initial node data or remote source.columns(ColumnDefinition[], default[]): Treegrid column definitions.types(object, default{}): Shared node type definitions.skeleton(boolean, defaultfalse): Applies skeleton styling to nodes.debugLevel(number, default3): Logging level from 0 through 4.minExpandLevel(number, default0): Keeps configured top levels expanded.emptyChildListExpandable(boolean, defaultfalse): Keeps nodes expandable whenchildrenis empty.rowHeightPx(number, default22): Row height in pixels.iconMap(string | object, default"bootstrap"): Icon definition map.autoCollapse(boolean, defaultfalse): Collapses siblings when another node expands.adjustHeight(boolean, defaulttrue): Adjusts tree height to its parent.connectTopBreadcrumb(HTMLElement | string | null): Connects a breadcrumb container.navigationModeOption("startRow" | "cell" | "startCell" | "row"): Keyboard navigation mode.header(boolean | string | null, defaultnull): Header visibility and optional text.showSpinner(boolean, defaultfalse): Displays a<progress>element while data loads.autoKeys(boolean, defaultfalse): Generates stable missing keys.checkbox(boolean | "radio" | function, defaultfalse): Selection-control presentation.icon(boolean | string | function): Global or dynamic node icon.iconTooltip(boolean | string | function): Icon tooltip.tooltip(boolean | string | function): Node-title tooltip.unselectable(boolean | function): Selection restriction.enabled(boolean, defaulttrue): Enables tree interaction.fixedCol(boolean, defaultfalse): Keeps the first grid column fixed.columnsFilterable(boolean, defaultfalse): Default column filter-control state.columnsMenu(boolean, defaultfalse): Default column menu-control state.columnsResizable(boolean, defaultfalse): Default column resize state.columnsSortable(boolean, defaultfalse): Default column sort-control state.sortFoldersFirst(boolean | function, defaultfalse): Groups folders before end nodes during sorting.selectMode("single" | "multi" | "hier", default"multi"): Selection model.quicksearch(boolean, defaulttrue): Keyboard title search.scrollIntoViewOnExpandClick(boolean, defaulttrue): Scrolls an expanded node into view.dnd(object): Drag-and-drop configuration.edit(object): Title editing configuration.filter(object): Default filter configuration.strings(object): System text.
System Strings
loading:"Loading..."loadError:"Error"noData:"No data"breadcrumbDelimiter:" » "queryResult:"Found ${matches} of ${count}"noMatch:"No results"matchIndex:"${match} of ${matches}"
Dynamic Options
These options accept per-node callback values:
checkboxiconiconTooltiptooltipunselectable
const tree = new mar10.Wunderbaum({
element: "#demo-tree",
checkbox: (node) => node.type !== "heading",
tooltip: (node) => {
return `${node.title} (${node.key})`;
},
unselectable: (node) => node.type === "heading",
source: treeData,
});
Event Callbacks
activate(e): A node became active.beforeActivate(e): Runs before activation. Returnfalseto cancel.beforeExpand(e): Runs before expansion or collapse. Returnfalseto cancel.beforeSelect(e): Runs before a selection change. Returnfalseto cancel.buttonClick(e): A treegrid header control was clicked.change(e): An embedded grid input changed.click(e): A tree click occurred. Returnfalseto cancel default handling.dblclick(e): A double click occurred. Returnfalseto cancel default handling.deactivate(e): A node was deactivated.discard(e): Rendered markup for a node was removed from the viewport.error(e): Initialization or data loading failed.expand(e): A node expanded or collapsed.focus(e): The tree received or lost focus.iconBadge(e): Supplies optional badge content for a node icon.init(e): Initial markup and source loading completed.keydown(e): A key was pressed while the tree had focus. Returnfalseto block default navigation.lazyLoad(e): An unloaded lazy node was opened for the first time.load(e): Data was loaded, applied, and rendered.modifyChild(e): A child-node modification occurred.receive(e): Data was fetched but has not yet been applied.render(e): A node row is about to enter the DOM.renderStatusNode(e): A status row is about to render.select(e): A node was selected or deselected.update(e): The rendered viewport was updated.
Tree API
Tree Properties
activeNode: Current active node ornull.focusNode: Node with keyboard focus.children: Top-level nodes.parent: Alwaysnull, which lets a tree behave like its root for selected operations.root: Invisible root node.id: Tree identifier.element: Tree container.headerElement: Header container.listContainerElement: Node-list container.nodeListElement: Element containing rendered rows.options: Merged runtime options.columns: Treegrid column definitions.types: Shared node type definitions.data: Extra data returned by a remote source.ready: Promise resolved after initialization.breadcrumb: Connected breadcrumb element ornull.filterMode: Current filter mode.Wunderbaum.version: Runtime release version.Wunderbaum.iconMaps: Built-inbootstrapandfontawesome6maps.Wunderbaum.util: Public utility module.iconMap: Deprecated icon-map accessor. UseWunderbaum.iconMaps.
Tree Lookup And Traversal
[Symbol.iterator](): Iterates descendants depth-first in pre-order.count(visible?): Returns the node count.countUnique(): Counts unique reference keys.findAll(match): Returns all matching nodes.findByRefKey(refKey): Returns nodes sharing a reference key.findFirst(match): Returns the first matching node.findKey(key): Returns the node with a unique key.findNextNode(match, startNode?, reverse?): Searches from a given node.findRelatedNode(node, where, includeHidden?): Finds a related node by navigation direction.getFirstChild(): Returns the first top-level node.getLastChild(): Returns the last top-level node.visit(callback): Visits all nodes.visitRows(callback, options?): Traverses rows using display order.
Loading And Structure
addChildren(nodeData, options?): Inserts top-level nodes.clear(): Removes all nodes.load(source): Replaces tree data from a source and returns a Promise.reload(options?): Reloads the current source. Experimental.destroy(): Removes the instance and generated markup.setTypes(types, replace?): Replaces or updates shared node types.resetColumns(): Recalculates column settings.update(change, options?): Requests a tree update.updatePendingModifications(): Applies queued rendering changes.
Expansion And Navigation
expandAll(flag?, options?): Recursively expands or collapses nodes.getActiveNode(): Returns the active node.getFocusNode(): Returns the focused node.getActiveColElem(): Returns the active treegrid cell.getTopmostVpNode(complete?): Returns the topmost viewport node.getLowestVpNode(complete?): Returns the lowest viewport node.scrollTo(nodeOrOpts): Scrolls a node into the viewport.setActiveNode(key, flag?, options?): Changes the active node by key.setColumn(colIdx, options?): Changes the active treegrid column.setCellNav(flag?): Changes cell navigation mode.setFocus(flag?): Sets or releases tree focus.setNavigationOption(mode, reset?): Changes row or cell navigation behavior.
Selection
selectAll(flag?): Selects or deselects applicable nodes recursively.toggleSelect(): Toggles selection in the current tree context.getSelectedNodes(stopOnParents?): Returns selected nodes.getRefKeys(selected?): Returns reference keys.
Filtering
filterNodes(filter, options): Applies a filter and returns the match count.clearFilter(): Removes the active filter.countMatches(): Returns the current match count.isFilterActive(): Checks for an active filter.updateFilter(): Reapplies the current filter.filterBranches(filter, options): Deprecated. UsefilterNodes()withmatchBranch: true.
Sorting
sort(options): Sorts tree nodes.sortByProperty(...): Deprecated.sortChildren(...): Deprecated.
State And Status
getState(options?): Returns selected tree state. Experimental.setState(state, options?): Restores tree state. Experimental.setStatus(status, options?): Displays or clears a status row.getOption(name, defaultValue?): Reads an option.setOption(name, value): Changes an option.setEnabled(flag?): Enables or disables interaction.isEnabled(): Returns enabled state.
State Checks
hasFocus()hasHeader()isCellNav()isRowNav()isEditing()isEditingTitle()isGrid()isLoading()
Commands And Deferred Updates
applyCommand(command, options): Executes a navigation or modification command.enableUpdate(flag): Suspends or resumes rendering updates.runWithDeferredUpdate(callback): Defers rendering until a synchronous callback finishes.runWithDeferredUpdateAsync(callback): Defers rendering until an asynchronous callback finishes.toDictArray(callback?): Converts top-level nodes to dictionaries.format(...)format_iter(...)toString()
Logging
log(...args)logDebug(...args)logInfo(...args)logWarn(...args)logError(...args)logDeprecate(...)logTime(...)logTimeEnd(...)
Static Lookup Helpers
Wunderbaum.getEventInfo(event)Wunderbaum.getNode(elementOrEvent)Wunderbaum.getTree(elementOrId)
WunderbaumNode API
Node Properties
tree: Owning tree.parent: Parent node.children: Child nodes ornull.key: Unique node key.refKey: Optional non-unique reference key.title: Node title.data: Custom application data.type: Shared type identifier.classes: Extra row classes.checkbox: Checkbox or radio configuration.radiogroup: Radio-group state for children.expanded: Expansion state.selected: Selection state.unselectable: Selection restriction.lazy: Lazy-loading state.icon: Node icon definition.iconTooltip: Icon tooltip.tooltip: Title tooltip.colspan: Treegrid colspan state.statusNodeType: Status row type.match: Current filter match value.subMatchCount: Descendant filter match count.WunderbaumNode.sequence: Static node sequence counter.
Creation And Structure
addChildren(nodeData, options?)addNode(nodeData, mode?)moveTo(targetNode, mode?, map?)remove()removeChildren()removeMarkup()resetLazy()resetNativeChildOrder(options?)triggerModify(operation, data?)triggerModifyChild(operation, child)
Traversal
[Symbol.iterator]()findAll(match)findDirectChild(match)findFirst(match)findRelatedNode(where, includeHidden?)getFirstChild()getLastChild()getNextSibling()getPrevSibling()getParent()getParentList(includeRoot?, includeSelf?)getPath(includeSelf?, part?, separator?)getLevel()getCloneList(includeSelf?)visit(callback)visitParents(callback, includeSelf?)visitSiblings(callback, includeSelf?)
Expansion And Visibility
collapseSiblings(options?)expandAll(flag?, options?)makeVisible(options?)scrollIntoView(options?)setExpanded(flag?, options?)navigate(where, options?)
Selection And Focus
setActive(flag?, options?)setFocus(flag?)setSelected(flag?, options?)toggleSelected()getSelectedNodes(stopOnParents?)getRefKeys(selected?)
Data And Presentation
getOption(name, defaultValue?)setClass(className, flag?)setIcon(icon)setKey(key, refKey?)setStatus(status, options?)setTitle(title)setTooltip(tooltip)update(change?)getColElem(colIdx)startEditTitle()toDict(recursive?, callback?)format(...)format_iter(...)
Loading And Sorting
load(source)loadLazy(forceReload?)sort(options)resort(options?)sortByProperty(...): Deprecated.sortChildren(...): Deprecated.
State Checks
hasChildren()hasClass(className)hasFocus()isActive()isAncestorOf(node)isChildOf(node)isClone()isColspan()isDescendantOf(node)isEditingTitle()isExpandable(andCollapsed?)isExpanded()isFirstSibling()isLastSibling()isLazy()isLoaded()isLoading()isMatched()isPagingNode()isParentOf(node)isPartload()isPartsel()isRadio()isRendered()isRootNode()isSelected()isStatusNode()isTopLevel()isUnloaded()isVisible()
Hierarchical Selection Helpers
fixSelection3AfterClick()fixSelection3FromEndNodes()
Node Commands And Logging
applyCommand(command, options)log(...args)logDebug(...args)logInfo(...args)logWarn(...args)logError(...args)toString()
Method Option Objects
`AddChildrenOptions`
before(WunderbaumNode | number | null): Inserts before a node or child index. The default appends.applyMinExpanLevel(boolean, defaulttrue): AppliesminExpandLevelto inserted descendants. The API property uses this exact spelling.
`ExpandAllOptions`
loadLazy(boolean, defaultfalse): Loads lazy branches during expansion.resetLazy(boolean, defaultfalse): Unloads lazy children during collapse.force(boolean, defaultfalse): IgnoresminExpandLevel.depth(number): Restricts recursion depth.deep(boolean, defaultfalse): Collapses deeper descendants when a depth limit is used.collapseOthers(boolean, defaultfalse): Collapses branches outside the requested depth.keepActiveNodeVisible(boolean, defaulttrue): Keeps the active node visible.
`GetStateOptions`
activeKey(boolean, defaulttrue)expandedKeys(boolean, defaultfalse)selectedKeys(boolean, defaultfalse)
`SetStateOptions`
expandLazy(boolean, defaultfalse): Loads lazy branches when required while restoring state.
A tree state object contains:
expandedKeysactiveKeyactiveColIdxselectedKeys
`MakeVisibleOptions`
noAnimation(boolean, defaultfalse)scrollIntoView(boolean, defaulttrue)noEvents(boolean, defaultfalse)
`NavigateOptions`
activate(boolean, defaulttrue)event(Event): Originating event.
`ScrollIntoViewOptions`
noAnimation(boolean, defaultfalse)noEvents(boolean, defaultfalse)topNode(WunderbaumNode)ofsY(number): Additional top offset in pixels.
ScrollToOptions uses the same fields and adds:
node(WunderbaumNode, required)
`SetActiveOptions`
retrigger(boolean, defaultfalse): Fires activation callbacks even when the status does not change.noEvents(boolean, defaultfalse): Suppresses activation callbacks.focusTree(boolean, defaultfalse): Gives keyboard focus to the tree.event(Event): Originating event.colIdx(number | string): Activates a treegrid column.edit(boolean): Focuses an embedded input. Column0or"*"opens title editing.
`SetColumnOptions`
edit(boolean, defaultfalse)scrollIntoView(boolean, defaulttrue)
`SetExpandedOptions`
force(boolean, defaultfalse)immediate(boolean, defaultfalse)noAnimation(boolean, defaultfalse)noEvents(boolean, defaultfalse)resetLazy(boolean, defaultfalse)scrollIntoView(boolean, defaultfalse)
`UpdateOptions`
immediate(boolean, defaultfalse): Requests an immediate redraw.
`SetSelectedOptions`
force(boolean, defaultfalse): Ignores selection restrictions.noEvents(boolean, defaultfalse): Suppresses selection callbacks.propagateDown(boolean, defaultfalse): Applies selection to descendants in"multi"mode.callback: Runs for each affected node and can returnfalseto skip it.
`SetStatusOptions`
message(string): Status-row message.details(string): Status tooltip.
`ReloadOptions`
source(SourceType): Loads another source.reactivate(boolean, defaulttrue): Reactivates the current active node after reload.
`ResetOrderOptions`
recursive(boolean, defaulttrue)propName(string, default"_nativeIndex")
`SortOptions`
propName(string): Property used for sorting when no key callback or column is supplied.key(function): Returns the comparison value for a node.cmp(function): Deprecated comparison callback. Usekey.order("asc" | "desc" | undefined)deep(boolean, defaulttrue): Sorts descendants recursively.caseInsensitive(boolean, defaultfalse)nativeOrderPropName(string, default"_nativeIndex")updateColInfo(boolean, defaultfalse): Rotates and records treegrid column sort state.colId(string): Column ID used withupdateColInfo.
`VisitRowsOptions`
includeHidden(boolean, defaultfalse)includeSelf(boolean, defaulttrue)reverse(boolean, defaultfalse)start(WunderbaumNode | null): Traversal starting node.wrap(boolean, defaultfalse)
Styling And Customization
CSS Custom Properties
Typography And Main Colors
--wb-font-stack--wb-error-color--wb-node-text-color--wb-border-color--wb-bg-highlight-color--wb-header-color--wb-background-color--wb-alternate-row-color--wb-alternate-row-color-hover--wb-focus-border-color
State Colors
--wb-drop-source-color--wb-drop-target-color--wb-dim-color--wb-error-background-color--wb-hover-color--wb-hover-border-color--wb-grid-color--wb-active-color--wb-active-cell-color--wb-active-border-color--wb-active-hover-color--wb-active-hover-border-color--wb-active-column-color--wb-active-header-column-color--wb-active-color-grayscale--wb-active-border-color-grayscale--wb-active-hover-color-grayscale--wb-active-cell-color-grayscale--wb-grid-color-grayscale--wb-filter-dim-color--wb-filter-submatch-color
Dimensions
--wb-row-outer-height--wb-row-inner-height--wb-row-padding-y--wb-col-padding-x--wb-icon-outer-height--wb-icon-outer-width--wb-icon-height--wb-icon-width--wb-icon-padding-y--wb-icon-padding-x--wb-header-height
#demo-tree {
--wb-node-text-color: #252525;
--wb-background-color: #fafafa;
--wb-header-color: #ececec;
--wb-bg-highlight-color: #2563eb;
--wb-focus-border-color: #1d4ed8;
--wb-hover-color: #eff6ff;
}
Feature Classes
wb-alternate: Alternating row backgrounds.wb-checkbox-auto-hide: Hides unchecked checkbox icons until the row is hovered.wb-fade-expander: Shows expanders while the tree is hovered.wb-initializing: Initial-loading class removed after initialization.wb-no-select: Prevents mouse text selection.wb-rainbow: Colors hierarchy levels.wb-rtl: Right-to-left presentation.
Automatic State Classes
Tree state:
wb-gridwb-fixed-colwb-cell-mode
Row state:
wb-activewb-busywb-errorwb-invalidwb-loadingwb-matchwb-selectedwb-skeletonwb-status-*wb-submatch
Helper Classes
wb-helper-centerwb-helper-disabledwb-helper-endwb-helper-hiddenwb-helper-invalidwb-helper-lazy-expanderwb-helper-linkwb-helper-start
Customize Icons
The built-in icon maps are bootstrap and fontawesome6. Load the corresponding icon font separately.
const tree = new mar10.Wunderbaum({
element: "#demo-tree",
iconMap: Object.assign(
{},
mar10.Wunderbaum.iconMaps.bootstrap,
{
folder: "bi bi-folder-fill",
folderOpen: "bi bi-folder2-open",
doc: "bi bi-file-earmark",
}
),
source: treeData,
});
Public icon-map keys:
errorloadingnoDataexpanderExpandedexpanderCollapsedexpanderLazycheckCheckedcheckUncheckedcheckUnknownradioCheckedradioUncheckedradioUnknownfolderfolderOpenfolderLazydoccolSortablecolSortAsccolSortDesccolFiltercolFilterActivecolMenu
Alternatives And Related Resources
- 10 Best Tree View JavaScript Libraries in 2026 (Lightweight & Free)
- JavaScript Treeview Library for Hierarchical Data – Quercus.js
- Interactive and Accessible Tree View JS Library – bs-treeview
- Advanced Data Grid/Table Library in Vanilla JavaScript – VanillaGrid







