Builtin Library
README.md
zui
Deprecated for authoring content.
zuipredates the engine's CSS-parityui.*surface and writes unlike CSS, producing flatter results. Author screens as raw widget trees ({ type, style, props, children }) styled withui.*, and read@builtin::examples.ui.*for complete worked screens.zuiremains in use internally by the editor; it will be rebuilt on the CSS-parity core.
Convenience UI library on top of the engine's ui.* Rust bindings.
Ships Layer 1 (per-widget builders), Layer 2 (theme tokens), Layer 3
(app lifecycle), router with unhandled-warning, pre-built shells, and
debug overlay. The engine's Rust UI surface is the substrate — zui is
one library on top of it. Any third-party Lua UI library can build on
the same primitives; the engine has no concept of "the zui library",
only widget types and a stable contract. See
docs/specs/ui-v3-architecture.md.
Exports
Layer 1 (widget builders) — short aliases on Z.*:
Z.lbl,Z.btn,Z.icon,Z.iconBtn,Z.iconButton,Z.chip,Z.badge,Z.card,Z.colorSwatch,Z.dialogueBox,Z.kbd,Z.input,Z.codeEditor,Z.slider,Z.dragValue,Z.checkbox,Z.toggle,Z.dropdown,Z.datePicker,Z.radioGroup,Z.selectableList,Z.image,Z.viewport,Z.progressBar,Z.richText,Z.fader,Z.knob,Z.meter,Z.healthBar,Z.hotbar,Z.minimap,Z.hbox,Z.vbox,Z.grid,Z.split,Z.sides,Z.panel,Z.section,Z.scroll,Z.collapsible,Z.window,Z.modal,Z.popup,Z.contextMenu,Z.scene,Z.area,Z.anchor,Z.topPanel,Z.bottomPanel,Z.leftPanel,Z.rightPanel,Z.centralPanel,Z.spacer,Z.flex,Z.sep,Z.plot,Z.graph,Z.dndList,Z.canvas,Z.tabs,Z.tree,Z.filterRow,Z.statRow,Z.statusLabel,Z.nodeZ.lsp— LSP composite-widget namespace.Z.fs— Filesystem composite-widget namespace.Z.widget— full widget namespace (for explicit access).
Layer 2 (theme tokens):
Z.theme— active default token table.Z.themeWith(overrides)— derive a theme with token overrides.Z.themeNames()— list known token names.Z.Theme— the underlying module.
Shared utils (re-exported):
Z.round,Z.fmt,Z.fmtVec3,Z.id,Z.eventValue,Z.map,Z.when,Z.compact,Z.Utils.
Layers 3-7 (app lifecycle + advanced features):
Z.app(name, builder)— App lifecycle wrapper (Z.App.create).Z.dynamic(list, fn)— one-screen-per-list-item bucket.Z.dataSource(fetchFn, opts)— TTL + gated cached fetcher.Z.highlight— syntax-highlighting dispatch and per-language modules.Z.shell— pre-built shell shapes (docked, canvas, inspector).Z.tags,Z.screens— Luau-owned screen tag registry + lifecycle helpers.Z.defineWidget(name, fn)/Z.unregisterWidget(name)— register Luau builders for raw{ type = name, ... }widget tables.Z.widgetState(id, key, default)/Z.widgetState.set(id, key, value)— per-widget reactive state.Z.VERSION,Z.SPEC— version string and spec link.
Usage
local Z = require("@builtin::modules.zui")
local C = Z.theme
local function tree()
return Z.centralPanel({
Z.topPanel({
Z.hbox({
Z.lbl("◈ MY APP", { color = C.accent, fontSize = 14, bold = true }),
Z.flex(),
Z.btn("Save", "save:click", { bg = C.accent, color = C.bg, bold = true }),
}, { style = { gap = 8, padding = { 6, 12, 6, 12 } } }),
}),
Z.section("CONTROLS", {
Z.slider("vol", 0.5, 0, 1, { onChange = "vol:set" }),
Z.btn("Reset", "vol:reset"),
}, { bg = C.panel, border = C.border, padding = { 8, 12, 8, 12 } }),
})
end
ui.registerScreen("my-app", tree(), 0)
ui.showScreen("my-app")
Notes
- This module's surface is mostly re-exports: every
Z.*widget alias isWidget.*(seewidget.module/), every theme alias isTheme.*, every util isUtils.*. The aliases exist for ergonomics only — explicit access viaZ.widget,Z.Theme,Z.Utils, etc. works the same way. - The module registers a handful of
ui.defineWidgethandlers at load time (tabs, card, sides, badge, colorSwatch, separator, progressBar, iconButton, dialogueBox, hotbar) so raw{ type = "<name>", ... }widget tables in existing demos and editor tools keep rendering after their Rust-side definitions were deleted. Re-running registration on hot-reload is safe — the engine replaces the previous closure. Z.defineWidgetrequires the engineuiglobal; off-host execution raises a clear error.Z.widgetStateis a callable read path with a.setwrite sub-method — no metatables on the caller side. Returns thedefaultwhen the engine global is missing.- The library is built on a stable Rust substrate (
ui.registerScreen,ui.getToken,ui.defineWidget, etc.). Other Lua UI libraries can build on the same substrate and coexist withzui; the engine has no concept of a privileged library. - See
docs/specs/ui-v3-architecture.mdfor the full layered design, Rust binding gaps, and follow-up roadmap.
Tall content inside an anchored panel
A Z.anchor("Center", ...) { Z.panel(rows) } whose rows exceed the
viewport will silently clip top + bottom — the player has no scrollbar
and no way to reach the off-screen entries. Opt into in-place scrolling
on the panel:
Z.anchor("Center", {}, {
Z.panel(rows, { scroll = true, maxHeight = 480 }),
})
scroll = true wraps the children in a scrollArea so overflow stays
reachable. Without scroll = true, maxHeight only clips. See the
panel README for scrollMaxHeight,
header/footer pinning, and the full pattern (closes #3270).