diff options
author | Hayleigh Thompson <me@hayleigh.dev> | 2023-07-12 00:50:25 +0100 |
---|---|---|
committer | Hayleigh Thompson <me@hayleigh.dev> | 2023-07-12 00:50:25 +0100 |
commit | d295fe8369a282d2ebb61049b17b2a692b6e4b82 (patch) | |
tree | 80e70575b3818ececfd62eb244603bbf74f4646e | |
parent | a561cd04a127ec203d8d6441e8aba84ef3f22d1d (diff) | |
download | lustre-d295fe8369a282d2ebb61049b17b2a692b6e4b82.tar.gz lustre-d295fe8369a282d2ebb61049b17b2a692b6e4b82.zip |
:sparkles: Create an example showing nested 'components' and mapping messages.
-rw-r--r-- | test/counter.gleam | 30 | ||||
-rw-r--r-- | test/nested.gleam | 56 | ||||
-rw-r--r-- | test/nested.html | 15 |
3 files changed, 79 insertions, 22 deletions
diff --git a/test/counter.gleam b/test/counter.gleam index 5a5326b..d24500b 100644 --- a/test/counter.gleam +++ b/test/counter.gleam @@ -1,10 +1,8 @@ // IMPORTS --------------------------------------------------------------------- import gleam/int -import gleam/io -import gleam/option.{None} import lustre -import lustre/element.{Element, button, div, text} +import lustre/element.{Element, button, div, p, text} import lustre/event // MAIN ------------------------------------------------------------------------ @@ -13,7 +11,7 @@ pub fn main() { // A `simple` lustre application doesn't produce `Cmd`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 app = lustre.simple(init, update, render) let assert Ok(dispatch) = lustre.start(app, "body") dispatch(Incr) @@ -23,22 +21,22 @@ pub fn main() { // MODEL ----------------------------------------------------------------------- -type Model = +pub type Model = Int -fn init() -> Model { +pub fn init() -> Model { 0 } // UPDATE ---------------------------------------------------------------------- -type Msg { +pub opaque type Msg { Incr Decr Reset } -fn update(model: Model, msg: Msg) -> Model { +pub fn update(model: Model, msg: Msg) -> Model { case msg { Incr -> model + 1 Decr -> model - 1 @@ -48,26 +46,14 @@ fn update(model: Model, msg: Msg) -> Model { // VIEW ------------------------------------------------------------------------ -fn view(model: Model) -> Element(Msg) { +pub fn render(model: Model) -> Element(Msg) { div( [], [ button([event.on_click(Incr)], [text("+")]), button([event.on_click(Decr)], [text("-")]), button([event.on_click(Reset)], [text("Reset")]), - button( - [ - event.on( - "click", - fn(_) { - io.println("Do nothing") - None - }, - ), - ], - [text("Do Nothing")], - ), - div([], [text(int.to_string(model))]), + p([], [text(int.to_string(model))]), ], ) } diff --git a/test/nested.gleam b/test/nested.gleam new file mode 100644 index 0000000..8be6891 --- /dev/null +++ b/test/nested.gleam @@ -0,0 +1,56 @@ +// IMPORTS --------------------------------------------------------------------- + +import counter +import gleam/list +import gleam/map.{Map} +import lustre +import lustre/element.{Element, div} + +// MAIN ------------------------------------------------------------------------ + +pub fn main() { + // A `simple` lustre application doesn't produce `Cmd`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(dispatch) = lustre.start(app, "body") + + Nil +} + +// MODEL ----------------------------------------------------------------------- + +type Model = + Map(Int, counter.Model) + +fn init() -> Model { + use counters, id <- list.fold(list.range(1, 10), map.new()) + + map.insert(counters, id, counter.init()) +} + +// UPDATE ---------------------------------------------------------------------- + +type Msg = + #(Int, counter.Msg) + +fn update(model: Model, msg: Msg) -> Model { + let #(id, counter_msg) = msg + let assert Ok(counter) = map.get(model, id) + + map.insert(model, id, counter.update(counter, counter_msg)) +} + +// RENDER ---------------------------------------------------------------------- + +fn render(model: Model) -> Element(Msg) { + div( + [], + { + use #(id, counter) <- list.map(map.to_list(model)) + let tagger = fn(msg) { #(id, msg) } + + element.map(counter.render(counter), tagger) + }, + ) +} diff --git a/test/nested.html b/test/nested.html new file mode 100644 index 0000000..8602345 --- /dev/null +++ b/test/nested.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <title>lustre | nested</title> + + <script type="module"> + import { main } from "../build/dev/javascript/lustre/nested.mjs"; + + document.addEventListener("DOMContentLoaded", main); + </script> + </head> + <body></body> +</html> |