lemon 0.2.0-alpha.21

A reactive UI toolkit for Rust
Documentation
//! [`Component::new`]: nested views with isolated hook state (function pointer + optional `.key`).

use lemon::prelude::*;

fn mini_counter(cx: &Cx) -> Element {
    let n = cx.use_signal(0i32);
    let label = n.clone();
    let inc = n.clone();

    Row::new()
        .gap(8.0)
        .align_items(Align::Center)
        .children(children![
            Text::new(move || format!("{}", label.get())).font_size(16.0),
            Button::new(cx, "+")
                .on_click(move || inc.update(|v| *v += 1))
                .width(44.0),
        ])
        .into_element()
}

fn app(cx: &Cx) -> Element {
    let parent = cx.use_signal(0i32);
    let parent_label = parent.clone();
    let parent_inc = parent.clone();

    Column::new()
        .padding(24.0)
        .gap(14.0)
        .children(children![
            Text::new("Component").font_size(18.0),
            Text::new(
                "Component::new(fn) uses a function pointer — no capturing closures. Give each instance a .key when you have siblings of the same function.",
            )
            .font_size(14.0)
            .color(Color::rgb8(140, 150, 170)),
            Text::new("Parent scope (root Cx):")
                .font_size(15.0)
                .color(Color::rgb8(160, 170, 190)),
            Row::new().gap(8.0).children(children![
                Text::new(move || format!("parent = {}", parent_label.get())).font_size(16.0),
                Button::new(cx, "+ parent").on_click(move || parent_inc.update(|v| *v += 1)),
            ]),
            Text::new("Two child components — separate hook slots:")
                .font_size(15.0)
                .color(Color::rgb8(160, 170, 190)),
            Component::new(mini_counter).key(1),
            Component::new(mini_counter).key(2),
        ])
        .into_element()
}

fn main() {
    run(
        WindowConfig::default()
            .title("Lemon — Component")
            .size(520.0, 440.0),
        app,
    );
}