xilem_web: Add Elm Architecture example (#425)

I have intentionally left out the `xilem_core::adapt` variant here in
order to have a clear classic Elm example. I would rather show the
`adapt` variant in a separate example.
This commit is contained in:
Markus Kohlhase 2024-07-12 13:39:37 +02:00 committed by GitHub
parent cf3530097b
commit 62c06c9f98
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 104 additions and 2 deletions

25
Cargo.lock generated
View File

@ -686,6 +686,17 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "console_log"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be8aed40e4edbf4d3b4431ab260b63fdc40f5780a4766824329ea0f1eefe3c0f"
dependencies = [
"log",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "core-foundation"
version = "0.9.4"
@ -900,6 +911,16 @@ dependencies = [
"wio",
]
[[package]]
name = "elm"
version = "0.0.0"
dependencies = [
"console_error_panic_hook",
"console_log",
"log",
"xilem_web",
]
[[package]]
name = "encode_unicode"
version = "0.3.6"
@ -1699,9 +1720,9 @@ dependencies = [
[[package]]
name = "log"
version = "0.4.21"
version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "malloc_buf"

View File

@ -8,6 +8,7 @@ members = [
"xilem_web",
"xilem_web/web_examples/counter",
"xilem_web/web_examples/counter_custom_element",
"xilem_web/web_examples/elm",
"xilem_web/web_examples/todomvc",
"xilem_web/web_examples/mathml_svg",
"xilem_web/web_examples/svgtoy",

View File

@ -0,0 +1,15 @@
[package]
name = "elm"
version = "0.0.0" # not versioned
publish = false
license.workspace = true
edition.workspace = true
[lints]
workspace = true
[dependencies]
console_error_panic_hook = "0.1.7"
console_log = { version = "1.0.0", features = ["color"] }
log = "0.4.22"
xilem_web = { path = "../.." }

View File

@ -0,0 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<title>Elm Architecture Example | Xilem Web</title>
</head>
<body></body>
</html>

View File

@ -0,0 +1,58 @@
// Copyright 2024 the Xilem Authors
// SPDX-License-Identifier: Apache-2.0
//! Xilem supports several patterns for creating modular components.
//! You can also emulate the elm architecture for a subset of your app.
//! Though usually it's more idiomatic to modularize state with
//! [`map_state`](xilem_web::core::map_state) or
//! [`adapt`](xilem_web::core::adapt).
use xilem_web::{
core::map_action,
document_body,
elements::html as el,
interfaces::{Element, HtmlDivElement},
Action, App,
};
#[derive(Debug, Default)]
struct Model {
count: i32,
}
#[derive(Debug)]
enum Message {
Increment,
Decrement,
}
impl Action for Message {}
fn update(model: &mut Model, message: Message) {
log::debug!("Update model {model:?} by {message:?}");
match message {
Message::Increment => model.count += 1,
Message::Decrement => model.count -= 1,
}
log::debug!("Model updated: {model:?}");
}
fn app_logic(model: &mut Model) -> impl HtmlDivElement<Model> {
log::debug!("Render view");
el::div((map_action(counter_view(model.count), update),))
}
fn counter_view<T: 'static>(count: i32) -> impl HtmlDivElement<T, Message> {
el::div((
el::label(format!("count: {count}")),
el::button("+").on_click(|_, _| Message::Increment),
el::button("-").on_click(|_, _| Message::Decrement),
))
}
pub fn main() {
_ = console_log::init_with_level(log::Level::Debug);
console_error_panic_hook::set_once();
log::info!("Start web application");
App::new(document_body(), Model::default(), app_logic).run();
}