17 points cat-whisperer 11 hours ago 8 comments
But how? How does it all work? I proposed we just do it the Ratatui way, but my friend was like, nah! We shall make it possible to build TUIs in Lua. (Weirdo!) But it paid off, and we got ourselves a shiny new Lua library, ito!!!
He didn't get the gravity of the situation. We had an awesome terminal UI library in Lua! I wanted everyone to know how cool that is, so I got cooking, wrote myself a custom canvas implementation of this library instead of the usual terminal adaptor, exported it as wasm, and made this super cool website where you can experiment building awesome UIs in Lua. For vibe-coders, we got an llms.txt too. Have at it, and see if you can build something really cool with it. The library's at github.com/uji-labs/ito, and the awesome sauce harness is at github.com/uji-labs/uji.
I hope you like it!
hollowturtle 1 hour ago | parent
cat-whisperer 1 hour ago | parent
Yannik_Sc 35 minutes ago | parent
ui.Button "Button Text" {
on_click = function()
print("Hello world")
end,
disabled = true
}
or ui.VStack {
padding = 31, -- Named key => option
wrap = true,
ui.Button "..." {}, -- Indexed by number => children
}
feels more Lua and slightly cleaner imootikik 19 minutes ago | parent
To me it is more about expressiveness and usage of basic language features. For example here's how a text field is set up currently.
ito.TextField(draft)
:label("Name")
:focused()
:on_submit(function(value)
if value:match("%S") then
phase.value = "review"
end
end)
:on_cancel(function()
phase.value = "choose"
end),
The field is created on the first line, and then altered further with subsequent method calls that alter it. This reads like someone very used to Rust (and its Builder pattern) and then translating it verbatim to Lua. A more native Lua interface for me would look like this: ito.TextField(draft, {
label = "Name",
focused = true,
on_submit = function(value)
if value:match("%S") then
phase.value = "review"
end
end,
on_cancel = function()
phase.value = "choose"
end),
})
As in: just pass a table to the builder. And if they ned to modify it later, they can just do: some_textfield.on_cancel = <some other function>
No need to "guard" the internal table with those extra methods.cat-whisperer 4 minutes ago | parent
maybe it’s a bad idea :X
cat-whisperer 6 minutes ago | parent