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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
// IMPORTS ---------------------------------------------------------------------
import gleam/dynamic
import gleam/int
import gleam/list
import gleam/map
import gleam/option.{Some}
import gleam/result
import lustre
import lustre/attribute
import lustre/effect
import lustre/element.{element, text}
import lustre/element/html.{button, div, li, ol, p, slot}
import lustre/event
// MAIN ------------------------------------------------------------------------
pub fn main() {
let assert Ok(_) =
lustre.component(
"custom-counter",
counter_init,
counter_update,
counter_render,
map.from_list([
#(
"count",
fn(attr) {
dynamic.int(attr)
|> result.map(GotCount)
},
),
]),
)
// A `simple` lustre application doesn't produce `Effect`s. These are best to
// start with if you're just getting started with lustre or you know you don't
// need the runtime to manage any side effects.
let app = lustre.simple(init, update, render)
let assert Ok(_) = lustre.start(app, "[data-lustre-app]")
Nil
}
fn init() {
[]
}
fn update(history, msg) {
case msg {
"reset" -> []
_ -> [msg, ..history]
}
}
fn render(history) {
let on_custom_click = {
use _ <- event.on("custom-click")
Some("click")
}
div(
[],
[
button([event.on_click("reset")], [text("Reset")]),
ol([], list.map(history, fn(msg) { li([], [text(msg)]) })),
element(
"custom-counter",
[on_custom_click, attribute.property("count", list.length(history))],
[ol([], list.map(history, fn(msg) { li([], [text(msg)]) }))],
),
],
)
}
// COUNTER ---------------------------------------------------------------------
fn counter_init() {
#(0, effect.none())
}
type CounterMsg {
GotCount(Int)
Clicked
}
fn counter_update(count, msg) {
case msg {
GotCount(count) -> #(count, effect.none())
Clicked -> #(count, event.emit("custom-click", Nil))
}
}
fn counter_render(count) {
div(
[],
[
button([event.on_click(Clicked)], [text("Click me!")]),
p([], [text("Count: "), text(int.to_string(count))]),
slot([]),
],
)
}
|