Tree
Tree renders a hierarchy of nodes the user can expand, collapse, and select — file explorers, category browsers, org charts, or any nested parent/child data. Nodes can be supplied inline with staticNodes, fetched from a fetchUrl, or lazy-loaded branch by branch.
Like the other builders, Tree is a static field on a page class (see Pages & components); it produces a serializable description that the shared Nuxt frontend renders.
What it renders
A card with an optional title / description header, then the node hierarchy. Each node is a row with a leading icon — its own icon, or on parent nodes without one the expandedIcon / collapsedIcon (open and closed folder icons by default) — then the label, and on expandable rows a trailing toggle chevron (swappable via trailingIcon).
Expanding a node reveals its children indented beneath it; selectable nodes highlight in the component color when clicked. The tree scales with size (xs through xl). While a lazy branch fetches its children, the whole tree is temporarily disabled until they arrive.
Usage
selectionBehavior is required, and every tree needs either a fetchUrl or staticNodes.
import { PageController, RegisterPage } from "@antelopejs-private/cms/interfaces/cms/page";
import { Tree, TreeSelectionBehavior } from "@antelopejs-private/cms/interfaces/cms-base/tree";
import { Color, Size } from "@antelopejs-private/cms/interfaces/cms-base/types";
@RegisterPage()
export class ExplorerPage extends PageController("explorer", {
displayName: "Explorer",
icon: "i-ph-tree-structure",
category: pagesCategory,
}) {
static files = Tree({
title: "Project Structure",
description: "Navigate your project files and folders",
fetchUrl: "/api/tree/data",
lazyLoad: true,
color: Color.primary,
size: Size.medium,
selectionBehavior: TreeSelectionBehavior.toggle,
});
}
The route returns an array of nodes; nested nodes go in children. Mark a branch lazy by giving it hasChildren: true, an empty children: [], and a lazyLoadUrl — it is fetched on first expand when the builder has lazyLoad: true.
import { Controller, Get } from "@antelopejs/interface-api";
export class TreeAPIController extends Controller("/api/tree") {
@Get("data")
getTreeData() {
return [
{
value: "root-1",
label: "Documents",
icon: "i-ph-folder",
expandable: true,
selectable: true,
children: [
{ value: "doc-1", label: "Proposal.pdf", icon: "i-ph-file-pdf", selectable: true },
{
value: "folder-reports",
label: "Reports",
icon: "i-ph-folder",
expandable: true,
hasChildren: true,
lazyLoadUrl: "/api/tree/reports",
children: [],
},
],
},
];
}
@Get("reports")
getReportsChildren() {
return [
{ value: "report-q1", label: "Q1 Report.xlsx", icon: "i-ph-file-xls", selectable: true },
];
}
}
For small, fixed hierarchies, pass staticNodes inline using the same node shape instead of a route.
value — it identifies the node and builds the hierarchical path used for expand/select state.TreeNode shape
| Field | Type | Purpose |
|---|---|---|
label | string | Row text (required). Resolved through i18n if it is a translation key. |
value | string | Unique node id (effectively required — see note above). |
icon | string | Iconify leading icon, e.g. i-ph-folder. |
children | TreeNode[] | Child nodes. Empty ([]) for an unloaded lazy branch. |
expandable | boolean | Whether the node can be expanded. |
selectable | boolean | Whether the node can be selected. |
hasChildren | boolean | Marks a lazy branch as having children to fetch. |
lazyLoadUrl | string | URL its children are fetched from on first expand. |
customData | unknown | Arbitrary payload carried with the node and its events. |
Options
| Option | Type | Default | Purpose |
|---|---|---|---|
selectionBehavior | TreeSelectionBehavior | — | Required. toggle or replace (see Selection). |
fetchUrl | string | — | Route returning the root node array. Required unless staticNodes. |
staticNodes | TreeNode[] | — | Inline node array. Required unless fetchUrl. |
fetchUrlMethod | HttpMethod | GET | HTTP method for fetchUrl and lazy lazyLoadUrl requests. |
lazyLoad | boolean | false | Enable on-demand loading of lazyLoadUrl branches. |
multiple | boolean | false | Allow more than one node selected at once. |
propagateSelect | boolean | false | Selecting a parent also marks its children selected. |
defaultExpanded | string[] | [] | Node values expanded on first render. Expansion is uncontrolled — this seed is the working way to open nodes from the builder. |
expanded | string[] | — | Present on the public TreeProps type but currently ignored by the frontend — use defaultExpanded instead. |
disabled | boolean | false | Render the whole tree display-only. |
title | string | — | Header title (also the component display name). |
description | string | — | Header description. |
color | Color | primary | Theme color for selection/highlight. |
size | Size | md | Row scale: xs through xl. |
expandedIcon | string | folder-open icon | Leading icon of an expanded parent node that has no icon of its own. |
collapsedIcon | string | folder icon | Leading icon of a collapsed parent node that has no icon of its own. |
trailingIcon | string | chevron-down icon | Trailing toggle icon on expandable (parent) rows; leaf rows carry none. |
nodeToggleFunctionId | string | — | Registered function run before a node expands/collapses. |
nodeSelectFunctionId | string | — | Registered function run before a node is selected. |
watchActions | WatchAction[] | — | Reactive watch wiring (from BaseComponentProps). Prefer .watch()/.watchOn() on the builder — see Actions & reactivity. |
Features
Expand / collapse
Expandable nodes toggle open and closed. Seed the initial open set with defaultExpanded (node values); the component also auto-expands the ancestors of any selected node so the selection is visible. Parent nodes without their own icon show expandedIcon / collapsedIcon as their leading icon — open and closed folders by default; the trailing toggle chevron on parent rows comes from trailingIcon.
Selection
selectionBehavior sets how a click changes the current selection: toggle flips the clicked node on or off, replace selects it and clears the rest. multiple allows more than one node selected at a time, and propagateSelect: true also marks a parent's children selected. Per node, selectable: false blocks selection; disabled: true on the builder renders the whole tree display-only. (These behaviors are forwarded to the underlying Nuxt UI tree.)
Lazy loading
With lazyLoad: true, a node that has hasChildren: true, an empty children, and a lazyLoadUrl defers loading until its first expand. The component then fetches lazyLoadUrl (using fetchUrlMethod, default GET), disables the whole tree until the branch's children arrive, and replaces the node's children with the response. On failure it shows an error toast and leaves the branch empty so it can be retried.
Node action hooks
nodeToggleFunctionId and nodeSelectFunctionId name registered frontend functions run before a node toggles or is selected — register the handler under the same string from your layer (Component events). The node is passed in; if the function throws, the action is cancelled. Use them for validation or side effects.
Events
The component emits NODE_SELECT, NODE_TOGGLE, NODE_EXPAND, NODE_COLLAPSE, and during lazy loading LAZY_LOAD / LAZY_LOAD_SUCCESS (the TreeEvents constants) for other components to react to through watch-actions (Actions & reactivity).
Permissions
Tree adds no permission options of its own. Like every component it is gated by the standard component permission — the page's full id followed by every field/child id in the tree's position, e.g. .files for a top-level field. The routes behind fetchUrl / lazyLoadUrl are ordinary controllers with their own auth. See Auth & permissions.