v0.28.0
https://github.com/ratatui/ratatui/releases/tag/v0.28.0
β οΈ See the breaking changes for this release.
Crossterm 0.28.0 β¬οΈ
Crossterm is updated to version
0.28.0, which is a
semver incompatible version with the previous version (0.27.0
). Ratatui re-exports the version of
crossterm that it is compatible with under ratatui::crossterm
, which can be used to avoid
incompatible versions in your dependency list.
See this issue for more information.
Chart: Add GraphType::Bar π
We have introduced a new variant to GraphType
, named Bar
, which is designed to draw a bar for
each point in the dataset:
let chart = Chart::new(vec![Dataset::default() .data(&data) .marker(symbols::Marker::Dot) .graph_type(GraphType::Bar)]);
Async Example π
We added a new example which demonstrates how to use Ratatui with widgets that fetch data asynchronously.
The code is available here.
Barchart: Support Lines π
Previously, Axis::labels
accepted a Vec<Span>
. To make it more flexible, we have changed it to
accept a vector of any type that can be converted into a [Line
] (e.g., &str
, String
, &Line
,
Span
, etc.). This means any code using conversion methods that infer the type will need to be
rewritten as follows.
Axis::default().labels(vec!["a".into(), "b".into()])Axis::default().labels(["a", "b"])
Terminal: try_draw
β¨
We have added a new method to Terminal
called try_draw
, which functions similarly to
Terminal::draw
but allows the render callback to be a function or closure that returns a Result
instead of nothing (()
).
This makes it easier to handle fallible rendering methods using the ?
operator:
terminal.try_draw(|frame| { some_method_that_can_fail()?; another_fallible_method()?; Ok(())})?;
The method returns Result::Ok
with a CompletedFrame
if successful, or Result::Err
with the
std::io::Error
that caused the failure.
Terminal: Make terminal
module private π
The terminal module is now private and can not be used directly. The types under this module are exported from the root of the crate.
use ratatui::terminal::{CompletedFrame, Frame, Terminal, TerminalOptions, ViewPort};use ratatui::{CompletedFrame, Frame, Terminal, TerminalOptions, ViewPort};
This simplifies the public API, making it more user-friendly for those unfamiliar with Rustβs
re-exports and avoiding clashes with other modules named terminal
in backend code.
Backend: Add get/set_cursor_position()
π
If you implement the Backend
trait yourself, you need to update the implementation and add the
get/set_cursor_position
methods, which indicates more clearly what about the cursor to set.
These new methods return/accept Into<Position>
which can be either a Position
or a (u16, u16)
tuple.
backend.set_cursor_position(Position { x: 0, y: 20 })?;let position = backend.get_cursor_position()?;
terminal.set_cursor_position((0, 20))?;let position = terminal.set_cursor_position()?;
You can remove the get/set_cursor
methods from your implementation as they are deprecated and a
default implementation for them exists.
Buffer: Add cell
, cell_mut
and index
π§©
Buffer used to access elements with buf.get(x, y)
or buf.get_mut(x, y)
. Now, we have added
support for index operators and introduced buf.cell()
and buf.cell_mut()
methods.
These new methods use Into<Position>
for coordinates, making them easier to use and safer by
returning Option<&Cell>
and Option<&mut Cell>
, which helps avoid panics (yay).
let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 10));
// Access cellslet cell = buf[(0, 0)];let cell = buf[Position::new(0, 0)];
// Get symbollet symbol = buf.cell((0, 0)).map(|cell| cell.symbol());let symbol = buf.cell(Position::new(0, 0)).map(|cell| cell.symbol());
// Set symbolbuf[(0, 0)].set_symbol("π");buf[Position::new(0, 0)].set_symbol("π");buf.cell_mut((0, 0)).map(|cell| cell.set_symbol("π"));buf.cell_mut(Position::new(0, 0)).map(|cell| cell.set_symbol("π"));
The existing get()
and get_mut()
methods are now marked as deprecated.
Frame: Rename size()
to area()
π
It is just the more correct name. π§
Frame::size
is now deprecated.
Text: Add Add
and AddAssign
implementations βοΈ
You can now combine Line, Span, and Text types together while inferring their types!
let line = Span::raw("Red").red() + Span::raw("blue").blue();let line = Line::raw("Red").red() + Span::raw("blue").blue();let line = Line::raw("Red").red() + Line::raw("Blue").blue();let text = Line::raw("Red").red() + Line::raw("Blue").blue();let text = Text::raw("Red").red() + Line::raw("Blue").blue();
let mut line = Line::raw("Red").red();line += Span::raw("Blue").blue();
let mut text = Text::raw("Red").red();text += Line::raw("Blue").blue();
line.extend(vec![Span::raw("1"), Span::raw("2"), Span::raw("3")]);
Text: Remove unnecessary lifetime π§
The ToText
trait no longer has a
lifetime parameter.
This change simplifies the trait and makes it easier to implement.
List/Table: New Scroll Methods π½
We have implemented new scroll_down_by(u16)
and scroll_up_by(u16)
methods for both ListState
and TableState
, which allow you to scroll through the items by a specified number of positions.
let mut state = ListState::default();state.select(Some(2));state.scroll_down_by(4);assert_eq!(state.selected, Some(6));
let mut state = TableState::default();state.select(Some(3));state.scroll_up_by(3);assert_eq!(state.selected, Some(0));
Table: Navigation Methods π§
You can now navigate in the Table
widget by using the following methods!
let mut state = TableState::default();state.select_first();state.select_next();state.select_previous();state.select_last();
This is the equivalent API as in ListState
.
Tracking Benchmarks β²οΈ
We started using Bencher.dev to track benchmarks over time and easily catch any regressions.
You can view our benchmarks at https://bencher.dev/console/projects/ratatui.
For discussions about future improvements, check out the tracking issue.
Check Semver Violations π¦
We have started experimenting with
cargo-semver-checks
in our CI to lint our API
for semver violations!
See the PR for related discussion.
Other πΌ
- Return
Size
fromBackend::size
instead ofRect
(#1254) - Remove unnecessary synchronization in
Layout
cache (#1245)Layout::init_cache
no longer returns bool and takes aNonZeroUsize
instead ofusize
- Remove unnecessary allocations when creating
Line
s (#1237) - Avoid extra allocations when rendering
List
&Table
(#1244 & #1242) - Add
Size::ZERO
andPosition::ORIGIN
constants toLayout
(#1253) - Enable serde for
Margin
,Position
,Rect
andSize
(#1255) - Prevent area mismatch in
TestBackend
(changes the serde representation) (#1252) - Allow removing all the axis labels in
Chart
(#1282) - Only apply style to first line when rendering a
Line
(#1247) - Ensure emojis are rendered (#1258)
- Add Code of Conduct (#1279)
βIf you are what you eat, then I only want to eat the good stuff.β β Remy