3. Replace src/main.luau
luastra/ui · app.render · app.handle · about 15 minutescomplete runnable application
Module state owns the count, render describes the current interface, and handle admits exactly two actions from stable controls.
When to use it
Replace the complete generated entry module; do not paste only render or handle because the imports, state, snapshot, and returned App.compose instance belong to the same file.
- --!strict lets luastra check analyze this entire module.
- app.render has no side effects: it returns a fresh description of UI from count.
- onTap contains an action name; the clicked component's stable id arrives separately as target.
- role=status announces the changed count without moving keyboard focus.
- snapshot is a small test seam used by tests/smoke.luau; the host never calls it.
Focused example
--!strict
local UI = require("luastra/ui")
local App = require("luastra/app")
local Root = {}
local count: number = 0
function Root.render(): UI.Node
return UI.Screen {
id = "counter",
documentTitle = "Beginner counter",
width = "full",
UI.Column {
id = "counter/content",
width = "content",
padding = "responsive",
gap = "md",
UI.Text {
id = "counter/title",
text = "My first Luastra app",
variant = "title",
},
UI.Text {
id = "counter/value",
text = `Count: {count}`,
role = "status",
label = `Current count: {count}`,
},
UI.Row {
id = "counter/actions",
gap = "sm",
responsive = true,
UI.Button {
id = "counter/add",
text = "Add one",
onTap = "counter.add",
},
UI.Button {
id = "counter/reset",
text = "Reset",
appearance = "secondary",
disabled = count == 0,
onTap = "counter.reset",
},
},
},
}
end
function Root.handle(action: string, target: string, _value: string)
if action == "counter.add" and target == "counter/add" then
count += 1
elseif action == "counter.reset" and target == "counter/reset" then
count = 0
end
end
function Root.snapshot()
return { count = count }
end
return App.compose {
render = function(_outputs) return Root.render() end,
handle = Root.handle,
snapshot = Root.snapshot,
}