▣
module · drop-in viewer
theme
Theme tokens for zui (Layer 2). Reads through `ui.getToken(name)` first so a loaded engine theme propagates automatically; falls back to in-module defaults that cover every named color used by the demos. Also owns the Luau-side `$variable` cascade — `register` / `load` resolve re…
by·posted 2mo ago
What it does
theme
Theme tokens for zui (Layer 2). Reads through ui.getToken(name) first
so a loaded engine theme propagates automatically; falls back to
in-module defaults that cover every named color used by the demos. Also
owns the Luau-side $variable cascade — register / load resolve
references end-to-end (cycle-detected) and push flat values to
ui.registerTheme.
Exports
M.with(overrides: TokenMap?) -> ThemeView— read-only view with overlays on top of engine/defaults.M.defaults() -> TokenMap— raw default token map (same reference each call).M.tokenNames() -> { string }— sorted list of shipped token names.M.resolve(theme: any) -> (ResolvedTheme?, string?)— flatten a theme table ($var→ literal). Returns(nil, errMsg)on failure.M.resolveTokens(theme) -> (TokenMap?, string?)— re-export from cascade.M.resolveStyles(theme, tokens) -> (StyleMap?, string?)— re-export from cascade.M.register(name: string, theme: any) -> (boolean, string?)— resolve and push toui.registerTheme.M.load(name: string) -> (boolean, string?)— require@builtin::themes.<name>and register it.M.activate(name: string) -> boolean— thin wrapper overui.setTheme(name).M.default: ThemeView— module-level token view with no overrides.
Types:
TokenMap = { [string]: any }StyleMap = { [string]: { [string]: any } }Theme = { name: string?, tokens: TokenMap?, styles: StyleMap? }ResolvedTheme = { name: string, tokens: TokenMap, styles: StyleMap }ThemeView— read-only metatable proxy; writes throw.
Usage
local Theme = require("@builtin::modules.zui.theme")
Theme.load("dark") -- require + register the built-in dark theme
Theme.activate("dark") -- ui.setTheme("dark")
local view = Theme.with({ accent = "#ff0" })
print(view.accent) -- "#ff0"
print(view.bg) -- engine token or default
Notes
registeroverridestheme.namewith the caller-supplied name solistThemes()/setTheme(name)find it under the requested key (mirrors the pre-Phase-4 #942 fix).- The cascade is cycle-detected — broken inputs surface as structured
(false, errMsg)returns instead of silently producing garbage colors. M.defaultis built at module-load time, afterMis fully populated, so its function-fallback__indexresolves correctly.ThemeViewwrites raise — useZ.themeWith({...})to get an overlay view rather than mutating the existing one.
Discussion
Scoped to this part · feeds back into the world's score.
Sign in to post.sign in
No comments yet. Be the first.