actuate

Crates.ioactuate
lib.rsactuate
version
sourcesrc
created_at2024-02-23 23:51:59.140906
updated_at2024-12-13 19:42:53.606498
descriptionA reactive user-interface framework
homepage
repositoryhttps://github.com/actuate-rs/actuate
max_upload_size
id1151083
Cargo.toml error:TOML parse error at line 17, column 1 | 17 | autolib = false | ^^^^^^^ unknown field `autolib`, expected one of `name`, `version`, `edition`, `authors`, `description`, `readme`, `license`, `repository`, `homepage`, `documentation`, `build`, `resolver`, `links`, `default-run`, `default_dash_run`, `rust-version`, `rust_dash_version`, `rust_version`, `license-file`, `license_dash_file`, `license_file`, `licenseFile`, `license_capital_file`, `forced-target`, `forced_dash_target`, `autobins`, `autotests`, `autoexamples`, `autobenches`, `publish`, `metadata`, `keywords`, `categories`, `exclude`, `include`
size0
Matt Hunzinger (matthunz)

documentation

README

Actuate

Crates.io version docs.rs docs CI status
Examples

A high-performance and borrow-checker friendly framework for declarative programming in Rust. This crate provides a generic library that lets you define reactive components (also known as composables).

Features

  • Declarative scenes and UI for Bevy
  • Efficient and borrow-checker friendly state management: Manage state with components and hooks, all using zero-cost smart pointers
  • Generic core for custom backends
use actuate::prelude::*;

#[derive(Data)]
struct Counter {
    start: i32,
}

impl Compose for Counter {
    fn compose(cx: Scope<Self>) -> impl Compose {
        let count = use_mut(&cx, || cx.me().start);

        material_ui((
            text::headline(format!("High five count: {}", count)),
            button(text::label("Up high")).on_click(move || SignalMut::update(count, |x| *x += 1)),
            button(text::label("Down low")).on_click(move || SignalMut::update(count, |x| *x -= 1)),
            if *count == 0 {
                Some(text::label("Gimme five!"))
            } else {
                None
            },
        ))
        .align_items(AlignItems::Center)
        .justify_content(JustifyContent::Center)
    }
}

Borrowing

Composables can borrow from their ancestors, as well as state.

use actuate::prelude::*;

#[derive(Data)]
struct User<'a> {
    // `actuate::Cow` allows for either a borrowed or owned value.
    name: Cow<'a, String>,
}

impl Compose for User<'_> {
    fn compose(cx: Scope<Self>) -> impl Compose {
        text::headline(cx.me().name.to_string())
    }
}

#[derive(Data)]
struct App {
    name: String
}

impl Compose for App {
    fn compose(cx: Scope<Self>) -> impl Compose {
        // Get a mapped reference to the app's `name` field.
        let name = Signal::map(cx.me(), |me| &me.name).into();

        User { name }
    }
}

Installation

To add this crate to your project:

cargo add actuate --features full

For more feature flags, see the crate documentation for features.

Inspiration

This crate is inspired by Xilem and uses a similar approach to type-safe reactivity. The main difference with this crate is the concept of scopes, components store their state in their own scope and updates to that scope re-render the component.

State management is inspired by React and Dioxus.

Previous implementations were in Concoct but were never very compatible with lifetimes.

Commit count: 474

cargo fmt