Builtin Library
README.md
inspector_app template
A property-inspector shell: a form that maps a state object onto a vertical list of labelled field rows. Use this template for editor-style sidebars, settings panes, and any form-shaped UI.
What's in the template
inspector_app/
├── README.md
├── inspector_app.scene/
│ ├── scene.json
│ └── entrypoint.luau ← spawns an entity with a UiPanel bound to the layout
└── inspector_app_layout.module/
└── init.luau ← mount(ctx): builds the widget tree, owns the state
Run it: layers.load("@builtin::_templates.inspector_app.inspector_app").
How it works
The scene entrypoint spawns an entity carrying a UiPanel component whose
source points at inspector_app_layout. The panel requires that module and
calls mount(ctx), handing it { entity, entityId, data, state? }.
mount owns the whole UI:
- It seeds
statefromctx.state(or its own defaults), so the values survive a live reload. build()returns a raw widget tree — a pure function ofstate— andui.registerScreen("inspector_app", build())publishes it.- It returns
{ state, update, onCallback, destroy }. Every widget carries a callback id (onChangeon the fields,onClickon the buttons); the panel routes those toonCallback(id, data), which mutatesstateand re-renders withui.updateScreen("inspector_app", build()).destroycallsui.unregisterScreen.
The widget tree
A node is { type, props, style, children }. props carries data and
behaviour (a label's text, a slider's value/min/max, a field's callback
id); style carries the CSS surface (padding, gap, background, color,
fontSize, borderRadius, alignItems, justifyContent, flex, …). The
inspector is an anchor holding a vertical panel: a header, a scrollArea
of labelled rows, an action row, and a status line. Each row is a horizontal
pairing a caption label with a control.
The sample fields cover the interactive widget types:
- Name — an
input(text field).onChangedeliversdata.valueas the new string. - Intensity — a
sliderwithmin/max.onChangedeliversdata.valueas the new number. - Enabled — a
checkbox.onChangedeliversdata.valueas the new boolean. - Color — an
inputbeside a swatchlabeltinted with the current value. - Position — a read-only
label.
Slider, checkbox, and input are controlled: the engine does not cache
their value, so build() passes it every frame from state.
Extending it
Add rows in build() and handle their callback ids in onCallback. Query the
widget vocabulary live with the gui toolbox's widgetTypes and
widgetProps tools, and
read the UI guide and
styling guide for the full model.
Switch to docked_app for a toolbar+body shell, canvas_app for a node-graph
editor, or blank_app for a minimal single-panel layout.