feat: add stdlib and browser examples
- 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>
This commit is contained in:
82
examples/web/counter_html.lux
Normal file
82
examples/web/counter_html.lux
Normal file
@@ -0,0 +1,82 @@
|
||||
// Counter with Html Module (Type-safe HTML)
|
||||
// Compile with: lux compile examples/web/counter_html.lux --target js -o examples/web/counter_html.js
|
||||
//
|
||||
// This version uses the Html module for type-safe HTML construction
|
||||
// instead of string concatenation. The Html module provides:
|
||||
// - Type-safe element constructors (div, button, etc.)
|
||||
// - Type-safe attribute constructors (class, onClick, etc.)
|
||||
// - Automatic HTML escaping
|
||||
|
||||
// ============================================================================
|
||||
// Model
|
||||
// ============================================================================
|
||||
|
||||
type Model = | Counter(Int)
|
||||
|
||||
fn getCount(m: Model): Int = match m { Counter(n) => n }
|
||||
|
||||
fn init(): Model = Counter(0)
|
||||
|
||||
// ============================================================================
|
||||
// Messages
|
||||
// ============================================================================
|
||||
|
||||
type Msg = | Increment | Decrement | Reset
|
||||
|
||||
// ============================================================================
|
||||
// Update
|
||||
// ============================================================================
|
||||
|
||||
fn update(model: Model, msg: Msg): Model =
|
||||
match msg {
|
||||
Increment => Counter(getCount(model) + 1),
|
||||
Decrement => Counter(getCount(model) - 1),
|
||||
Reset => Counter(0)
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// View - Type-safe HTML using Html module
|
||||
// ============================================================================
|
||||
|
||||
fn view(model: Model): String = {
|
||||
let count = getCount(model)
|
||||
|
||||
// Build HTML tree using Html module
|
||||
let title = Html.h1([], [Html.text("Lux Counter")])
|
||||
let display = Html.div([Html.class("display")], [Html.text(toString(count))])
|
||||
|
||||
let decBtn = Html.button(
|
||||
[Html.attr("onclick", "dispatch('Decrement')")],
|
||||
[Html.text("-")]
|
||||
)
|
||||
let resetBtn = Html.button(
|
||||
[Html.attr("onclick", "dispatch('Reset')")],
|
||||
[Html.text("Reset")]
|
||||
)
|
||||
let incBtn = Html.button(
|
||||
[Html.attr("onclick", "dispatch('Increment')")],
|
||||
[Html.text("+")]
|
||||
)
|
||||
let buttons = Html.div([Html.class("buttons")], [decBtn, resetBtn, incBtn])
|
||||
|
||||
let container = Html.div([Html.class("counter")], [title, display, buttons])
|
||||
|
||||
// Render to HTML string
|
||||
Html.render(container)
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Export for browser runtime
|
||||
// ============================================================================
|
||||
|
||||
fn luxInit(): Model = init()
|
||||
|
||||
fn luxUpdate(model: Model, msgName: String): Model =
|
||||
match msgName {
|
||||
"Increment" => update(model, Increment),
|
||||
"Decrement" => update(model, Decrement),
|
||||
"Reset" => update(model, Reset),
|
||||
_ => model
|
||||
}
|
||||
|
||||
fn luxView(model: Model): String = view(model)
|
||||
Reference in New Issue
Block a user