v0.26.0
https://github.com/ratatui/ratatui/releases/tag/v0.26.0
β οΈ See the breaking changes for this release.
FOSDEM π’
At the time this release is published, one of our maintainers (Orhun ParmaksΔ±z) will be giving an introductory talk about Ratatui at FOSDEM! The talk will be also recorded and streamed live.
See the event details here.
If you are around in person, donβt miss the chance to get some Ratatui stickers!
Demo: Destroy Mode π₯
We have a brand new demo which has a destroy mode! (Made for celebrating the 1000th commit of Ratatui)
To run it:
Press d
to activate destroy mode and enjoy!
Ref Widget Implementation π§©
Many widgets can now be rendered without changing their state.
We implemented WidgetRef
trait for references to widgets and changed their implementations to be
immutable. This allows us to render widgets without consuming them by passing a ref to the widget to
Frame::render_widget()
. It also allows boxed widgets to be rendered.
Note: this trait is gated behind a feature flag unstable-widget-ref
. The approach we take might
change for this (as there are approaches that would allow the code below to just use Widget
instead of WidgetRef
).
Layout: flex
β¨
We now support a new way to space the elements in a Layout
: Flex! We added a Flex
enum loosely
based on flexbox:
Flex::Start
(new default)Flex::Center
Flex::End
Flex::SpaceAround
Flex::SpaceBetween
Flex::Legacy
(old default)
In addition to changing the default to Flex::Start
, we have made a couple of changes to the
constraints.
Min(v)
grows to allocate excess space in allFlex
modes instead of shrinking (except inFlex::Legacy
where it retains old behavior).- We added a new constraint variant
Fill(1)
that grows to allocate excess space, growing equally withMin(v)
.
While is a breaking change to the behavior of constraints, most users should see identical layouts
with the new Flex::Start
, especially if Min()
is one of the constraints. However, you want the
old behavior, you can use Flex::Legacy
:
We have also removed the unstable feature SegmentSize
.
Check out the pull request for the motivation behind this feature and more information.
We have also built a constraint-explorer TUI that will allow you to compare how constraints behave
in different Flex
modes. Check out the pull request
for a video demo of the constraint-explorer
.
Color Palettes π¨
There are two brand new colors palettes ready to use, Material and Tailwind.
The
ratatui::style::palette::material
module contains the Google 2014 Material Design palette.
The
ratatui::style::palette::tailwind
module contains the default Tailwind color palette. This is useful for styling components with
colors that match the Tailwind color palette.
See https://m2.material.io/design/color/the-color-system.html#tools-for-picking-colors and https://tailwindcss.com/docs/customizing-colors for more information.
Alignment Convenience Functions ποΈ
We added the following alignment convenience functions for Line
, Paragraph
and Text
:
Line::from("align on left").left_aligned();
Line::from("centered!").centered();
Line::from("align on right").right_aligned();
Same applies for Paragraph
and Text
e.g. Paragraph::new("Hello, world!").centered()
.
Span
on the other hand has the following new methods:
Padding: New Constructors ποΈ
Padding
has new constructors:
Padding::proportional(4);
: make horizontal and vertical padding seem equalPadding::symmetric(5, 6);
: defines left and right paddingPadding::left(3);
: defines left paddingPadding::right(3);
: defines right paddingPadding::top(3);
: defines top paddingPadding::bottom(3);
: defines bottom padding
Block: bordered
π§±
Block
has a new constructor method named bordered
for avoiding creating a block with no borders
and setting Borders::ALL
.
So you can simplify your code as follows:
Color: New Constructors ποΈ
Color
can be constructed from u32
values now. The format is 0x00RRGGBB
:
We also added from_hsl
method for constructing Color::Rgb
values.
HSL stands for Hue (0-360 deg), Saturation (0-100%), and Lightness (0-100%) and working with HSL the values can be more intuitive. For example, if you want to make a red color more orange, you can change the Hue closer toward yellow on the color wheel (i.e. increase the Hue).
Layout: Increase Cache Size π
We increase the default cache size of layout from 16 to 500.
This is a somewhat arbitrary size for the layout cache based on adding the columns and rows on my laptopβs terminal (171+51 = 222) and doubling it for good measure and then adding a bit more to make it a round number. This gives enough entries to store a layout for every row and every column, twice over, which should be enough for most apps.
For those that need more, the cache size can be set with Layout::init_cache()
.
See the relevant discussion in this issue.
Layout: Horizontal and Vertical Constructors ποΈ
The Layout
now allows to create a vertical or horizontal layout with default values with the
following constructors:
Layout: Accept Constraints π
The Layout constructors now accept any type that implements Into<Constraint>
instead of just
AsRef<Constraint>
. This is useful when you want to specify a fixed size for a layout, but donβt
want to explicitly create a Constraint::Length yourself.
Layout: spacing
π
Spacing can now be added between the items of a layout.
Rect: contains
π²
If you want to perform hit tests, this new method is for you. (e.g. did the user click in an area)
We also added the Position
struct for storing the x and y coordinates (columns and rows).
Rect: clamp
π¦
There is a new useful method when you want to be able to dynamically move a rectangle around, but keep it constrained to a certain area.
For example, this can be used to implement a draggable window that can be moved around, but not outside the terminal window.
Layout: areas
and spacers
methods π
Now you can split a Rect
into multiple sub-Rect
s in a more concise way:
Rect: Rows/Colums Iterators π²
This enables iterating over rows and columns of a Rect this simplifies looping over cells.
Table: Accept Constraints π
Table constructors now accept any type that implements Into<Constraint>
instead of just
AsRef<Constraint>
. This is useful when you want to specify a fixed size for a table columns, but
donβt want to explicitly create a Constraint::Length yourself.
Table: Accepts Iterator π
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 also means that any iterator whose item is convertible into Row
can now be collected into a
Table
.
Table: Accept Text as highlight symbol π
You can now use multi-line symbols for highlighting items in a table.
See the demo
Table: footer
π
Table
now has a footer
method for setting the rows that will be displayed at the bottom.
Along with that, there is a new top_margin
method of Row
:
Widget Implementation π§©
Line
and Span
now implements Widget
which means it can be used as a child of other widgets.
You can also use Line::render()
to render it rather than calling buffer.set_line()
.
Same applies to Span
and you can use Span::render()
to render it rather than calling
buffer.set_span()
.
Line: styled
π¨
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()
).
Style: Accept Into π¨
All style related methods now accept S: Into<Style>
instead of Style
. Color
and Modifier
implement Into<Style>
so this is allows for more ergonomic usage. E.g.:
This means that if you are already passing an ambiguous type that implements Into<Style>
you will
need to remove the .into()
call.
Tabs: Accept Iterator of Line
π
Previously Tabs::new
required a Vec
, it can now accept any object that implements IntoIterator
with an item type implementing Into<Line>
.
Calls to Tabs::new()
whose argument is collected from an iterator will no longer compile.
For example, Tabs::new(["a","b"].into_iter().collect())
will no longer compile, because the return
type of .collect()
can no longer be inferred to be a Vec<_>
.
New Border Sets π²
We added the McGugan
border set, which allows for tighter borders.
Wide border set based on McGugan box technique:
Tall border set based on McGugan box technique:
Terminal: Frame Count π’
You can now get the current frame count!
This count is particularly useful when dealing with dynamic content or animations where the state of the display changes over time. By tracking the frame count, developers can synchronize updates or changes to the content with the rendering process.
Buffer: SSO π
We now apply SSO (small string optimization) technique to text buffer in buffer::Cell
i.e. use
CompactString
instead of String
to store the Cell::symbol
field. This saves reduces the size
of memory allocations at runtime.
See the related discussion here.
Other πΌ
- Rename
Constraint::Proportional
toConstraint::Fill
(#880) - Add Rect -> Size conversion methods (#789)
- Implement
Display
forText
,Line
,Span
(#826) - Support de/serialization of TableState, ListState, and ScrollbarState via
serde
feature - Implement FromIterator for Row (#755)
- Add
From
for termwiz style (#726) - Add style and alignment to
Text
(#807) - Collect iterator of
ListItem
intoList
(#775) - Remove deprecated
Block::title_on_bottom
(#757) - Make
patch_style
andreset_style
chainable (#754)