mirror of
https://github.com/ratatui/ratatui.git
synced 2025-10-02 15:25:54 +00:00

Added comprehensive state management examples covering both immutable and mutable patterns and documentation to help developers choose the right approach for their applications.
79 lines
2.9 KiB
Rust
79 lines
2.9 KiB
Rust
//! # StatefulWidget Pattern (Recommended)
|
|
//!
|
|
//! This example demonstrates the `StatefulWidget` trait, which is the recommended approach for
|
|
//! handling mutable state in Ratatui applications. This pattern separates the widget's rendering
|
|
//! logic from its state, making it more flexible and reusable.
|
|
//!
|
|
//! This example runs with the Ratatui library code in the branch that you are currently
|
|
//! reading. See the [`latest`] branch for the code which works with the most recent Ratatui
|
|
//! release.
|
|
//!
|
|
//! [`latest`]: https://github.com/ratatui/ratatui/tree/latest
|
|
//!
|
|
//! ## When to Use This Pattern
|
|
//!
|
|
//! - Most Ratatui applications (this is the recommended default)
|
|
//! - When building reusable widget libraries
|
|
//! - When you need clean separation between rendering logic and state
|
|
//! - When multiple widgets might share similar state structures
|
|
//! - When you want to follow idiomatic Ratatui patterns
|
|
//!
|
|
//! ## Trade-offs
|
|
//!
|
|
//! **Pros:**
|
|
//! - Clean separation of concerns between widget and state
|
|
//! - Reusable - the same widget can work with different state instances
|
|
//! - Testable - state and rendering logic can be tested independently
|
|
//! - Composable - works well with complex application architectures
|
|
//! - Idiomatic - follows Ratatui's recommended patterns
|
|
//!
|
|
//! **Cons:**
|
|
//! - Slightly more verbose than direct mutation patterns
|
|
//! - Requires understanding of the `StatefulWidget` trait
|
|
//! - State must be managed externally
|
|
//!
|
|
//! ## Example Usage
|
|
//!
|
|
//! The widget defines its rendering behavior through `StatefulWidget`, while the state is
|
|
//! managed separately. This allows the same widget to be used with different state instances
|
|
//! and makes testing easier.
|
|
|
|
use ratatui::buffer::Buffer;
|
|
use ratatui::layout::Rect;
|
|
use ratatui::widgets::{StatefulWidget, Widget};
|
|
use ratatui_state_examples::is_exit_key_pressed;
|
|
|
|
/// Demonstrates the StatefulWidget pattern for mutable state management.
|
|
///
|
|
/// Creates a counter widget using `StatefulWidget` and runs the application loop,
|
|
/// updating the counter on each render cycle until the user exits.
|
|
fn main() -> color_eyre::Result<()> {
|
|
color_eyre::install()?;
|
|
ratatui::run(|terminal| {
|
|
let mut counter = 0;
|
|
loop {
|
|
terminal.draw(|frame| {
|
|
frame.render_stateful_widget(CounterWidget, frame.area(), &mut counter)
|
|
})?;
|
|
if is_exit_key_pressed()? {
|
|
break Ok(());
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
/// A counter widget that uses the StatefulWidget pattern for state management.
|
|
///
|
|
/// Demonstrates the separation of rendering logic from state, making the widget reusable
|
|
/// with different state instances and easier to test.
|
|
struct CounterWidget;
|
|
|
|
impl StatefulWidget for CounterWidget {
|
|
type State = usize;
|
|
|
|
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
|
|
*state += 1;
|
|
format!("Counter: {state}").render(area, buf);
|
|
}
|
|
}
|