- stdlib/html.lux: Type-safe HTML construction - stdlib/browser.lux: Browser utilities - examples/web/: Counter app with DOM manipulation - examples/counter.lux: Simple counter example Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
3.4 KiB
3.4 KiB
Lux Web Examples
Interactive browser examples demonstrating Lux compiled to JavaScript.
Quick Start
# 1. Compile the counter example
lux compile examples/web/counter.lux --target js -o examples/web/counter.js
# 2. Start a local server
cd examples/web
./serve.sh
# 3. Open in browser
# http://localhost:8080/index.html
Examples
Counter (String-based)
A simple counter demonstrating the TEA (The Elm Architecture) pattern using string concatenation for HTML:
fn view(model: Model): String = {
"<div>" + toString(getCount(model)) + "</div>"
}
Counter with Html Module (Type-safe)
The same counter using the type-safe Html module:
fn view(model: Model): String = {
let count = getCount(model)
let display = Html.div([Html.class("display")], [Html.text(toString(count))])
Html.render(display)
}
Compile with:
lux compile examples/web/counter_html.lux --target js -o examples/web/counter_html.js
The Elm Architecture (TEA)
Both examples follow the TEA pattern:
- Model: Application state (
Counter(Int)) - Msg: Events (
Increment,Decrement,Reset) - Update: State transitions
(Model, Msg) -> Model - View: HTML rendering
Model -> HtmlorModel -> String
Available Modules
Html Module
Type-safe HTML construction:
// Elements
Html.div(attrs, children)
Html.span(attrs, children)
Html.button(attrs, children)
Html.input(attrs, children)
Html.h1(attrs, children)
// ... 30+ elements
// Attributes
Html.class("name")
Html.id("id")
Html.href("url")
Html.style("...")
Html.attr("name", "value")
// Events
Html.onClick(handler)
Html.onInput(handler)
Html.on("event", handler)
// Text
Html.text("content")
// Rendering
Html.render(node) // -> String (for innerHTML)
Html.renderToDom(node) // -> Element (for appendChild)
Dom Effect
Direct DOM manipulation:
fn main(): Unit with {Dom} = {
match Dom.querySelector("#app") {
Some(el) => Dom.setTextContent(el, "Hello!"),
None => ()
}
}
Available operations:
querySelector,querySelectorAll,getElementByIdcreateElement,createTextNode,appendChildsetTextContent,getTextContent,setInnerHtmlsetAttribute,getAttribute,addClass,removeClassaddEventListener,focus,blurgetValue,setValue(for inputs)scrollTo,getWindowSize,getBoundingClientRect
How It Works
- Lux code is compiled to JavaScript using
lux compile --target js - The HTML page loads the compiled JS
- A minimal runtime handles the TEA loop:
luxInit_lux()creates initial stateluxUpdate_lux(model, msg)handles state updatesluxView_lux(model)renders HTMLdispatch(msg)triggers updates and re-renders
TEA Runtime
For applications using the Html module with event handlers, you can use the built-in TEA runtime:
Lux.app({
init: luxInit_lux(),
update: (model, msg) => luxUpdate_lux(model, msg),
view: (model, dispatch) => luxView_lux(model),
root: "#app"
});
Or for string-based views:
Lux.simpleApp({
init: luxInit_lux(),
update: (model, msg) => luxUpdate_lux(model, msg),
view: (model) => luxView_lux(model),
root: "#app"
});
Development
To modify an example:
- Edit the
.luxfile - Recompile:
lux compile <file>.lux --target js -o <file>.js - Refresh the browser