//! # 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); } }