Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/jquesada2016/leptos-tea
The Elm Architecture state management for leptos.
https://github.com/jquesada2016/leptos-tea
Last synced: about 2 months ago
JSON representation
The Elm Architecture state management for leptos.
- Host: GitHub
- URL: https://github.com/jquesada2016/leptos-tea
- Owner: jquesada2016
- Created: 2023-03-12T23:42:19.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2023-09-20T21:15:04.000Z (over 1 year ago)
- Last Synced: 2024-04-26T08:20:46.354Z (9 months ago)
- Language: Rust
- Size: 47.9 KB
- Stars: 24
- Watchers: 2
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
- awesome-leptos - leptos-tea
README
The Elm Architecture for `leptos`.
This crate is a particular strategy for state management
in leptos`. It follows the Elm architecture, but not
strictly so, which allows mixing and matching with other state
management approaches.First, let's look at an example.
# Example
**Note**: This example uses the `nightly` feature flag for
both `leptos_tea` and `leptos`.```rust
use leptos::*;
use leptos_tea::Cmd;#[derive(Default, leptos_tea::Model)]
struct CounterModel {
counter: usize,
}#[derive(Default)]
enum Msg {
#[default]
Init,
Increment,
Decrement,
}fn update(model: UpdateCounterModel, msg: Msg, _: Cmd) {
match msg {
Msg::Increment => model.counter.update(|c| *c += 1),
Msg::Decrement => model.counter.update(|c| *c -= 1),
Msg::Init => {}
}
}#[component]
fn Counter(cx: Scope) -> impl IntoView {
let (model, msg_dispatcher) = CounterModel::default().init(cx, update);view! { cx,
{model.counter}
"-"
"+"
}
}
```In the above example, we're annotating `CounterModel` with
`leptos_tea::Model`, which will derive a few important things:```rust
# use leptos::*;
# use leptos_tea::Cmd;// Original struct, stays as-is
struct CounterModel {
counter: usize,
}// Model passed to the update function
struct UpdateCounterModel {
counter: RwSignal,
}// model passed to the component when you call `.init()`
struct ViewCounterModel {
counter: ReadSignal,
}impl CounterModel {
// Initializes everything and starts listening for messages.
// Msg::default() will be send to the update function when
// called
fn init(
self,
cx: Scope,
update_fn: impl Fn(UpdateCounterModel, Msg, Cmd),
) -> (ViewCounterModel, SignalSetter) {
/* ... */
# todo!()
}
}
```You first need to create your `CounterModel`, however you'd like.
In this case, we're using `Default`. Then you call `.init()`,
which will return a tuple containing the read-only model, as well
as a `MsgDispatcher`, which allows you to do `msg_dispatcher(Msg::Blah)`
on nightly, or `msg_dispatcher.dispatch(Msg::Blah)` on stable.And that's how this crate and state management approach works.
# Model nesting
Models can be nested inside one another like thus:
```rust
#[derive(leptos_tea::Model)]
struct Model {
#[model]
inner_model: InnerModel,
}#[derive(leptos_tea::Model)]
struct InnerModel(/* ... */);
```# Limitations
`leptos_tea::Model` currently only supports tuple and field structs.
Enum support will be added soon.# Features
- `nightly`: Implements `Fn(Msg)` for `MsgDispatcher`.