The Environment System
The Environment system is WaterUI's approach to dependency injection and configuration management. It provides a type-safe way to pass data, themes, services, and other dependencies through your view hierarchy without explicit parameter passing. Think of it as a context that flows down through your UI tree.
Basic Environment Usage
Storing Values
The most common way to add values to an environment is with the .with() method:
use waterui::prelude::*;
#[derive(Debug, Clone)]
struct AppConfig {
api_url: String,
timeout_seconds: u64,
}
#[derive(Debug, Clone)]
struct Theme {
primary_color: waterui::core::Color,
background_color: waterui::core::Color,
}
pub fn entry() -> impl View {
home()
.with(AppConfig {
api_url: "https://api.example.com".to_string(),
timeout_seconds: 30,
})
.with(Theme {
primary_color: (0.0, 0.4, 1.0).into(),
background_color: (1.0, 1.0, 1.0).into(),
})
}
pub fn home() -> impl View{
// Your home page
}
Accessing Values in Views
For Struct Views
Views can access environment values in their body method:
struct ApiStatusView;
impl View for ApiStatusView {
fn body(self, env: &Environment) -> impl View {
// Get configuration from environment
let config = env.get::<AppConfig>()
.expect("AppConfig should be provided");
let theme = env.get::<Theme>()
.expect("Theme should be provided");
vstack((
waterui_text::Text::new(config.api_url.clone()).foreground(theme.primary_color.clone()),
waterui_text::Text::new(format!("Timeout: {}s", config.timeout_seconds)).size(14.0),
))
.background(waterui::background::Background::color(theme.background_color.clone()))
}
}
For Function Views
Function views don't directly receive the env parameter. Instead, you can compose them with struct views that can access the environment. Alternatively, you can use action_with to extract values from the environment in event handlers.
In action
use waterui::prelude::*;
use waterui::reactive::binding;
#[derive(Debug, Clone)]
pub struct Message(&'static str);
pub fn click_me() -> impl View {
let value = binding(String::new());
vstack((
button("Show environment value").action_with(&value, |value, msg: waterui::core::extract::Use<Message>| {
value.set(msg.0 .0.to_string());
}),
text!("{}", value),
))
.with(Message("I'm Lexo"))
}