
According to the issue linked from Cargo.toml, the intention has been to manually upgrade unicode-width every now and then, after verifying that the new version does not disrupt Ratatui. See https://github.com/ratatui/ratatui/issues/1271#issuecomment-2373917195. This PR unblocks using Ratatui in a dependency graph where some other crate requires some of the fixes that landed in unicode-width 0.2.1. Without this PR, Cargo blocks Ratatui from being used. ```console error: failed to select a version for `unicode-width`. ... required by package `ratatui v0.29.0` ... which satisfies dependency `ratatui = "^0.29"` of package `cargo v0.91.0` ... which satisfies path dependency `cargo` (locked to 0.91.0) of package `repro v0.0.0` versions that meet the requirements `=0.2.0` are: 0.2.0 all possible versions conflict with previously selected packages. previously selected package `unicode-width v0.2.1` ... which satisfies dependency `unicode-width = "^0.2.1"` of package `cargo v0.91.0` ... which satisfies path dependency `cargo` (locked to 0.91.0) of package `repro v0.0.0` failed to select a version for `unicode-width` which could resolve this conflict ```
41 KiB
Breaking Changes
This document contains a list of breaking changes in each version and some notes to help migrate between versions. It is compiled manually from the commit history and changelog. We also tag PRs on GitHub with a breaking change label.
Summary
This is a quick summary of the sections below:
- v0.30.0 Unreleased
Flex::SpaceAround
now mirrors flexbox: space between items is twice the size of the outer gaps are twice the size of first and last elementsblock::Title
no longer exists- The
From
impls for backend types are now replaced with more specific traits FrameExt
trait forunstable-widget-ref
featureList::highlight_symbol
now acceptsInto<Line>
instead of&str
- 'layout::Alignment' is renamed to 'layout::HorizontalAlignment'
- The MSRV is now 1.85.0
Backend
now requires an associatedError
type andclear_region
methodTestBackend
now usescore::convert::Infallible
for error handling instead ofstd::io::Error
- Disabling
default-features
will now disable layout cache, which can have a negative impact on performance Layout::init_cache
andLayout::DEFAULT_CACHE_SIZE
are now only available iflayout-cache
feature is enabled- Disabling
default-features
suppresses the error message ifshow_cursor()
fails when droppingTerminal
- Support a broader range for
unicode-width
version
- v0.29.0
Sparkline::data
takesIntoIterator<Item = SparklineBar>
instead of&[u64]
and is no longer const- Removed public fields from
Rect
iterators Line
now implementsFrom<Cow<str>
Table::highlight_style
is nowTable::row_highlight_style
Tabs::select
now acceptsInto<Option<usize>>
Color::from_hsl
is now behind thepalette
feature
- v0.28.0
Backend::size
returnsSize
instead ofRect
Backend
trait migrates toget/set_cursor_position
- Ratatui now requires Crossterm 0.28.0
Axis::labels
now acceptsIntoIterator<Into<Line>>
Layout::init_cache
no longer returns bool and takes aNonZeroUsize
instead ofusize
ratatui::terminal
module is now privateToText
no longer has a lifetimeFrame::size
is deprecated and renamed toFrame::area
- v0.27.0
- List no clamps the selected index to list
- Prelude items added / removed
- 'termion' updated to 4.0
Rect::inner
takesMargin
directly instead of referenceBuffer::filled
takesCell
directly instead of referenceStylize::bg()
now acceptsInto<Color>
- Removed deprecated
List::start_corner
LineGauge::gauge_style
is deprecated
- v0.26.0
Flex::Start
is the new default flex mode forLayout
patch_style
&reset_style
now consume and returnSelf
- Removed deprecated
Block::title_on_bottom
Line
now has an extrastyle
field which applies the style to the entire lineBlock
style methods cannot be created in a const contextTabs::new()
now acceptsIntoIterator<Item: Into<Line<'a>>>
Table::new
now acceptsIntoIterator<Item: Into<Row<'a>>>
.
- v0.25.0
- Removed
Axis::title_style
andBuffer::set_background
List::new()
now acceptsIntoIterator<Item = Into<ListItem<'a>>>
Table::new()
now requires specifying the widthsTable::widths()
now acceptsIntoIterator<Item = AsRef<Constraint>>
- Layout::new() now accepts direction and constraint parameters
- The default
Tabs::highlight_style
is nowStyle::new().reversed()
- Removed
- v0.24.0
- MSRV is now 1.70.0
ScrollbarState
:position
,content_length
, andviewport_content_length
are nowusize
BorderType
:line_symbols
is nowborder_symbols
and returnssymbols::border::set
Frame<'a, B: Backend>
is nowFrame<'a>
Stylize
shorthands forString
now consume the value and returnSpan<'static>
Spans
is removed
- v0.23.0
Scrollbar
:track_symbol
now takesOption<&str>
Scrollbar
: symbols moved tosymbols
module- MSRV is now 1.67.0
- v0.22.0
serde
representation ofBorders
andModifiers
has changed
- v0.21.0
- MSRV is now 1.65.0
terminal::ViewPort
is now an enum"".as_ref()
must be annotated to implementInto<Text<'a>>
Marker::Block
renders as a block char instead of a bar char
- v0.20.0
- MSRV is now 1.63.0
List
no longer ignores empty strings
v0.30.0 Unreleased
Flex::SpaceAround
now mirrors flexbox: space between items is twice the size of the outer gaps (#1952)
The old Flex::SpaceAround
behavior has been changed to distribute space evenly around each
element, with the middle spacers being twice the size of the first and last one. The old
behavior can be achieved by using Flex::SpaceEvenly
instead.
- let rects = Layout::horizontal([Length(1), Length(2)]).flex(Flex::SpaceAround).split(area);
+ let rects = Layout::horizontal([Length(1), Length(2)]).flex(Flex::SpaceEvenly).split(area);
block::Title
no longer exists (#1926)
The title alignment is better expressed in the Line
as this fits more coherently with the rest of
the library.
widgets::block
is no longer exportedwidgets::block::Title
no longer existswidgets::block::Position
is nowwidgets::TitlePosition
Block::title()
now acceptsInto::<Line>
instead ofInto<Title>
BlockExt
is now exported at widgets::BlockExt
instead ofwidgets::block::BlockExt
- use ratatui::widgets::{Block, block::{Title, Position}};
+ use ratatui::widgets::{Block, TitlePosition};
let block = Block::default()
- .title(Title::from("Hello"))
- .title(Title::from("Hello").position(Position::Bottom).alignment(Alignment::Center))
- .title_position(Position::Bottom);
+ .title(Line::from("Hello"))
+ .title_bottom(Line::from("Hello").centered());
+ .title_position(TitlePosition::Bottom);
- use ratatui::widgets::block::BlockExt;
+ use ratatui::widgets::BlockExt;
struct MyWidget {
block: Option<Block>,
}
impl Widget for &MyWidget {
fn render(self, area: Rect, buf: &mut Buffer) {
self.block.as_ref().render(area, buf);
let area = self.block.inner_if_some();
// ...
}
}
Style
no longer implements Styled
(#1572)
Any calls to methods implemented by the blanket implementation of Stylize
are now defined directly
on Style
. Remove the Stylize
import if it is no longer used by your code.
- use ratatui::style::Stylize;
let style = Style::new().red();
The reset()
method does not have a direct replacement, as it clashes with the existing reset()
method. Use the Style::reset()
method instead.
- some_style.reset();
+ Style::reset();
Disabling default-features
suppresses the error message if show_cursor()
fails when dropping Terminal
(#1794)
Since disabling default-features
disables std
, printing to stderr is not possible. It is
recommended to re-enable std
when not using Ratatui in no_std
environment.
Layout::init_cache
and Layout::DEFAULT_CACHE_SIZE
are now only available if layout-cache
feature is enabled (#1795)
Previously, Layout::init_cache
and Layout::DEFAULT_CACHE_SIZE
were available independently of
enabled feature flags.
Disabling default-features
will now disable layout cache, which can have a negative impact on performance (#1795)
Layout cache is now opt-in in ratatui-core
and enabled by default in ratatui
. If app doesn't
make use of no_std
-compatibility, and disables default-feature
, it is recommended to explicitly
re-enable layout cache. Not doing so may impact performance.
- ratatui = { version = "0.29.0", default-features = false }
+ ratatui = { version = "0.30.0", default-features = false, features = ["layout-cache"] }
TestBackend
now uses core::convert::Infallible
for error handling instead of std::io::Error
(#1823)
Since TestBackend
never fails, it now uses Infallible
as associated Error
. This may require
changes in test cases that use TestBackend
.
Backend
now requires an associated Error
type and clear_region
method (#1778)
Custom Backend
implementations must now define an associated Error
type for method Result
s
and implement the clear_region
method, which no longer has a default implementation.
This change was made to provide greater flexibility for custom backends, particularly to remove the
explicit dependency on std::io
for backends that want to support no_std
targets.
If your app or library uses the Backend
trait directly - for example, by providing a generic
implementation for many backends - you may need to update the referenced error type.
- fn run<B: Backend>(mut terminal: Terminal<B>) -> io::Result<()> {
+ fn run<B: Backend>(mut terminal: Terminal<B>) -> Result<(), B::Error> {
Alternatively, you can explicitly require the associated error to be std::io::Error
. This approach
may require fewer changes in user code but is generally not recommended, as it limits compatibility
with third-party backends. Additionally, the error type used by built-in backends may or may not
change in the future, making this approach less future-proof compared to the previous one.
- fn run<B: Backend>(mut terminal: Terminal<B>) -> io::Result<()> {
+ fn run<B: Backend<Error = io::Error>>(mut terminal: Terminal<B>) -> io::Result<()> {
If your application uses a concrete backend implementation, prefer specifying it explicitly instead.
- fn run<B: Backend>(mut terminal: Terminal<B>) -> io::Result<()> {
+ fn run(mut terminal: DefaultTerminal) -> io::Result<()> {
The MSRV is now 1.85.0 (#1860)
The minimum supported Rust version (MSRV) is now 1.85.0.
layout::Alignment
is renamed to layout::HorizontalAlignment
(#1735)
The Alignment
enum has been renamed to HorizontalAlignment
to better reflect its purpose. A type
alias has been added to maintain backwards compatibility, however there are some cases where type
aliases are not enough to maintain backwards compatibility. E.g. when using glob imports to import
all the enum variants.
We don't expect to remove or deprecate the type alias in the near future, but it is recommended to update your imports to use the new name.
- use ratatui::layout::Alignment;
+ use ratatui::layout::HorizontalAlignment;
- use Alignment::*;
+ use HorizontalAlignment::*;
List::highlight_symbol
accepts Into<Line>
(#1595)
Previously List::highlight_symbol
accepted &str
. Any code that uses conversion methods will need
to be rewritten. Since Into::into
is not const, this function cannot be called in const context.
FrameExt
trait for unstable-widget-ref
feature (#1530)
To call Frame::render_widget_ref()
or Frame::render_stateful_widget_ref()
you now need to:
- Import the
FrameExt
trait fromratatui::widgets
. - Enable the
unstable-widget-ref
feature.
For example:
use ratatui::{
layout::Rect,
widgets::{Block, FrameExt},
};
let block = Block::new();
let area = Rect::new(0, 0, 5, 5);
frame.render_widget_ref(&block, area);
WidgetRef
no longer has a blanket implementation of Widget
Previously there was a blanket implementation of Widget for WidgetRef. This has been reversed to instead be a blanket implementation of WidgetRef for all &W where W: Widget. Any widgets that previously implemented WidgetRef directly should now instead implement Widget for a reference to the type.
-impl WidgetRef for Foo {
- fn render_ref(&self, area: Rect, buf: &mut Buffer)
+impl Widget for &Foo {
+ fn render(self, area: Rect, buf: &mut Buffer)
}
The From
impls for backend types are now replaced with more specific traits #1464
Crossterm gains ratatui::backend::crossterm::{FromCrossterm, IntoCrossterm}
Termwiz gains ratatui::backend::termwiz::{FromTermwiz, IntoTermwiz}
This is necessary in order to avoid the orphan rule when implementing From
for crossterm types
once the crossterm types are moved to a separate crate.
+ use ratatui::backend::crossterm::{FromCrossterm, IntoCrossterm};
let crossterm_color = crossterm::style::Color::Black;
- let ratatui_color = crossterm_color.into();
- let ratatui_color = ratatui::style::Color::from(crossterm_color);
+ let ratatui_color = ratatui::style::Color::from_crossterm(crossterm_color);
- let crossterm_color = ratatui_color.into();
- let crossterm_color = crossterm::style::Color::from(ratatui_color);
+ let crossterm_color = ratatui_color.into_crossterm();
let crossterm_attribute = crossterm::style::types::Attribute::Bold;
- let ratatui_modifier = crossterm_attribute.into();
- let ratatui_modifier = ratatui::style::Modifier::from(crossterm_attribute);
+ let ratatui_modifier = ratatui::style::Modifier::from_crossterm(crossterm_attribute);
- let crossterm_attribute = ratatui_modifier.into();
- let crossterm_attribute = crossterm::style::types::Attribute::from(ratatui_modifier);
+ let crossterm_attribute = ratatui_modifier.into_crossterm();
Similar conversions for ContentStyle
-> Style
and Attributes
-> Modifier
exist for
Crossterm and the various Termion and Termwiz types as well.
Bar::label()
and BarGroup::label()
now accepts Into<Line<'a>>
. (#1471)
Previously Bar::label()
and BarGroup::label()
accepted Line<'a>
, but they now accepts Into<Line<'a>>
.
for Bar::label()
:
- Bar::default().label("foo".into());
+ Bar::default().label("foo");
for BarGroup::label()
:
- BarGroup::default().label("bar".into());
+ BarGroup::default().label("bar");
Bar::text_value
now accepts Into<String>
(#1471)
Previously Bar::text_value
accepted String
, but now it accepts Into<String>
.
for Bar::text_value()
:
- Bar::default().text_value("foobar".into());
+ Bar::default().text_value("foobar");
termwiz
is upgraded to 0.23.0 (#1682)
The termwiz
backend is upgraded from 0.22.0 to 0.23.0.
This release has a few fixes for hyperlinks and input handling, plus some dependency updates. See the commits for more details.
Support a broader range for unicode-width
version (#1999)
Ratatui's dependency on unicode-width
, previously pinned to 0.2.0, has
expanded to allow version 0.2.1. This comes with 2 behavior changes described in
unicode-width#61 and unicode-width#74.
v0.29.0
Sparkline::data
takes IntoIterator<Item = SparklineBar>
instead of &[u64]
and is no longer const (#1326)
The Sparkline::data
method has been modified to accept IntoIterator<Item = SparklineBar>
instead of &[u64]
.
SparklineBar
is a struct that contains an Option<u64>
value, which represents an possible
absent value, as distinct from a 0
value. This change allows the Sparkline
to style
data points differently, depending on whether they are present or absent.
SparklineBar
also contains an Option<Style>
that will be used to apply a style the bar in
addition to any other styling applied to the Sparkline
.
Several From
implementations have been added to SparklineBar
to support existing callers who
provide &[u64]
and other types that can be converted to SparklineBar
, such as Option<u64>
.
If you encounter any type inference issues, you may need to provide an explicit type for the data
passed to Sparkline::data
. For example, if you are passing a single value, you may need to use
into()
to convert it to form that can be used as a SparklineBar
:
let value = 1u8;
- Sparkline::default().data(&[value.into()]);
+ Sparkline::default().data(&[u64::from(value)]);
As a consequence of this change, the data
method is no longer a const fn
.
Color::from_hsl
is now behind the palette
feature and accepts palette::Hsl
(#1418)
Previously Color::from_hsl
accepted components as individual f64 parameters. It now accepts a
single palette::Hsl
value and is gated behind a palette
feature flag.
- Color::from_hsl(360.0, 100.0, 100.0)
+ Color::from_hsl(Hsl::new(360.0, 100.0, 100.0))
Removed public fields from Rect
iterators (#1358, #1424)
The pub
modifier has been removed from fields on the Columns
,Rows
, and Positions
iterators.
These fields were not intended to be public and should not have been accessed directly.
Rect::area()
now returns u32 instead of u16 (#1378)
This is likely to impact anything which relies on Rect::area
maxing out at u16::MAX. It can now
return up to u16::MAX * u16::MAX (2^32 - 2^17 + 1).
Line
now implements From<Cow<str>
(#1373)
As this adds an extra conversion, ambiguous inferred expressions may no longer compile.
// given:
struct Foo { ... }
impl From<Foo> for String { ... }
impl From<Foo> for Cow<str> { ... }
let foo = Foo { ... };
let line = Line::from(foo); // now fails due to now ambiguous inferred type
// replace with e.g.
let line = Line::from(String::from(foo));
Tabs::select()
now accepts Into<Option<usize>>
(#1413)
Previously Tabs::select()
accepted usize
, but it now accepts Into<Option<usize>>
. This breaks
any code already using parameter type inference:
let selected = 1u8;
- let tabs = Tabs::new(["A", "B"]).select(selected.into())
+ let tabs = Tabs::new(["A", "B"]).select(selected as usize)
Table::highlight_style
is now Table::row_highlight_style
(#1331)
The Table::highlight_style
is now deprecated in favor of Table::row_highlight_style
.
Also, the serialized output of the TableState
will now include the "selected_column" field.
Software that manually parse the serialized the output (with anything other than the Serialize
implementation on TableState
) may have to be refactored if the "selected_column" field is not
accounted for. This does not affect users who rely on the Deserialize
, or Serialize
implementation on the state.
v0.28.0
Backend::size
returns Size
instead of Rect
(#1254)
The Backend::size
method returns a Size
instead of a Rect
.
There is no need for the position here as it was always 0,0.
Backend
trait migrates to get/set_cursor_position
(#1284)
If you just use the types implementing the Backend
trait, you will see deprecation hints but
nothing is a breaking change for you.
If you implement the Backend trait yourself, you need to update the implementation and add the
get/set_cursor_position
method. You can remove the get/set_cursor
methods as they are deprecated
and a default implementation for them exists.
Ratatui now requires Crossterm 0.28.0 (#1278)
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.
Axis::labels()
now accepts IntoIterator<Into<Line>>
(#1273 and #1283)
Previously Axis::labels accepted Vec<Span>
. Any code that uses conversion methods that infer the
type will need to be rewritten as the compiler cannot infer the correct type.
- Axis::default().labels(vec!["a".into(), "b".into()])
+ Axis::default().labels(["a", "b"])
Layout::init_cache
no longer returns bool and takes a NonZeroUsize
instead of usize
(#1245)
- let is_initialized = Layout::init_cache(100);
+ Layout::init_cache(NonZeroUsize::new(100).unwrap());
ratatui::terminal
module is now private (#1160)
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. This reduces clashes with other modules in the backends that
are also named terminal, and confusion about module exports for newer Rust users.
- use ratatui::terminal::{CompletedFrame, Frame, Terminal, TerminalOptions, ViewPort};
+ use ratatui::{CompletedFrame, Frame, Terminal, TerminalOptions, ViewPort};
ToText
no longer has a lifetime (#1234)
This change simplifies the trait and makes it easier to implement.
Frame::size
is deprecated and renamed to Frame::area
(#1293)
Frame::size
is renamed to Frame::area
as it's the more correct name.
v0.27.0
List no clamps the selected index to list ([#1159])
The List
widget now clamps the selected index to the bounds of the list when navigating with
first
, last
, previous
, and next
, as well as when setting the index directly with select
.
Previously selecting an index past the end of the list would show treat the list as having a selection which was not visible. Now the last item in the list will be selected instead.
Prelude items added / removed (#1149)
The following items have been removed from the prelude:
style::Styled
- this trait is useful for widgets that want to support the Stylize trait, but it adds complexity as widgets have twostyle
methods and aset_style
method.symbols::Marker
- this item is used by code that needs to draw to theCanvas
widget, but it's not a common item that would be used by most users of the library.terminal::{CompletedFrame, TerminalOptions, Viewport}
- these items are rarely used by code that needs to interact with the terminal, and they're generally only ever used once in any app.
The following items have been added to the prelude:
layout::{Position, Size}
- these items are used by code that needs to interact with the layout system. These are newer items that were added in the last few releases, which should be used more liberally. This may cause conflicts for types defined elsewhere with a similar name.
To update your app:
// if your app uses Styled::style() or Styled::set_style():
-use ratatui::prelude::*;
+use ratatui::{prelude::*, style::Styled};
// if your app uses symbols::Marker:
-use ratatui::prelude::*;
+use ratatui::{prelude::*, symbols::Marker}
// if your app uses terminal::{CompletedFrame, TerminalOptions, Viewport}
-use ratatui::prelude::*;
+use ratatui::{prelude::*, terminal::{CompletedFrame, TerminalOptions, Viewport}};
// to disambiguate existing types named Position or Size:
- use some_crate::{Position, Size};
- let size: Size = ...;
- let position: Position = ...;
+ let size: some_crate::Size = ...;
+ let position: some_crate::Position = ...;
Termion is updated to 4.0 #1106
Changelog: https://gitlab.redox-os.org/redox-os/termion/-/blob/master/CHANGELOG.md
A change is only necessary if you were matching on all variants of the MouseEvent
enum without a
wildcard. In this case, you need to either handle the two new variants, MouseLeft
and
MouseRight
, or add a wildcard.
Rect::inner
takes Margin
directly instead of reference (#1008)
Margin
needs to be passed without reference now.
-let area = area.inner(&Margin {
+let area = area.inner(Margin {
vertical: 0,
horizontal: 2,
});
Buffer::filled
takes Cell
directly instead of reference (#1148)
Buffer::filled
moves the Cell
instead of taking a reference.
-Buffer::filled(area, &Cell::new("X"));
+Buffer::filled(area, Cell::new("X"));
Stylize::bg()
now accepts Into<Color>
(#1103)
Previously, Stylize::bg()
accepted Color
but now accepts Into<Color>
. This allows more
flexible types from calling scopes, though it can break some type inference in the calling scope.
Remove deprecated List::start_corner
and layout::Corner
(#759)
List::start_corner
was deprecated in v0.25. Use List::direction
and ListDirection
instead.
- list.start_corner(Corner::TopLeft);
- list.start_corner(Corner::TopRight);
// This is not an error, BottomRight rendered top to bottom previously
- list.start_corner(Corner::BottomRight);
// all becomes
+ list.direction(ListDirection::TopToBottom);
- list.start_corner(Corner::BottomLeft);
// becomes
+ list.direction(ListDirection::BottomToTop);
layout::Corner
was removed entirely.
LineGauge::gauge_style
is deprecated (#565)
LineGauge::gauge_style
is deprecated and replaced with LineGauge::filled_style
and LineGauge::unfilled_style
:
let gauge = LineGauge::default()
- .gauge_style(Style::default().fg(Color::Red).bg(Color::Blue)
+ .filled_style(Style::default().fg(Color::Green))
+ .unfilled_style(Style::default().fg(Color::White));
v0.26.0
Flex::Start
is the new default flex mode for Layout
(#881)
Previously, constraints would stretch to fill all available space, violating constraints if necessary.
With v0.26.0, Flex
modes are introduced, and the default is Flex::Start
, which will align
areas associated with constraints to be beginning of the area. With v0.26.0, additionally,
Min
constraints grow to fill excess space. These changes will allow users to build layouts
more easily.
With v0.26.0, users will most likely not need to change what constraints they use to create
existing layouts with Flex::Start
. However, to get old behavior, use Flex::Legacy
.
- let rects = Layout::horizontal([Length(1), Length(2)]).split(area);
// becomes
+ let rects = Layout::horizontal([Length(1), Length(2)]).flex(Flex::Legacy).split(area);
Table::new()
now accepts IntoIterator<Item: Into<Row<'a>>>
(#774)
Previously, Table::new()
accepted IntoIterator<Item=Row<'a>>
. The argument change to
IntoIterator<Item: Into<Row<'a>>>
, This allows more flexible types from calling scopes, though it
can some break type inference in the calling scope for empty containers.
This can be resolved either by providing an explicit type (e.g. Vec::<Row>::new()
), or by using
Table::default()
.
- let table = Table::new(vec![], widths);
// becomes
+ let table = Table::default().widths(widths);
Tabs::new()
now accepts IntoIterator<Item: Into<Line<'a>>>
(#776)
Previously, Tabs::new()
accepted Vec<T>
where T: Into<Line<'a>>
. This allows more flexible
types from calling scopes, though it can break some type inference in the calling scope.
This typically occurs when collecting an iterator prior to calling Tabs::new
, and can be resolved
by removing the call to .collect()
.
- let tabs = Tabs::new((0.3).map(|i| format!("{i}")).collect());
// becomes
+ let tabs = Tabs::new((0.3).map(|i| format!("{i}")));
Table::default() now sets segment_size to None and column_spacing to (#751)
The default() implementation of Table now sets the column_spacing field to 1 and the segment_size
field to SegmentSize::None
. This will affect the rendering of a small amount of apps.
To use the previous default values, call table.segment_size(Default::default())
and
table.column_spacing(0)
.
patch_style
& reset_style
now consumes and returns Self
(#754)
Previously, patch_style
and reset_style
in Text
, Line
and Span
were using a mutable
reference to Self
. To be more consistent with the rest of ratatui
, which is using fluent
setters, these now take ownership of Self
and return it.
The following example shows how to migrate for Line
, but the same applies for Text
and Span
.
- let mut line = Line::from("foobar");
- line.patch_style(style);
// becomes
+ let line = Line::new("foobar").patch_style(style);
Remove deprecated Block::title_on_bottom
([#757])
Block::title_on_bottom
was deprecated in v0.22. Use Block::title
and Title::position
instead.
- block.title("foobar").title_on_bottom();
+ block.title(Title::from("foobar").position(Position::Bottom));
Block
style methods cannot be used in a const context (#720)
Previously the style()
, border_style()
and title_style()
methods could be used to create a
Block
in a constant context. These now accept Into<Style>
instead of Style
. These methods no
longer can be called from a constant context.
Line
now has a style
field that applies to the entire line (#708)
Previously the style of a Line
was stored in the Span
s that make up the line. Now the Line
itself has a style
field, which can be set with the Line::styled
method. Any code that creates
Line
s using the struct initializer instead of constructors will fail to compile due to the added
field. This can be easily fixed by adding ..Default::default()
to the field list or by using a
constructor method (Line::styled()
, Line::raw()
) or conversion method (Line::from()
).
Each Span
contained within the line will no longer have the style that is applied to the line in
the Span::style
field.
let line = Line {
spans: vec!["".into()],
alignment: Alignment::Left,
+ ..Default::default()
};
// or
let line = Line::raw(vec!["".into()])
.alignment(Alignment::Left);
v0.25.0
Removed Axis::title_style
and Buffer::set_background
(#691)
These items were deprecated since 0.10.
- You should use styling capabilities of
text::Line
given as argument ofAxis::title
instead ofAxis::title_style
- You should use styling capabilities of
Buffer::set_style
instead ofBuffer::set_background
List::new()
now accepts IntoIterator<Item = Into<ListItem<'a>>>
(#672)
Previously List::new()
took Into<Vec<ListItem<'a>>>
. This change will throw a compilation
error for IntoIterator
s with an indeterminate item (e.g. empty vecs).
E.g.
- let list = List::new(vec![]);
// becomes
+ let list = List::default();
The default Tabs::highlight_style
is now Style::new().reversed()
(#635)
Previously the default highlight style for tabs was Style::default()
, which meant that a Tabs
widget in the default configuration would not show any indication of the selected tab.
The default Tabs::highlight_style
is now Style::new().reversed()
(#635)
Previously the default highlight style for tabs was Style::default()
, which meant that a Tabs
widget in the default configuration would not show any indication of the selected tab.
Table::new()
now requires specifying the widths of the columns (#664)
Previously Table
s could be constructed without widths
. In almost all cases this is an error.
A new widths
parameter is now mandatory on Table::new()
. Existing code of the form:
- Table::new(rows).widths(widths)
Should be updated to:
+ Table::new(rows, widths)
For ease of automated replacement in cases where the amount of code broken by this change is large
or complex, it may be convenient to replace Table::new
with Table::default().rows
.
- Table::new(rows).block(block).widths(widths);
// becomes
+ Table::default().rows(rows).widths(widths)
Table::widths()
now accepts IntoIterator<Item = AsRef<Constraint>>
(#663)
Previously Table::widths()
took a slice (&'a [Constraint]
). This change will introduce clippy
needless_borrow
warnings for places where slices are passed to this method. To fix these, remove
the &
.
E.g.
- let table = Table::new(rows).widths(&[Constraint::Length(1)]);
// becomes
+ let table = Table::new(rows, [Constraint::Length(1)]);
Layout::new() now accepts direction and constraint parameters (#557)
Previously layout new took no parameters. Existing code should either use Layout::default()
or
the new constructor.
let layout = layout::new()
.direction(Direction::Vertical)
.constraints([Constraint::Min(1), Constraint::Max(2)]);
// becomes either
let layout = layout::default()
.direction(Direction::Vertical)
.constraints([Constraint::Min(1), Constraint::Max(2)]);
// or
let layout = layout::new(Direction::Vertical, [Constraint::Min(1), Constraint::Max(2)]);
v0.24.0
ScrollbarState
field type changed from u16
to usize
(#456)
In order to support larger content lengths, the position
, content_length
and
viewport_content_length
methods on ScrollbarState
now take usize
instead of u16
BorderType::line_symbols
renamed to border_symbols
(#529)
Applications can now set custom borders on a Block
by calling border_set()
. The
BorderType::line_symbols()
is renamed to border_symbols()
and now returns a new struct
symbols::border::Set
. E.g.:
- let line_set: symbols::line::Set = BorderType::line_symbols(BorderType::Plain);
// becomes
+ let border_set: symbols::border::Set = BorderType::border_symbols(BorderType::Plain);
Generic Backend
parameter removed from Frame
(#530)
Frame
is no longer generic over Backend. Code that accepted Frame<Backend>
will now need to
accept Frame
. To migrate existing code, remove any generic parameters from code that uses an
instance of a Frame. E.g.:
- fn ui<B: Backend>(frame: &mut Frame<B>) { ... }
// becomes
+ fn ui(frame: Frame) { ... }
Stylize
shorthands now consume rather than borrow String
(#466)
In order to support using Stylize
shorthands (e.g. "foo".red()
) on temporary String
values, a
new implementation of Stylize
was added that returns a Span<'static>
. This causes the value to
be consumed rather than borrowed. Existing code that expects to use the string after a call will no
longer compile. E.g.
- let s = String::new("foo");
- let span1 = s.red();
- let span2 = s.blue(); // will no longer compile as s is consumed by the previous line
// becomes
+ let span1 = s.clone().red();
+ let span2 = s.blue();
Deprecated Spans
type removed (replaced with Line
) (#426)
Spans
was replaced with Line
in 0.21.0. Buffer::set_spans
was replaced with
Buffer::set_line
.
- let spans = Spans::from(some_string_str_span_or_vec_span);
- buffer.set_spans(0, 0, spans, 10);
// becomes
+ let line - Line::from(some_string_str_span_or_vec_span);
+ buffer.set_line(0, 0, line, 10);
v0.23.0
Scrollbar::track_symbol()
now takes an Option<&str>
instead of &str
(#360)
The track symbol of Scrollbar
is now optional, this method now takes an optional value.
- let scrollbar = Scrollbar::default().track_symbol("|");
// becomes
+ let scrollbar = Scrollbar::default().track_symbol(Some("|"));
Scrollbar
symbols moved to symbols::scrollbar
and widgets::scrollbar
module is private (#330)
The symbols for defining scrollbars have been moved to the symbols
module from the
widgets::scrollbar
module which is no longer public. To update your code update any imports to the
new module locations. E.g.:
- use ratatui::{widgets::scrollbar::{Scrollbar, Set}};
// becomes
+ use ratatui::{widgets::Scrollbar, symbols::scrollbar::Set}
MSRV updated to 1.67 (#361)
The MSRV of ratatui is now 1.67 due to an MSRV update in a dependency (time
).
v0.22.0
bitflags
updated to 2.3 (#205)
The serde
representation of bitflags
has changed. Any existing serialized types that have
Borders or Modifiers will need to be re-serialized. This is documented in the bitflags
changelog..
v0.21.0
MSRV is 1.65.0 (#171)
The minimum supported rust version is now 1.65.0.
Terminal::with_options()
stabilized to allow configuring the viewport (#114)
In order to support inline viewports, the unstable method Terminal::with_options()
was stabilized
and ViewPort
was changed from a struct to an enum.
let terminal = Terminal::with_options(backend, TerminalOptions {
- viewport: Viewport::fixed(area),
});
// becomes
let terminal = Terminal::with_options(backend, TerminalOptions {
+ viewport: Viewport::Fixed(area),
});
Code that binds Into<Text<'a>>
now requires type annotations (#168)
A new type Masked
was introduced that implements From<Text<'a>>
. This causes any code that
previously did not need to use type annotations to fail to compile. To fix this, annotate or call
to_string()
/ to_owned()
/ as_str()
on the value. E.g.:
- let paragraph = Paragraph::new("".as_ref());
// becomes
+ let paragraph = Paragraph::new("".as_str());
Marker::Block
now renders as a block rather than a bar character (#133)
Code using the Block
marker that previously rendered using a half block character ('▀'``) now renders using the full block character (
'█'). A new marker variant
Bar` is introduced to replace
the existing code.
- let canvas = Canvas::default().marker(Marker::Block);
// becomes
+ let canvas = Canvas::default().marker(Marker::Bar);
v0.20.0
v0.20.0 was the first release of Ratatui - versions prior to this were release as tui-rs. See the Changelog for more details.
MSRV is update to 1.63.0 (#80)
The minimum supported rust version is 1.63.0
List no longer ignores empty string in items (#42)
The following code now renders 3 items instead of 2. Code which relies on the previous behavior will need to manually filter empty items prior to display.
let items = vec![
ListItem::new("line one"),
ListItem::new(""),
ListItem::new("line four"),
];