Create a custom widget
While Ratatui offers a rich set of pre-built widgets, there may be scenarios where you require a unique component tailored to specific needs. In such cases, creating a custom widget becomes invaluable. This page will guide you through the process of designing and implementing custom widgets.
Widget
trait
At the core of creating a custom widget is the Widget
trait. Any struct that implements this trait
can be rendered using the framework’s drawing capabilities.
pub struct MyWidget {
// Custom widget properties
content: String,
}
impl Widget for MyWidget {
fn render(self, area: Rect, buf: &mut Buffer) {
// Rendering logic goes here
}
}
The render
method must draw into the current Buffer
. There are a number of methods implemented
on Buffer
.
impl Widget for MyWidget {
fn render(self, area: Rect, buf: &mut Buffer) {
buf.set_string(area.left(), area.top(), &self.content, Style::default().fg(Color::Green));
}
}
For a given state, the Widget
trait implements how that struct should be rendered.
pub struct Button {
label: String,
is_pressed: bool,
style: Style,
pressed_style: Option<Style>,
}
impl Widget for Button {
fn render(self, area: Rect, buf: &mut Buffer) {
let style = if self.is_pressed {
self.pressed_style.unwrap_or_else(|| Style::default().fg(Color::Blue))
} else {
self.style
};
buf.set_string(area.left(), area.top(), &self.label, style);
}
}
Ratatui also has a StatefulWidget
. This is essentially a widget that can “remember” information
between two draw calls. This is essential when you have interactive UI components, like lists, where
you might need to remember which item was selected or how much the user has scrolled.
Here’s a breakdown of the trait:
pub trait StatefulWidget {
type State;
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State);
}
type State
: This represents the type of the state that this widget will use to remember details between draw calls.fn render(...)
: This method is responsible for drawing the widget on the terminal. Notably, it also receives a mutable reference to the state, allowing you to read from and modify the state as needed.