style: auto-format example files with lux fmt
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,14 +1,3 @@
|
||||
// Counter Example - A simple interactive counter using TEA pattern
|
||||
//
|
||||
// This example demonstrates:
|
||||
// - Model-View-Update architecture (TEA)
|
||||
// - Html DSL for describing UI (inline version)
|
||||
// - Message-based state updates
|
||||
|
||||
// ============================================================================
|
||||
// Html Types (subset of stdlib/html)
|
||||
// ============================================================================
|
||||
|
||||
type Html<M> =
|
||||
| Element(String, List<Attr<M>>, List<Html<M>>)
|
||||
| Text(String)
|
||||
@@ -19,130 +8,96 @@ type Attr<M> =
|
||||
| Id(String)
|
||||
| OnClick(M)
|
||||
|
||||
// Html builder helpers
|
||||
fn div<M>(attrs: List<Attr<M>>, children: List<Html<M>>): Html<M> =
|
||||
Element("div", attrs, children)
|
||||
fn div<M>(attrs: List<Attr<M>>, children: List<Html<M>>): Html<M> = Element("div", attrs, children)
|
||||
|
||||
fn span<M>(attrs: List<Attr<M>>, children: List<Html<M>>): Html<M> =
|
||||
Element("span", attrs, children)
|
||||
fn span<M>(attrs: List<Attr<M>>, children: List<Html<M>>): Html<M> = Element("span", attrs, children)
|
||||
|
||||
fn h1<M>(attrs: List<Attr<M>>, children: List<Html<M>>): Html<M> =
|
||||
Element("h1", attrs, children)
|
||||
fn h1<M>(attrs: List<Attr<M>>, children: List<Html<M>>): Html<M> = Element("h1", attrs, children)
|
||||
|
||||
fn button<M>(attrs: List<Attr<M>>, children: List<Html<M>>): Html<M> =
|
||||
Element("button", attrs, children)
|
||||
fn button<M>(attrs: List<Attr<M>>, children: List<Html<M>>): Html<M> = Element("button", attrs, children)
|
||||
|
||||
fn text<M>(content: String): Html<M> =
|
||||
Text(content)
|
||||
fn text<M>(content: String): Html<M> = Text(content)
|
||||
|
||||
fn class<M>(name: String): Attr<M> =
|
||||
Class(name)
|
||||
fn class<M>(name: String): Attr<M> = Class(name)
|
||||
|
||||
fn onClick<M>(msg: M): Attr<M> =
|
||||
OnClick(msg)
|
||||
|
||||
// ============================================================================
|
||||
// Model - The application state (using ADT wrapper)
|
||||
// ============================================================================
|
||||
fn onClick<M>(msg: M): Attr<M> = OnClick(msg)
|
||||
|
||||
type Model =
|
||||
| Counter(Int)
|
||||
|
||||
fn getCount(model: Model): Int =
|
||||
match model {
|
||||
Counter(n) => n
|
||||
}
|
||||
Counter(n) => n,
|
||||
}
|
||||
|
||||
fn init(): Model = Counter(0)
|
||||
|
||||
// ============================================================================
|
||||
// Messages - Events that can occur
|
||||
// ============================================================================
|
||||
|
||||
type Msg =
|
||||
| Increment
|
||||
| Decrement
|
||||
| Reset
|
||||
|
||||
// ============================================================================
|
||||
// Update - State transitions
|
||||
// ============================================================================
|
||||
|
||||
fn update(model: Model, msg: Msg): Model =
|
||||
match msg {
|
||||
Increment => Counter(getCount(model) + 1),
|
||||
Decrement => Counter(getCount(model) - 1),
|
||||
Reset => Counter(0)
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// View - Render the UI
|
||||
// ============================================================================
|
||||
Increment => Counter(getCount(model) + 1),
|
||||
Decrement => Counter(getCount(model) - 1),
|
||||
Reset => Counter(0),
|
||||
}
|
||||
|
||||
fn viewCounter(count: Int): Html<Msg> = {
|
||||
let countText = text(toString(count))
|
||||
let countSpan = span([class("count")], [countText])
|
||||
let displayDiv = div([class("counter-display")], [countSpan])
|
||||
|
||||
let minusBtn = button([onClick(Decrement), class("btn")], [text("-")])
|
||||
let resetBtn = button([onClick(Reset), class("btn btn-reset")], [text("Reset")])
|
||||
let plusBtn = button([onClick(Increment), class("btn")], [text("+")])
|
||||
let buttonsDiv = div([class("counter-buttons")], [minusBtn, resetBtn, plusBtn])
|
||||
|
||||
let title = h1([], [text("Counter")])
|
||||
div([class("counter-app")], [title, displayDiv, buttonsDiv])
|
||||
}
|
||||
|
||||
fn view(model: Model): Html<Msg> = viewCounter(getCount(model))
|
||||
|
||||
// ============================================================================
|
||||
// Debug: Print Html structure
|
||||
// ============================================================================
|
||||
|
||||
fn showAttr(attr: Attr<Msg>): String =
|
||||
match attr {
|
||||
Class(s) => "class=\"" + s + "\"",
|
||||
Id(s) => "id=\"" + s + "\"",
|
||||
OnClick(msg) => match msg {
|
||||
Increment => "onclick=\"Increment\"",
|
||||
Decrement => "onclick=\"Decrement\"",
|
||||
Reset => "onclick=\"Reset\""
|
||||
}
|
||||
}
|
||||
Class(s) => "class=\"" + s + "\"",
|
||||
Id(s) => "id=\"" + s + "\"",
|
||||
OnClick(msg) => match msg {
|
||||
Increment => "onclick=\"Increment\"",
|
||||
Decrement => "onclick=\"Decrement\"",
|
||||
Reset => "onclick=\"Reset\"",
|
||||
},
|
||||
}
|
||||
|
||||
fn showAttrs(attrs: List<Attr<Msg>>): String =
|
||||
match List.head(attrs) {
|
||||
None => "",
|
||||
Some(a) => match List.tail(attrs) {
|
||||
None => showAttr(a),
|
||||
Some(rest) => showAttr(a) + " " + showAttrs(rest)
|
||||
}
|
||||
}
|
||||
None => "",
|
||||
Some(a) => match List.tail(attrs) {
|
||||
None => showAttr(a),
|
||||
Some(rest) => showAttr(a) + " " + showAttrs(rest),
|
||||
},
|
||||
}
|
||||
|
||||
fn showChildren(children: List<Html<Msg>>, indent: Int): String =
|
||||
match List.head(children) {
|
||||
None => "",
|
||||
Some(c) => match List.tail(children) {
|
||||
None => showHtml(c, indent),
|
||||
Some(rest) => showHtml(c, indent) + showChildren(rest, indent)
|
||||
}
|
||||
}
|
||||
None => "",
|
||||
Some(c) => match List.tail(children) {
|
||||
None => showHtml(c, indent),
|
||||
Some(rest) => showHtml(c, indent) + showChildren(rest, indent),
|
||||
},
|
||||
}
|
||||
|
||||
fn showHtml(html: Html<Msg>, indent: Int): String =
|
||||
match html {
|
||||
Empty => "",
|
||||
Text(s) => s,
|
||||
Element(tag, attrs, children) => {
|
||||
let attrStr = showAttrs(attrs)
|
||||
let attrPart = if String.length(attrStr) > 0 then " " + attrStr else ""
|
||||
let childStr = showChildren(children, indent + 2)
|
||||
"<" + tag + attrPart + ">" + childStr + "</" + tag + ">"
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Entry point
|
||||
// ============================================================================
|
||||
Empty => "",
|
||||
Text(s) => s,
|
||||
Element(tag, attrs, children) => {
|
||||
let attrStr = showAttrs(attrs)
|
||||
let attrPart = if String.length(attrStr) > 0 then " " + attrStr else ""
|
||||
let childStr = showChildren(children, indent + 2)
|
||||
"<" + tag + attrPart + ">" + childStr + "</" + tag + ">"
|
||||
},
|
||||
}
|
||||
|
||||
fn main(): Unit with {Console} = {
|
||||
let model = init()
|
||||
@@ -150,24 +105,19 @@ fn main(): Unit with {Console} = {
|
||||
Console.print("")
|
||||
Console.print("Initial count: " + toString(getCount(model)))
|
||||
Console.print("")
|
||||
|
||||
let m1 = update(model, Increment)
|
||||
Console.print("After Increment: " + toString(getCount(m1)))
|
||||
|
||||
let m2 = update(m1, Increment)
|
||||
Console.print("After Increment: " + toString(getCount(m2)))
|
||||
|
||||
let m3 = update(m2, Increment)
|
||||
Console.print("After Increment: " + toString(getCount(m3)))
|
||||
|
||||
let m4 = update(m3, Decrement)
|
||||
Console.print("After Decrement: " + toString(getCount(m4)))
|
||||
|
||||
let m5 = update(m4, Reset)
|
||||
Console.print("After Reset: " + toString(getCount(m5)))
|
||||
|
||||
Console.print("")
|
||||
Console.print("=== View (HTML Structure) ===")
|
||||
Console.print(showHtml(view(m2), 0))
|
||||
}
|
||||
|
||||
let output = run main() with {}
|
||||
|
||||
Reference in New Issue
Block a user