aboutsummaryrefslogtreecommitdiff
path: root/lib/test/examples/components.gleam
blob: ed2f7f3891c0bf28f4a54922bc5e11d1219d49c6 (plain)
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_view,
      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, view)
  let assert Ok(_) = lustre.start(app, "[data-lustre-app]", Nil)

  Nil
}

fn init(_) {
  []
}

fn update(history, msg) {
  case msg {
    "reset" -> []
    _ -> [msg, ..history]
  }
}

fn view(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_view(count) {
  div(
    [],
    [
      button([event.on_click(Clicked)], [text("Click me!")]),
      p([], [text("Count: "), text(int.to_string(count))]),
      slot([]),
    ],
  )
}