# Lux Web Examples Interactive browser examples demonstrating Lux compiled to JavaScript. ## Quick Start ```bash # 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: ```lux fn view(model: Model): String = { "
" + toString(getCount(model)) + "
" } ``` ### Counter with Html Module (Type-safe) The same counter using the type-safe Html module: ```lux 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: ```bash 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 -> Html` or `Model -> String` ## Available Modules ### Html Module Type-safe HTML construction: ```lux // 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: ```lux fn main(): Unit with {Dom} = { match Dom.querySelector("#app") { Some(el) => Dom.setTextContent(el, "Hello!"), None => () } } ``` Available operations: - `querySelector`, `querySelectorAll`, `getElementById` - `createElement`, `createTextNode`, `appendChild` - `setTextContent`, `getTextContent`, `setInnerHtml` - `setAttribute`, `getAttribute`, `addClass`, `removeClass` - `addEventListener`, `focus`, `blur` - `getValue`, `setValue` (for inputs) - `scrollTo`, `getWindowSize`, `getBoundingClientRect` ## How It Works 1. Lux code is compiled to JavaScript using `lux compile --target js` 2. The HTML page loads the compiled JS 3. A minimal runtime handles the TEA loop: - `luxInit_lux()` creates initial state - `luxUpdate_lux(model, msg)` handles state updates - `luxView_lux(model)` renders HTML - `dispatch(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: ```javascript 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: ```javascript Lux.simpleApp({ init: luxInit_lux(), update: (model, msg) => luxUpdate_lux(model, msg), view: (model) => luxView_lux(model), root: "#app" }); ``` ## Development To modify an example: 1. Edit the `.lux` file 2. Recompile: `lux compile .lux --target js -o .js` 3. Refresh the browser