| Crates.io | tumo_scope |
| lib.rs | tumo_scope |
| version | 0.1.0 |
| created_at | 2026-01-22 20:30:26.406844+00 |
| updated_at | 2026-01-22 20:30:26.406844+00 |
| description | A reactive UI toolkit for building GUI interfaces, inspired by Jetpack Compose. |
| homepage | |
| repository | https://gitee.com/mindbox/tumo |
| max_upload_size | |
| id | 2062567 |
| size | 63,031 |
A reactive UI toolkit for building GUI interfaces, inspired by Jetpack Compose. Scope provides a declarative syntax and component-based architecture for creating efficient, responsive user interfaces in Rust.
Scope is a modern UI toolkit that embraces the principles of reactive programming and declarative UI construction. It enables developers to build complex user interfaces with fine-grained state management and efficient re-composition.
Recomposition units are functions that generate UI descriptions. There are three types of composition units, each serving different purposes:
FnOnce(&mut Cx<'_, E>)Fn(&mut Cx<'_, E>) + 'staticFn(&mut Cx<'_, E>, f32, f32) + 'staticAny type can be used as state, internally stored using Rc to persist across recompositions. State comes in four variants:
Effects are functions of type FnOnce(&mut E) -> T used for executing side effects. They are triggered based on a rekey value (a u64 type) that identifies the effect's dependencies. This value can be a hash of the dependency content.
A mechanism for sharing data across multiple levels of recomposition, similar to Flutter's Provider pattern. Offers enable efficient data propagation through the component tree.
The E type in Cx<'_, E> represents the environment type, with only one instance per Context. Through Cx, you can directly dereference to &E, allowing all scopes read-only access to the environment. In effect functions, you can obtain &mut E and modify the environment. Scope definitions can specify required environment traits using E: Trait bounds.
use scope::prelude::*;
struct AppEnv {
counter: u32,
}
fn my_component(cx: &mut Cx<'_, AppEnv>) {
println!("print every re-composition: {}", env.counter);
cx.effect_once(move|env| {
println!("print once: {}", env.counter);
});
}
let mut ctx = Context::<AppEnv>::new(my_component);
let mut env = AppEnv { counter: 0 };
ctx.build_root(true, &mut env);
fn counter_component(cx: &mut Cx<'_, AppEnv>) {
let counter_state = 0.state(cx).bind(cx);
cx.effect(counter_state.peek(), |env| {
// This effect runs whenever counter_state changes
env.counter = counter_state.peek();
});
cx.effect_once(move|env| {
// Update state
counter_state.set(counter_state.peek() + 1);
});
}
struct Theme {
primary_color: Color,
}
impl Offer for Theme {}
fn theme_provider(cx: &mut Cx<'_, AppEnv>) {
let theme = Theme { primary_color: Color::BLUE };
theme.offer(cx);
cx.scope(cx.a(), |cx| {
if let Some(current_theme) = Theme::try_current(cx) {
// Use the offered theme
}
});
}
MIT