aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/07-routing/README.md6
-rw-r--r--examples/07-routing/gleam.toml2
-rw-r--r--examples/07-routing/header.pngbin0 -> 93127 bytes
-rw-r--r--examples/07-routing/manifest.toml14
-rw-r--r--examples/07-routing/src/app.gleam134
5 files changed, 137 insertions, 19 deletions
diff --git a/examples/07-routing/README.md b/examples/07-routing/README.md
index 6c0b261..5eaf0cd 100644
--- a/examples/07-routing/README.md
+++ b/examples/07-routing/README.md
@@ -2,12 +2,14 @@
# 07 Routing
+We haven't quite got round to documenting this example yet. You can still check out the [source code](./src/app.gleam) and run it with the following command:
+
```sh
-gleam run -m lustre/dev start --spa
+gleam run -m lustre/dev start --use-example-styles
```
## Getting help
-If you're having trouble with Lustre or not sure what the right way to do
+If you're having trouble with Lustre or are not sure what the right way to do
something is, the best place to get help is the [Gleam Discord server](https://discord.gg/Fm8Pwmy).
You could also open an issue on the [Lustre GitHub repository](https://github.com/lustre-labs/lustre/issues).
diff --git a/examples/07-routing/gleam.toml b/examples/07-routing/gleam.toml
index 5930290..cdecf3c 100644
--- a/examples/07-routing/gleam.toml
+++ b/examples/07-routing/gleam.toml
@@ -11,4 +11,4 @@ modem = "~> 1.0"
[dev-dependencies]
gleeunit = "~> 1.0"
-lustre_dev_tools = "~> 1.0"
+lustre_dev_tools = "~> 1.1"
diff --git a/examples/07-routing/header.png b/examples/07-routing/header.png
new file mode 100644
index 0000000..ffee3c6
--- /dev/null
+++ b/examples/07-routing/header.png
Binary files differ
diff --git a/examples/07-routing/manifest.toml b/examples/07-routing/manifest.toml
index 954f1a3..6000b9b 100644
--- a/examples/07-routing/manifest.toml
+++ b/examples/07-routing/manifest.toml
@@ -15,15 +15,15 @@ packages = [
{ name = "gleam_package_interface", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_json", "gleam_stdlib"], otp_app = "gleam_package_interface", source = "hex", outer_checksum = "52A721BCA972C8099BB881195D821AAA64B9F2655BECC102165D5A1097731F01" },
{ name = "gleam_stdlib", version = "0.36.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "C0D14D807FEC6F8A08A7C9EF8DFDE6AE5C10E40E21325B2B29365965D82EB3D4" },
{ name = "glearray", version = "0.2.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "glearray", source = "hex", outer_checksum = "908154F695D330E06A37FAB2C04119E8F315D643206F8F32B6A6C14A8709FFF4" },
- { name = "gleeunit", version = "1.0.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "D364C87AFEB26BDB4FB8A5ABDE67D635DC9FA52D6AB68416044C35B096C6882D" },
+ { name = "gleeunit", version = "1.1.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "72CDC3D3F719478F26C4E2C5FED3E657AC81EC14A47D2D2DEBB8693CA3220C3B" },
{ name = "glint", version = "0.18.0", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_community_colour", "gleam_stdlib", "snag"], otp_app = "glint", source = "hex", outer_checksum = "BB0F14643CC51C069A5DC6E9082EAFCD9967AFD1C9CC408803D1A40A3FD43B54" },
- { name = "lustre", version = "4.0.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_json", "gleam_otp", "gleam_stdlib"], otp_app = "lustre", source = "hex", outer_checksum = "1D40C1378279F7015687F8C9DB739D6880BB0B843F4428B85C61EDDA8BF21FC6" },
- { name = "lustre_dev_tools", version = "1.0.0", build_tools = ["gleam"], requirements = ["argv", "filepath", "gleam_community_ansi", "gleam_erlang", "gleam_json", "gleam_otp", "gleam_package_interface", "gleam_stdlib", "glint", "simplifile", "spinner", "tom"], otp_app = "lustre_dev_tools", source = "hex", outer_checksum = "66142ADDCA3D6C63A89E016CF6C21E07D06D6DC92479325182A07C360BD026D3" },
+ { name = "lustre", version = "4.1.4", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_json", "gleam_otp", "gleam_stdlib"], otp_app = "lustre", source = "hex", outer_checksum = "BA9ED993187B0BB721FFBB1F01F6CCA14548F68873C55567B77918D33D0D9ECB" },
+ { name = "lustre_dev_tools", version = "1.1.1", build_tools = ["gleam"], requirements = ["argv", "filepath", "gleam_community_ansi", "gleam_erlang", "gleam_json", "gleam_otp", "gleam_package_interface", "gleam_stdlib", "glint", "simplifile", "spinner", "tom"], otp_app = "lustre_dev_tools", source = "hex", outer_checksum = "16E34D9441FFCA0F5A4E13EAA910228275867F88971EC79ECD3F802375EA82BE" },
{ name = "lustre_http", version = "0.5.2", build_tools = ["gleam"], requirements = ["gleam_fetch", "gleam_http", "gleam_javascript", "gleam_json", "gleam_stdlib", "lustre"], otp_app = "lustre_http", source = "hex", outer_checksum = "FB0478CBFA6B16DBE8ECA326DAE2EC15645E04900595EF2C4F039ABFA0512ABA" },
- { name = "lustre_ui", version = "0.5.0", build_tools = ["gleam"], requirements = ["gleam_community_colour", "gleam_json", "gleam_stdlib", "lustre"], otp_app = "lustre_ui", source = "hex", outer_checksum = "7ECB5414BE926082401891C62FAAA21221FC0B7A2F0568A492349F48DC2B02A0" },
+ { name = "lustre_ui", version = "0.6.0", build_tools = ["gleam"], requirements = ["gleam_community_colour", "gleam_json", "gleam_stdlib", "lustre"], otp_app = "lustre_ui", source = "hex", outer_checksum = "FA1F9E89D89CDD5DF376ED86ABA8A38441CB2E664CD4D402F22A49DA4D7BB56D" },
{ name = "modem", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "lustre"], otp_app = "modem", source = "hex", outer_checksum = "584897B281E86458C513D9FB0D00C143507FA684042616A87BD4A4695B272FDE" },
{ name = "repeatedly", version = "2.1.1", build_tools = ["gleam"], requirements = [], otp_app = "repeatedly", source = "hex", outer_checksum = "38808C3EC382B0CD981336D5879C24ECB37FCB9C1D1BD128F7A80B0F74404D79" },
- { name = "simplifile", version = "1.5.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "C44DB387524F90DC42142699C78C850003289D32C7C99C7D32873792A299CDF7" },
+ { name = "simplifile", version = "1.6.1", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "B75D3C64E526D9D7EDEED5F3BA31DAAF5F2B4D80A4183FE17FDB02ED526E4E96" },
{ name = "snag", version = "0.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "snag", source = "hex", outer_checksum = "54D32E16E33655346AA3E66CBA7E191DE0A8793D2C05284E3EFB90AD2CE92BCC" },
{ name = "spinner", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_erlang", "gleam_stdlib", "glearray", "repeatedly"], otp_app = "spinner", source = "hex", outer_checksum = "200BA3D4A04D468898E63C0D316E23F526E02514BC46454091975CB5BAE41E8F" },
{ name = "thoas", version = "0.4.1", build_tools = ["rebar3"], requirements = [], otp_app = "thoas", source = "hex", outer_checksum = "4918D50026C073C4AB1388437132C77A6F6F7C8AC43C60C13758CC0ADCE2134E" },
@@ -34,7 +34,7 @@ packages = [
gleam_stdlib = { version = "~> 0.36" }
gleeunit = { version = "~> 1.0" }
lustre = { version = "~> 4.0" }
-lustre_dev_tools = { version = "~> 1.0" }
+lustre_dev_tools = { version = "~> 1.1" }
lustre_http = { version = "~> 0.5.2" }
lustre_ui = { version = "~> 0.4" }
-modem = { version = "~> 1.0"}
+modem = { version = "~> 1.0" }
diff --git a/examples/07-routing/src/app.gleam b/examples/07-routing/src/app.gleam
index a9d14d0..382bd60 100644
--- a/examples/07-routing/src/app.gleam
+++ b/examples/07-routing/src/app.gleam
@@ -1,4 +1,8 @@
import gleam/uri.{type Uri}
+import gleam/list
+import gleam/string
+import gleam/result
+import gleam/dynamic
import lustre
import lustre/attribute
import lustre/effect.{type Effect}
@@ -15,7 +19,6 @@ import modem
// In your own apps, make sure to add the `lustre/ui` dependency and include the
// stylesheet somewhere.
import lustre/ui
-import lustre/ui/aside
// MAIN ------------------------------------------------------------------------
@@ -27,31 +30,144 @@ pub fn main() {
// MODEL -----------------------------------------------------------------------
type Model {
- Model
+ Model(current: Route, guests: List(Guest), new_guest_name: String)
+}
+
+type Route {
+ Home
+ WelcomeGuest(value: String)
+}
+
+type Guest {
+ Guest(slug: String, name: String)
}
fn init(_) -> #(Model, Effect(Msg)) {
- #(Model, modem.init(on_route_change))
+ #(
+ Model(
+ current: Home,
+ guests: [
+ Guest(slug: "chihiro", name: "Chihiro"),
+ Guest(slug: "totoro", name: "Totoro"),
+ ],
+ new_guest_name: "",
+ ),
+ modem.init(on_route_change),
+ )
}
fn on_route_change(uri: Uri) -> Msg {
- let path = uri.path_segments(uri.path)
-
- RouterPushedPath(path)
+ case uri.path_segments(uri.path) {
+ ["welcome", guest] -> OnRouteChange(WelcomeGuest(guest))
+ _ -> OnRouteChange(Home)
+ }
}
// UPDATE ----------------------------------------------------------------------
pub opaque type Msg {
- RouterPushedPath(List(String))
+ OnRouteChange(Route)
+ UserUpdatedNewGuestName(String)
+ UserAddedNewGuest(Guest)
}
fn update(model: Model, msg: Msg) -> #(Model, Effect(Msg)) {
- todo
+ case msg {
+ OnRouteChange(route) -> #(Model(..model, current: route), effect.none())
+ UserUpdatedNewGuestName(name) -> #(
+ Model(..model, new_guest_name: name),
+ effect.none(),
+ )
+ UserAddedNewGuest(guest) -> #(
+ Model(
+ ..model,
+ guests: list.append(model.guests, [guest]),
+ new_guest_name: "",
+ ),
+ effect.none(),
+ )
+ }
}
// VIEW ------------------------------------------------------------------------
fn view(model: Model) -> Element(Msg) {
- todo
+ let styles = [#("margin", "15vh")]
+
+ let page = case model.current {
+ WelcomeGuest(name) -> render_welcome(model, name)
+ Home -> render_home(model)
+ }
+
+ ui.stack([attribute.style(styles)], [render_nav(model), page])
+}
+
+fn render_nav(model: Model) -> Element(a) {
+ let item_styles = [#("margin", "15px"), #("text-decoration", "underline")]
+
+ let nav_item = fn(path, text) {
+ html.a([attribute.href("/" <> path), attribute.style(item_styles)], [
+ element.text(text),
+ ])
+ }
+
+ let guests =
+ model.guests
+ |> list.map(fn(guest: Guest) {
+ nav_item("welcome/" <> guest.slug, guest.name)
+ })
+
+ html.nav([], [nav_item("", "Home"), ..guests])
+}
+
+fn render_home(model: Model) {
+ let new_guest_input = fn(event) {
+ use code <- result.try(dynamic.field("key", dynamic.string)(event))
+ case code {
+ "Enter" -> {
+ let guest_slug =
+ model.new_guest_name
+ |> string.replace(" ", "-")
+ |> string.lowercase
+ Ok(
+ UserAddedNewGuest(Guest(name: model.new_guest_name, slug: guest_slug)),
+ )
+ }
+ _ -> {
+ use value <- result.try(event.value(event))
+ Ok(UserUpdatedNewGuestName(value))
+ }
+ }
+ }
+ ui.centre(
+ [attribute.style([#("margin-top", "10vh")])],
+ ui.stack([], [
+ to_title("Welcome to the Party 🏡"),
+ html.label([], [element.text("Please sign the guest book:")]),
+ ui.input([
+ event.on("keyup", new_guest_input),
+ attribute.value(model.new_guest_name),
+ ]),
+ ]),
+ )
+}
+
+fn render_welcome(model: Model, slug) -> Element(a) {
+ let guest =
+ model.guests
+ |> list.find(fn(guest: Guest) { guest.slug == slug })
+
+ let title = case guest {
+ Ok(guest) -> to_title("Hello, " <> guest.name <> "! 🎉")
+ _ -> to_title("Sorry ... didn't quite catch that.")
+ }
+
+ ui.centre([attribute.style([#("margin-top", "10vh")])], title)
+}
+
+fn to_title(text) {
+ html.h1(
+ [attribute.style([#("font-size", "36px"), #("font-weight", "bold")])],
+ [element.text(text)],
+ )
}