Builtin Library
- ..
- .metadata17 B
- README.md1.9 KB
- fromFlat.module
- init.luau8.6 KB
README.md
tree
Recursive expandable tree. Each node renders as a clickable row
(chevron + optional icon + label, indented by depth * indentPx, with
optional right-side action buttons). Clicking the chevron emits
<onToggle>-<key>; clicking the label emits <onSelect>-<key>. The
tree itself is stateless — toggle/select state lives in the caller's
state.
Exports
tree(nodes, opts?) -> Node— render a list of root nodes into a vbox of rows. Reached via the module's__callmetamethod.tree.fromFlat: (items, opts?) -> (roots, nodeById)— re-exports thefromFlatsub-module that builds recursive nodes from a flat parent-pointer list.
Node shape:
{ key, label, children?, expandable?, expanded?, icon?, actions?, payload? }
Usage
local Z = { tree = require("@builtin::modules.zui.widget.tree") }
local function buildTree()
return Z.tree(state.nodes, {
onSelect = "ent-select",
onToggle = "ent-toggle",
selectedKey = state.selectedId,
})
end
app:on("^ent%-select%-(.+)$", function(_v, _id, key)
state.selectedId = key
end)
app:on("^ent%-toggle%-(.+)$", function(_v, _id, key)
state.expanded[key] = not state.expanded[key]
end)
Notes
- The module returns a callable table —
tree(...)works as a function, andtree.fromFlat(...)reaches the sub-module. This is a dynamic-dispatch shape; thetyped functiondirective is skipped here per the module-conversion spec rule 7. - A row gets a chevron when it has children OR when
expandable == true(lazy-load: the caller fetches children on the toggle event). actionscallback ids are emitted verbatim — no key suffixing — so a row-level action ("× delete") reads as the same callback whether invoked from the tree, a context menu, or a toolbar.- Hard depth cap (32) protects against accidentally cyclic node data.