Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commit3bb1da2647

README.md

zui

Deprecated for authoring content. zui predates the engine's CSS-parity ui.* surface and writes unlike CSS, producing flatter results. Author screens as raw widget trees ({ type, style, props, children }) styled with ui.*, and read @builtin::examples.ui.* for complete worked screens. zui remains 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.node
  • Z.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 is Widget.* (see widget.module/), every theme alias is Theme.*, every util is Utils.*. The aliases exist for ergonomics only — explicit access via Z.widget, Z.Theme, Z.Utils, etc. works the same way.
  • The module registers a handful of ui.defineWidget handlers 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.defineWidget requires the engine ui global; off-host execution raises a clear error.
  • Z.widgetState is a callable read path with a .set write sub-method — no metatables on the caller side. Returns the default when 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 with zui; the engine has no concept of a privileged library.
  • See docs/specs/ui-v3-architecture.md for 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).