#signal #reactive #frp

macro futures-signals-component-macro

Macro for creating futures-signals compatible components

2 releases

0.1.1 Jul 5, 2024
0.1.0 Jun 30, 2024

#374 in GUI

Download history 125/week @ 2024-06-26 155/week @ 2024-07-03 356/week @ 2024-07-10 808/week @ 2024-07-17 1352/week @ 2024-07-24 763/week @ 2024-07-31 127/week @ 2024-08-07 101/week @ 2024-08-14 110/week @ 2024-08-21 124/week @ 2024-08-28

514 downloads per month

MIT license

36KB
697 lines

futures-signals-component-macros

This crates provides utility macros for making components based on futures-signals. Its purpose is to generate macro-style components that are flexible to use with both signal and non-signal properties, while not overloading the component implementation with type complexity.

Here's an example of how to create a component (in this case the output is a DOMINATOR Dom node, but it can be any rust type:

#[component(render_fn = some_button)]
pub struct SomeButton<T: ToString + Default = i32, U: ToI32 + ToString + Default = i32> {
    /// The button label. This can be a signal, which allows us to update the label dynamically based on state changes
    /// The macro also generates a setter for a non-signal setter, in case we just want to assign a static value to the property
    #[signal]
    pub label: String,
    
    #[signal]
    pub foo: T,

    #[signal]
    pub bar: U,

    #[signal_vec]
    #[default(vec![123])]
    pub some_generic_signal_vec: i32,
}

pub fn some_button(props: impl SomeButtonPropsTrait + 'static) -> Dom {
    let SomeButtonProps { label, .. } = props.take();

    html!("div", {
        .apply_if(label.is_some(), |b| {
            b.text_signal(label.unwrap())
        })
    })
}

To use this component, you can then use the generated some_button! macro, like so:

fn my_app(label: impl Signal<Item=String> + 'static) -> Dom {
    some_button!({
        .label_signal(label)
        .foo(42)
    })
}

Developing and testing

To run the tests locally, you need a few dependencies on your system.

First of all, you need rust. Install it following the instructions for your system at https://rustup.rs/

You also need the wasm32-unknown-unknown target:

rustup target add wasm32-unknown-unknown

And finally you will need the wasm-bindgen-cli tool to be able to run the in-browser tests:

cargo install wasm-bindgen-cli

Now you can run tests with the following commands:

cargo test & 
cargo test --target wasm32-unknown-unknown

Dependencies

~0.8–3.5MB
~70K SLoC