1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
// IMPORTS ---------------------------------------------------------------------
import gleam/dict.{type Dict}
import gleam/dynamic.{type Decoder}
import gleam/int
import gleam/json
import gleam/result
import lustre/attribute
import lustre/effect.{type Effect}
import lustre/element.{type Element}
import lustre/element/html
import lustre/event
import lustre/server
import lustre/ui
// MODEL -----------------------------------------------------------------------
pub type Model =
Int
pub fn init(count: Int) -> #(Model, Effect(Msg)) {
#(count, effect.none())
}
// UPDATE ----------------------------------------------------------------------
pub opaque type Msg {
Incr
Decr
Reset(Int)
}
pub fn update(model: Model, msg: Msg) -> #(Model, Effect(Msg)) {
case msg {
Incr -> #(model + 1, effect.none())
Decr -> #(model - 1, effect.none())
Reset(count) -> #(
count,
effect.event(
"changed",
json.string("You reset the count to: " <> int.to_string(count)),
),
)
}
}
pub fn on_attribute_change() -> Dict(String, Decoder(Msg)) {
dict.from_list([
#("count", fn(dyn) {
dyn
|> dynamic.int
|> result.map(Reset)
}),
])
}
// VIEW ------------------------------------------------------------------------
pub fn view(model: Model) -> Element(Msg) {
let count = int.to_string(model)
ui.centre(
[attribute.style([#("width", "100vw"), #("height", "100vh")])],
ui.sequence([], [
ui.button([event.on_click(Decr)], [element.text("-")]),
ui.centre([], html.span([], [element.text(count)])),
ui.button([event.on_click(Incr)], [element.text("+")]),
]),
)
// ui.cluster([], [
// ui.input([event.on_input(Change), attribute.value(model.input)]),
// html.span([], [element.text(model.input)]),
// ]),
// ui.centre(
// [
// event.on("mousemove", on_mouse_move),
// server.include(["offsetX", "offsetY"]),
// attribute.style([
// #("aspect-ratio", "1 / 1 "),
// #("background-color", "var(--element-background)"),
// ]),
// ],
// html.div([], [
// html.p([], [element.text("x: " <> int.to_string(model.mouse.0))]),
// html.p([], [element.text("y: " <> int.to_string(model.mouse.1))]),
// ]),
// ),
}
|