NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
crates.io · #1261 most downloaded on crates.io
A library that's all about cooking up terminal user interfaces
Last release 3 months ago
19 Jun 2026
Release timing varies
gaps range from 2 weeks to 5 months
Nearly every release is documented
notes for 18 of 19 stable releases
Nothing withdrawn
no release was ever pulled
4 years old
87 releases · first in 2023
One column per quarter.
2cfe82a _(buffer)_ Deprecate assert_buffer_eq! in favor of assert_eq! by @EdJoPaTo in #1007
We are happy to announce a brand new Ratatui Forum 🐭 for Rust & TUI enthusiasts.
This is a patch release that fixes the unicode truncation bug, adds performance and quality of life improvements.
✨ Release highlights: https://ratatui.rs/highlights/v0263/
97ee102 (buffer) Track_caller for index_of by @EdJoPaTo in #1046
**
The caller put in the wrong x/y -> the caller is the cause.
bf09234 (table) Make TableState::new const by @EdJoPaTo in #1040
eb281df (uncategorized) Use inner Display implementation by @EdJoPaTo in #1097
ec763af (uncategorized) Make Stylize's .bg(color) generic by @kdheepak in #1099
This PR makes `.bg(color)` generic accepting anything that can be
converted into `Color`; similar to the `.fg(color)` method on the same
trait
4d1784f (uncategorized) Re-export ParseColorError as style::ParseColorError by @joshka in #1086
366cbae (buffer) Fix Debug panic and fix formatting of overridden parts by @EdJoPaTo in #1098
Fix panic in `Debug for Buffer` when `width == 0`.
Also corrects the output when symbols are overridden.
4392759 (examples) Changed user_input example to work with multi-byte unicode chars by @OkieOth in #1069
This is the proposed solution for issue #1068. It solves the bug in the
user_input example with multi-byte UTF-8 characters as input.
Fixes:#1068
20fc0dd (examples) Fix key handling in constraints by @psobolik in #1066
Add check for `KeyEventKind::Press` to constraints example's event
handler to eliminate double keys
on Windows.
Fixes:#1062
f4637d4 (reflow) Allow wrapping at zero width whitespace by @kxxt in #1074
699c2d7 (uncategorized) Unicode truncation bug by @joshka in #1089
- Rewrote the line / span rendering code to take into account how
multi-byte / wide emoji characters are truncated when rendering into
areas that cannot accommodate them in the available space
- Added comprehensive coverage over the edge cases
- Adds a benchmark to ensure perf
b30411d (uncategorized) Termwiz underline color test by @joshka in #1094
Fixes code that doesn't compile in the termwiz tests when
underline-color feature is enabled.
5f1e119 (uncategorized) Correct feature flag typo for termwiz by @joshka in #1088
underline-color was incorrectly spelt as underline_color
0a16496 (uncategorized) Use to_string to serialize Color by @SleepySwords in #934
Since deserialize now uses `FromStr` to deserialize color, serializing
`Color` RGB values, as well as index values, would produce an output
that would no longer be able to be deserialized without causing an
error.
Color::Rgb will now be serialized as the hex representation of their
value.
For example, with serde_json, Color::Rgb(255, 0, 255) would be
serialized as "#FF00FF" rather than {"Rgb": [255, 0, 255]}.
Color::Indexed will now be serialized as just the string of the index.
For example, with serde_json, Color::Indexed(10) would be serialized
as "10" rather than {"Indexed": 10}.
Other color variants remain the same.
2cfe82a (buffer) Deprecate assert_buffer_eq! in favor of assert_eq! by @EdJoPaTo in #1007
- Simplify `assert_buffer_eq!` logic.
- Deprecate `assert_buffer_eq!`.
- Introduce `TestBackend::assert_buffer_lines`.
Also simplify many tests involving buffer comparisons.
For the deprecation, just use `assert_eq` instead of `assert_buffer_eq`:
```diff
-assert_buffer_eq!(actual, expected);
+assert_eq!(actual, expected);
```
---
I noticed `assert_buffer_eq!` creating no test coverage reports and
looked into this macro. First I simplified it. Then I noticed a bunch of
`assert_eq!(buffer, …)` and other indirect usages of this macro (like
`TestBackend::assert_buffer`).
The good thing here is that it's mainly used in tests so not many
changes to the library code.
baedc39 (buffer) Simplify set_stringn logic by @EdJoPaTo in #1083
9bd89c2 (clippy) Enable breaking lint checks by @EdJoPaTo in #988
We need to make sure to not change existing methods without a notice.
But at the same time this also finds public additions with mistakes
before they are even released which is what I would like to have.
This renames a method and deprecated the old name hinting to a new name.
Should this be mentioned somewhere, so it's added to the release notes?
It's not breaking because the old method is still there.
bef5bcf (example) Remove pointless new method by @EdJoPaTo in #1038
Use `App::default()` directly.
da1ade7 (github) Update code owners about past maintainers by @orhun in #1073
As per suggestion in
https://github.com/ratatui/ratatui/pull/1067#issuecomment-2079766990
It's good for historical purposes!
3687f78 (github) Update code owners by @orhun in #1067
Removes the team members that are not able to review PRs recently (with
their approval ofc)
839cca2 (table) Fix typo in docs for highlight_symbol by @kdheepak in #1108
f945a0b (test) Fix typo in TestBackend documentation by @orhun in #1107
828d17a (uncategorized) Add minimal example by @joshka in #1114
e95230b (uncategorized) Add note about scrollbar state content length by @Utagai in #1077
366c2a0 (block) Use Block::bordered by @EdJoPaTo in #1041
Block::bordered() is shorter than
Block::new().borders(Borders::ALL), requires one less import
(Borders) and in case Block::default() was used before can even be
const.
2e71c18 (buffer) Simplify Buffer::filled with macro by @EdJoPaTo in #1036
The `vec![]` macro is highly optimized by the Rust team and shorter.
Don't do it manually.
This change is mainly cleaner code. The only production code that uses
this is `Terminal::with_options` and `Terminal::insert_before` so it's
not performance relevant on every render.
81b9633 (calendar) Use const fn by @EdJoPaTo in #1039
Also, do the comparison without `as u8`. Stays the same at runtime and
is cleaner code.
c442dfd (canvas) Change map data to const instead of static by @EdJoPaTo in #1037
1706b0a (crossterm) Speed up combined fg and bg color changes by up to 20% by @joshka in #1072
1a4bb1c (layout) Avoid allocating memory when using split ergonomic utils by @tranzystorekk in #1105
Don't create intermediate vec in `Layout::areas` and
`Layout::spacers` when there's no need for one.
aa4260f (uncategorized) Use std::fmt instead of importing Debug and Display by @joshka in #1087
This is a small universal style change to avoid making this change a
part of other PRs.
[rationale](https://github.com/ratatui/ratatui/pull/1083#discussion_r1588466060)
5fbb77a (readme) Use terminal theme for badges by @TadoTheMiner in #1026
The badges in the readme were all the default theme. Giving them
prettier colors that match the terminal gif is better. I've used the
colors from the VHS repo.
bef2bc1 (cargo) Add homepage to Cargo.toml by @joshka in #1080
76e5fe5 (uncategorized) Revert "Make Stylize's .bg(color) generic" by @kdheepak in #1102
This reverts commit ec763af8512df731799c8f30c38c37252068a4c4 from #1099
64eb391 (uncategorized) Fixup cargo lint for windows targets by @joshka in #1071
Crossterm brings in multiple versions of the same dep
326a461 (uncategorized) Add package categories field by @mcskware in #1035
Add the package categories field in Cargo.toml, with value
`["command-line-interface"]`. This fixes the (currently non-default)
clippy cargo group lint
[`clippy::cargo_common_metadata`](https://rust-lang.github.io/rust-clippy/master/index.html#/cargo_common_metadata).
As per discussion in [Cargo package categories
suggestions](https://github.com/ratatui/ratatui/discussions/1034),
this lint is not suggested to be run by default in CI, but rather as an
occasional one-off as part of the larger
[`clippy::cargo`](https://doc.rust-lang.org/stable/clippy/lints.html#cargo)
lint group.
4955380 (uncategorized) Remove pre-push hooks by @joshka in #1115
28e81c0 (uncategorized) Add underline-color to all features flag in makefile by @joshka in #1100
c75aa19 (uncategorized) Add clippy::cargo lint by @joshka in #1053
Followup to https://github.com/ratatui/ratatui/pull/1035 and
https://github.com/ratatui/ratatui/discussions/1034
It's reasonable to enable this and deal with breakage by fixing any
specific issues that arise.
@Utagai made their first contribution in #1077@kxxt made their first contribution in #1074@OkieOth made their first contribution in #1069@psobolik made their first contribution in #1066@SleepySwords made their first contribution in #934@mcskware made their first contribution in #1035Full Changelog: https://github.com/ratatui/ratatui/compare/v0.26.2...v0.26.3
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Therefore, this is not containing anything that can be a breaking change.
This is a patch release that fixes bugs and adds enhancements, including new iterator constructors, List scroll padding, and various rendering improvements. ✨
✨ Release highlights: https://ratatui.rs/highlights/v0262/
11b452d
(layout) Mark various functions as const by @EdJoPaTo in #951
1cff511
(line) Impl Styled for Line by @joshka in #968
This adds `FromIterator` impls for `Line` and `Text` that allow creating
`Line` and `Text` instances from iterators of `Span` and `Line`
instances, respectively.
```rust
let line = Line::from_iter(vec!["Hello".blue(), " world!".green()]);
let line: Line = iter::once("Hello".blue())
.chain(iter::once(" world!".green()))
.collect();
let text = Text::from_iter(vec!["The first line", "The second line"]);
let text: Text = iter::once("The first line")
.chain(iter::once("The second line"))
.collect();
```
654949b
(list) Add Scroll Padding to Lists by @CameronBarnes in #958
Introduces scroll padding, which allows the api user to request that a certain number of ListItems be kept visible above and below the currently selected item while scrolling.
```rust
let list = List::new(items).scroll_padding(1);
```
26af650
(text) Add push methods for text and line by @joshka in #998
Adds the following methods to the `Text` and `Line` structs:
- Text::push_line
- Text::push_span
- Line::push_span
This allows for adding lines and spans to a text object without having
to call methods on the fields directly, which is useful for incremental
construction of text objects.
b5bdde0
(text) Add FromIterator impls for Line and Text by @joshka in #967
This adds `FromIterator` impls for `Line` and `Text` that allow creating
`Line` and `Text` instances from iterators of `Span` and `Line`
instances, respectively.
```rust
let line = Line::from_iter(vec!["Hello".blue(), " world!".green()]);
let line: Line = iter::once("Hello".blue())
.chain(iter::once(" world!".green()))
.collect();
let text = Text::from_iter(vec!["The first line", "The second line"]);
let text: Text = iter::once("The first line")
.chain(iter::once("The second line"))
.collect();
```
12f67e8
(uncategorized) Impl Widget for &str and String by @kdheepak in #952
Currently, `f.render_widget("hello world".bold(), area)` works but
`f.render_widget("hello world", area)` doesn't. This PR changes that my
implementing `Widget` for `&str` and `String`. This makes it easier to
render strings with no styles as widgets.
Example usage:
```rust
terminal.draw(|f| f.render_widget("Hello World!", f.size()))?;
```
---------
0207160
(line) Line truncation respects alignment by @TadoTheMiner in #987
When rendering a `Line`, the line will be truncated:
- on the right for left aligned lines
- on the left for right aligned lines
- on bot sides for centered lines
E.g. "Hello World" will be rendered as "Hello", "World", "lo wo" for
left, right, centered lines respectively.
c56f49b
(list) Saturating_sub to fix highlight_symbol overflow by @mrjackwills in #949
An overflow (pedantically an underflow) can occur if the
highlight_symbol is a multi-byte char, and area is reduced to a size
less than that char length.
943c043
(scrollbar) Dont render on 0 length track by @EdJoPaTo in #964
Fixes a panic when `track_length - 1` is used. (clamp panics on `-1.0`
being smaller than `0.0`)
742a5ea
(text) Fix panic when rendering out of bounds by @joshka in #997
Previously it was possible to cause a panic when rendering to an area
outside of the buffer bounds. Instead this now correctly renders nothing
to the buffer.
f6c4e44
(uncategorized) Ensure that paragraph correctly renders styled text by @joshka in #992
Paragraph was ignoring the new `Text::style` field added in 0.26.0
35e971f
(uncategorized) Scrollbar thumb not visible on long lists by @ThomasMiz in #959
When displaying somewhat-long lists, the `Scrollbar` widget sometimes did not display a thumb character, and only the track will be visible.
6fd5f63
(lint) Prefer idiomatic for loops by @EdJoPaTo
37b957c
(lints) Add lints to scrollbar by @EdJoPaTo
c12bcfe
(non-src) Apply pedantic lints by @EdJoPaTo in #976
Fixes many not yet enabled lints (mostly pedantic) on everything that is
not the lib (examples, benches, tests). Therefore, this is not containing
anything that can be a breaking change.
Lints are not enabled as that should be the job of #974. I created this
as a separate PR as it's mostly independent and would only clutter up the
diff of #974 even more.
Also see
https://github.com/ratatui/ratatui/pull/974#discussion_r1506458743
---------
8719608
(span) Rename to_aligned_line into into_aligned_line by @EdJoPaTo in #993
With the Rust method naming conventions these methods are into methods
consuming the Span. Therefore, it's more consistent to use `into_`
instead of `to_`.
```rust
Span::to_centered_line
Span::to_left_aligned_line
Span::to_right_aligned_line
```
Are marked deprecated and replaced with the following
```rust
Span::into_centered_line
Span::into_left_aligned_line
Span::into_right_aligned_line
```
b831c56
(widget-ref) Clippy::needless_pass_by_value by @EdJoPaTo
359204c
(uncategorized) Simplify to io::Result by @EdJoPaTo in #1016
Simplifies the code, logic stays exactly the same.
8e68db9
(uncategorized) Remove pointless default on internal structs by @EdJoPaTo in #980
See #978
Also remove other derives. They are unused and just slow down compilation.
3be189e
(uncategorized) Clippy::thread_local_initializer_can_be_made_const by @EdJoPaTo
enabled by default on nightly
5c4efac
(uncategorized) Clippy::map_err_ignore by @EdJoPaTo
bbb6d65
(uncategorized) Clippy::else_if_without_else by @EdJoPaTo
fdb14dc
(uncategorized) Clippy::redundant_type_annotations by @EdJoPaTo
9b3b23a
(uncategorized) Remove literal suffix by @EdJoPaTo
it's not needed and can just be assumed
related:clippy::(un)separated_literal_suffix
58b6e0b
(uncategorized) Clippy::should_panic_without_expect by @EdJoPaTo
c870a41
(uncategorized) Clippy::many_single_char_names by @EdJoPaTo
a6036ad
(uncategorized) Clippy::similar_names by @EdJoPaTo
060d26b
(uncategorized) Clippy::match_same_arms by @EdJoPaTo
fcbea9e
(uncategorized) Clippy::uninlined_format_args by @EdJoPaTo
14b24e7
(uncategorized) Clippy::if_not_else by @EdJoPaTo
5ed1f43
(uncategorized) Clippy::redundant_closure_for_method_calls by @EdJoPaTo
c8c7924
(uncategorized) Clippy::too_many_lines by @EdJoPaTo
e3afe7c
(uncategorized) Clippy::unreadable_literal by @EdJoPaTo
a1f54de
(uncategorized) Clippy::bool_to_int_with_if by @EdJoPaTo
b8ea190
(uncategorized) Clippy::cast_lossless by @EdJoPaTo
0de5238
(uncategorized) Dead_code by @EdJoPaTo
enabled by default, only detected by nightly yet
df5dddf
(uncategorized) Unused_imports by @EdJoPaTo
enabled by default, only detected on nightly yet
f1398ae
(uncategorized) Clippy::useless_vec by @EdJoPaTo
Lint enabled by default but only nightly finds this yet
525848f
(uncategorized) Manually apply clippy::use_self for impl with lifetimes by @EdJoPaTo
660c718
(uncategorized) Clippy::empty_line_after_doc_comments by @EdJoPaTo
ab951fa
(uncategorized) Clippy::return_self_not_must_use by @EdJoPaTo
3cd4369
(uncategorized) Clippy::doc_markdown by @EdJoPaTo
9bc014d
(uncategorized) Clippy::items_after_statements by @EdJoPaTo
36a0cd5
(uncategorized) Clippy::deref_by_slicing by @EdJoPaTo
f7f6692
(uncategorized) Clippy::equatable_if_let by @EdJoPaTo
01418eb
(uncategorized) Clippy::default_trait_access by @EdJoPaTo
8536760
(uncategorized) Clippy::inefficient_to_string by @EdJoPaTo
a558b19
(uncategorized) Clippy::implicit_clone by @EdJoPaTo
5b00e3a
(uncategorized) Clippy::use_self by @EdJoPaTo
27680c0
(uncategorized) Clippy::semicolon_if_nothing_returned by @EdJoPaTo
14461c3
(breaking-changes) Typos and markdownlint by @EdJoPaTo in #1009
3b002fd
(uncategorized) Update incompatible code warning in examples readme by @joshka in #1013
e02f476
(borders) Allow border!() in const by @EdJoPaTo in #977
This allows more compiler optimizations when the macro is used.
541f0f9
(cell) Use const CompactString::new_inline by @EdJoPaTo in #979
Some minor find when messing around trying to `const` all the things.
While `reset()` and `default()` can not be `const` it's still a benefit
when their contents are.
65e7923
(scrollbar) Const creation by @EdJoPaTo in #963
A bunch of `const fn` allow for more performance and `Default` now uses the `const` new implementations.
8195f52
(uncategorized) Clippy::needless_pass_by_value by @EdJoPaTo
183c07e
(uncategorized) Clippy::trivially_copy_pass_by_ref by @EdJoPaTo
a13867f
(uncategorized) Clippy::cloned_instead_of_copied by @EdJoPaTo
3834374
(uncategorized) Clippy::missing_const_for_fn by @EdJoPaTo
125ee92
(docs) Fix: fix typos in crate documentation by @orhun in #1002
38c17e0
(editorconfig) Set and apply some defaults by @EdJoPaTo
07da90a
(funding) Add eth address for receiving funds from drips.network by @BenJam in #994
078e97e
(github) Add EdJoPaTo as a maintainer by @orhun in #986
b0314c5
(uncategorized) Remove conventional commit check for PR by @Valentin271 in #950
This removes conventional commit check for PRs.
Since we use the PR title and description this is useless. It fails a
lot of time and we ignore it.
IMPORTANT NOTE: This does **not** mean Ratatui abandons conventional
commits. This only relates to commits in PRs.
6e6ba27
(lint) Warn on pedantic and allow the rest by @EdJoPaTo
c4ce7e8
(uncategorized) Enable more satisfied lints by @EdJoPaTo
These lints dont generate warnings and therefore dont need refactoring.
I think they are useful in the future.
a4e84a6
(uncategorized) Increase msrv to 1.74.0 by @EdJoPaTo [breaking]
configure lints in Cargo.toml requires 1.74.0
BREAKING CHANGE:rust 1.74 is required now
@TadoTheMiner made their first contribution in #987@BenJam made their first contribution in #994@CameronBarnes made their first contribution in #958@ThomasMiz made their first contribution in #959Full Changelog: https://github.com/ratatui/ratatui/compare/v0.26.1...0.26.2
Nothing published for this version
Nothing published for this version
Nothing published for this version
This is a patch release that fixes bugs and adds enhancements, including new iterators, title options for blocks, and various rendering improvements.
This is a patch release that fixes bugs and adds enhancements, including new iterators, title options for blocks, and various rendering improvements. ✨
74a0511 (rect) Add Rect::positions iterator (#928)
Useful for performing some action on all the cells in a particular area.
E.g.,
```rust
fn render(area: Rect, buf: &mut Buffer) {
for position in area.positions() {
buf.get_mut(position.x, position.y).set_symbol("x");
}
}
```
9182f47 (uncategorized) Add Block::title_top and Block::title_top_bottom (#940)
This adds the ability to add titles to the top and bottom of a block
without having to use the `Title` struct (which will be removed in a
future release - likely v0.28.0).
Fixes a subtle bug if the title was created from a right aligned Line
and was also right aligned. The title would be rendered one cell too far
to the right.
```rust
Block::bordered()
.title_top(Line::raw("A").left_aligned())
.title_top(Line::raw("B").centered())
.title_top(Line::raw("C").right_aligned())
.title_bottom(Line::raw("D").left_aligned())
.title_bottom(Line::raw("E").centered())
.title_bottom(Line::raw("F").right_aligned())
.render(buffer.area, &mut buffer);
// renders
"┌A─────B─────C┐",
"│ │",
"└D─────E─────F┘",
```
Addresses part of https://github.com/ratatui/ratatui/issues/738
2202059 (block) Fix crash on empty right aligned title (#933)
- Simplified implementation of the rendering for block.
- Introduces a subtle rendering change where centered titles that are
odd in length will now be rendered one character to the left compared
to before. This aligns with other places that we render centered text
and is a more consistent behavior. See
https://github.com/ratatui/ratatui/pull/807#discussion_r1455645954
for another example of this.
14c67fb (list) Highlight symbol when using a multi-bytes char (#924)
ratatui v0.26.0 brought a regression in the List widget, in which the
highlight symbol width was incorrectly calculated - specifically when
the highlight symbol was a multi-char character, e.g. `▶`.
0dcdbea (paragraph) Render Line::styled correctly inside a paragraph (#930)
Renders the styled graphemes of the line instead of the contained spans.
fae5862 (uncategorized) Ensure that buffer::set_line sets the line style (#926)
Fixes a regression in 0.26 where buffer::set_line was no longer setting
the style. This was due to the new style field on Line instead of being
stored only in the spans.
Also adds a configuration for just running unit tests to bacon.toml.
fbb5dfa (uncategorized) Scrollbar rendering when no track symbols are provided (#911)
61a8278 (canvas) Add documentation to canvas module (#913)
Document the whole `canvas` module. With this, the whole `widgets`
module is documented.
18870ce (uncategorized) Fix the method name for setting the Line style (#947)
8fb4630 (uncategorized) Remove github action bot that makes comments nudging commit signing (#937)
We can consider reverting this commit once this PR is merged:
https://github.com/1Password/check-signed-commits-action/pull/9
Thank you so much to everyone that contributed to this release!
Here is the list of contributors who have contributed to ratatui for the first time!
@mo8it@m4rch3n1ngNothing published for this version
Nothing published for this version
⚠️ List of breaking changes can be found here.
We are excited to announce the new version of ratatui - a Rust library that's all about cooking up TUIs 🐭
In this version, we have primarily focused on simplifications and quality-of-life improvements for providing a more intuitive and user-friendly experience while building TUIs.
✨ Release highlights: https://ratatui.rs/highlights/v026/
⚠️ List of breaking changes can be found here.
💖 Consider sponsoring us at https://github.com/sponsors/ratatui!
79ceb9f (line) Add alignment convenience functions (#856)
This adds convenience functions `left_aligned()`, `centered()` and
`right_aligned()` plus unit tests. Updated example code.
0df9354 (padding) Add new constructors for padding (#828)
Adds `proportional`, `symmetric`, `left`, `right`, `top`, and `bottom`
constructors for Padding struct.
Proportional is
```
/// **NOTE**: Terminal cells are often taller than they are wide, so to make horizontal and vertical
/// padding seem equal, doubling the horizontal padding is usually pretty good.
```
d726e92 (paragraph) Add alignment convenience functions (#866)
Added convenience functions left_aligned(), centered() and
right_aligned() plus unit tests. Updated example code.
c1ed5c3 (span) Add alignment functions (#873)
Implemented functions that convert Span into a
left-/center-/right-aligned Line. Implemented unit tests.
Closes #853
b80264d (text) Add alignment convenience functions (#862)
Adds convenience functions `left_aligned()`, `centered()` and
`right_aligned()` plus unit tests.
23f6938
(block) Add Block::bordered (#736)
This avoid creating a block with no borders and then settings Borders::ALL. i.e.
```diff
- Block::default().borders(Borders::ALL);
+ Block::bordered();
```
ffd5fc7 (color) Add Color::from_u32 constructor (#785)
Convert a u32 in the format 0x00RRGGBB to a Color.
```rust
let white = Color::from_u32(0x00FFFFFF);
let black = Color::from_u32(0x00000000);
```
4f2db82 (color) Use the FromStr implementation for deserialization (#705)
The deserialize implementation for Color used to support only the enum
names (e.g. Color, LightRed, etc.) With this change, you can use any of
the strings supported by the FromStr implementation (e.g. black,
light-red, #00ff00, etc.)
1cbe1f5
(constraints) Rename Constraint::Proportional to Constraint::Fill (#880)
Constraint::Fill is a more intuitive name for the behavior, and it is
shorter.
Resolves #859
dfd6db9 (demo2) Add destroy mode to celebrate commit 1000! (#809)
```shell
cargo run --example demo2 --features="crossterm widget-calendar"
```
Press `d` to activate destroy mode and Enjoy!

Vendors a copy of tui-big-text to allow us to use it in the demo.
540fd2d
(layout) Change Flex::default() (#881) [breaking]
This PR makes a number of simplifications to the layout and constraint
features that were added after v0.25.0.
For users upgrading from v0.25.0, the net effect of this PR (along with
the other PRs) is the following:
- New `Flex` modes have been added.
- `Flex::Start` (new default)
- `Flex::Center`
- `Flex::End`
- `Flex::SpaceAround`
- `Flex::SpaceBetween`
- `Flex::Legacy` (old default)
- `Min(v)` grows to allocate excess space in all `Flex` modes instead of
shrinking (except in `Flex::Legacy` where it retains old behavior).
- `Fill(1)` grows to allocate excess space, growing equally with
`Min(v)`.
---
The following contains a summary of the changes in this PR and the
motivation behind them.
**`Flex`**
- Removes `Flex::Stretch`
- Renames `Flex::StretchLast` to `Flex::Legacy`
**`Constraint`**
- Removes `Fixed`
- Makes `Min(v)` grow as much as possible everywhere (except
`Flex::Legacy` where it retains the old behavior)
- Makes `Min(v)` grow equally as `Fill(1)` while respecting `Min` lower
bounds. When `Fill` and `Min` are used together, they both fill excess
space equally.
Allowing `Min(v)` to grow still allows users to build the same layouts
as before with `Flex::Start` with no breaking changes to the behavior.
This PR also removes the unstable feature `SegmentSize`.
This is a breaking change to the behavior of constraints. If users want
old behavior, they can use `Flex::Legacy`.
```rust
Layout::vertical([Length(25), Length(25)]).flex(Flex::Legacy)
```
Users that have constraint that exceed the available space will probably
not see any difference or see an improvement in their layouts. Any
layout with `Min` will be identical in `Flex::Start` and `Flex::Legacy`
so any layout with `Min` will not be breaking.
Previously, `Table` used `EvenDistribution` internally by default, but
with that gone the default is now `Flex::Start`. This changes the
behavior of `Table` (for the better in most cases). The only way for
users to get exactly the same as the old behavior is to change their
constraints. I imagine most users will be happier out of the box with
the new Table default.
Resolves https://github.com/ratatui/ratatui/issues/843
Thanks to `@joshka` for the direction
bbcfa55 (layout) Add Rect::contains method (#882)
This is useful for performing hit tests (i.e. did the user click in an
area).
1e75596 (layout) Increase default cache size to 500 (#850)
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()`.
2819eea (layout) Add Position struct (#790)
This stores the x and y coordinates (columns and rows)
- add conversions from Rect
- add conversion with Size to Rect
- add Rect::as_position
1561d64 (layout) Add Rect -> Size conversion methods (#789)
- add Size::new() constructor
- add Rect::as_size()
- impl From<Rect> for Size
- document and add tests for Size
f13fd73
(layout) Add Rect::clamp() method (#749)
* feat(layout): add a Rect::clamp() method
This ensures a rectangle does not end up outside an area. This is useful
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.
```rust
let window_area = Rect::new(state.x, state.y, 20, 20).clamp(area);
state.x = rect.x;
state.y = rect.y;
```
* refactor: use rstest to simplify clamp test
* fix: use rstest description instead of string
test layout::rect::tests::clamp::case_01_inside ... ok
test layout::rect::tests::clamp::case_02_up_left ... ok
test layout::rect::tests::clamp::case_04_up_right ... ok
test layout::rect::tests::clamp::case_05_left ... ok
test layout::rect::tests::clamp::case_03_up ... ok
test layout::rect::tests::clamp::case_06_right ... ok
test layout::rect::tests::clamp::case_07_down_left ... ok
test layout::rect::tests::clamp::case_08_down ... ok
test layout::rect::tests::clamp::case_09_down_right ... ok
test layout::rect::tests::clamp::case_10_too_wide ... ok
test layout::rect::tests::clamp::case_11_too_tall ... ok
test layout::rect::tests::clamp::case_12_too_large ... ok
* fix: less ambiguous docs for this / other rect
* fix: move rstest to dev deps
98bcf1c (layout) Add Rect::split method (#729)
This method splits a Rect and returns a fixed-size array of the
resulting Rects. This allows the caller to use array destructuring
to get the individual Rects.
```rust
use Constraint::*;
let layout = &Layout::vertical([Length(1), Min(0)]);
let [top, main] = area.split(&layout);
```
0494ee5 (layout) Accept Into<Constraint> for constructors (#744)
This allows Layout constructors to 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.
```rust
Layout::new(Direction::Vertical, [1, 2, 3]);
Layout::horizontal([1, 2, 3]);
Layout::vertical([1, 2, 3]);
Layout::default().constraints([1, 2, 3]);
```
7ab12ed (layout) Add horizontal and vertical constructors (#728)
* feat(layout): add vertical and horizontal constructors
This commit adds two new constructors to the `Layout` struct, which
allow the user to create a vertical or horizontal layout with default
values.
```rust
let layout = Layout::vertical([
Constraint::Length(10),
Constraint::Min(5),
Constraint::Length(10),
]);
let layout = Layout::horizontal([
Constraint::Length(10),
Constraint::Min(5),
Constraint::Length(10),
]);
```
4278b40 (line) Implement iterators for Line (#896)
This allows iterating over the `Span`s of a line using `for` loops and
other iterator methods.
- add `iter` and `iter_mut` methods to `Line`
- implement `IntoIterator` for `Line`, `&Line`, and `&mut Line` traits
- update call sites to iterate over `Line` rather than `Line::spans`
5d410c6 (line) Implement Widget for Line (#715)
This allows us to use Line as a child of other widgets, and to use
Line::render() to render it rather than calling buffer.set_line().
```rust
frame.render_widget(Line::raw("Hello, world!"), area);
// or
Line::raw("Hello, world!").render(frame, area);
```
c977293 (line) Add style field, setters and docs (#708) [breaking]
- The `Line` struct now stores the style of the line rather than each
`Span` storing it.
- Adds two new setters for style and spans
- Adds missing docs
BREAKING CHANGE:Line::style is now a field of Line instead of being
stored in each Span.
bbf2f90 (rect.rs) Implement Rows and Columns iterators in Rect (#765)
This enables iterating over rows and columns of a Rect. In tern being able to use that with other iterators and simplify looping over cells.
fe06f0c (serde) Support TableState, ListState, and ScrollbarState (#723)
TableState, ListState, and ScrollbarState can now be serialized and deserialized
using serde.
```rust
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
struct AppState {
list_state: ListState,
table_state: TableState,
scrollbar_state: ScrollbarState,
}
let app_state = AppState::default();
let serialized = serde_json::to_string(app_state);
let app_state = serde_json::from_str(serialized);
```
37c1836 (span) Implement Widget on Span (#709)
This allows us to use Span as a child of other widgets, and to use
Span::render() to render it rather than calling buffer.set_span().
```rust
frame.render_widget(Span::raw("Hello, world!"), area);
// or
Span::raw("Hello, world!").render(frame, area);
// or even
"Hello, world!".green().render(frame, area);
```
e1e85aa (style) Add material design color palette (#786)
The `ratatui::style::palette::material` module contains the Google 2014
Material Design palette.
See https://m2.material.io/design/color/the-color-system.html#tools-for-picking-colors
for more information.
```rust
use ratatui::style::palette::material::BLUE_GRAY;
Line::styled("Hello", BLUE_GRAY.c500);
```
bf67850 (style) Add tailwind color palette (#787)
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://tailwindcss.com/docs/customizing-colors for more information
on Tailwind.
```rust
use ratatui::style::palette::tailwind::SLATE;
Line::styled("Hello", SLATE.c500);
```
27e9216 (table) Remove allow deprecated attribute used previously for segment_size ✨ (#875)
a489d85 (table) Deprecate SegmentSize on table (#842)
This adds for table:
- Added new flex method with flex field
- Deprecated segment_size method and removed segment_size field
- Updated documentation
- Updated tests
c69ca47
(table) Collect iterator of Row into Table (#774) [breaking]
Any iterator whose item is convertible into `Row` can now be
collected into a `Table`.
Where previously, `Table::new` accepted `IntoIterator<Item = Row>`, it
now accepts `IntoIterator<Item: Into<Row>>`.
BREAKING CHANGE:The compiler can no longer infer the element type of the container
passed to Table::new(). For example, Table::new(vec![], widths)
will no longer compile, as the type of vec![] can no longer be
inferred.
2faa879 (table) Accept Text for highlight_symbol (#781)
This allows for multi-line symbols to be used as the highlight symbol.
```rust
let table = Table::new(rows, widths)
.highlight_symbol(Text::from(vec![
"".into(),
" █ ".into(),
" █ ".into(),
"".into(),
]));
```
e64e194 (table) Implement FromIterator for widgets::Row (#755)
The `Row::new` constructor accepts a single argument that implements
`IntoIterator`. This commit adds an implementation of `FromIterator`,
as a thin wrapper around `Row::new`. This allows `.collect::<Row>()`
to be used at the end of an iterator chain, rather than wrapping the
entire iterator chain in `Row::new`.
803a72d (table) Accept Into<Constraint> for widths (#745)
This allows Table constructors to 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.
```rust
Table::new(rows, [1,2,3])
Table::default().widths([1,2,3])
```
f025d2b (table) Add Table::footer and Row::top_margin methods (#722)
* feat(table): Add a Table::footer method
f29c73f
(tabs) Accept Iterators of Line in constructors (#776) [breaking]
Any iterator whose item is convertible into `Line` can now be
collected into `Tabs`.
In addition, where previously `Tabs::new` required a `Vec`, it can now
accept any object that implements `IntoIterator` with an item type
implementing `Into<Line>`.
BREAKING CHANGE: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<_>.
b459228
(termwiz) Add From termwiz style impls (#726)
Important note: this also fixes a wrong mapping between ratatui's gray
and termwiz's grey. `ratatui::Color::Gray` now maps to
`termwiz::color::AnsiColor::Silver`
9ba7354 (text) Implement iterators for Text (#900)
This allows iterating over the `Lines`s of a text using `for` loops and
other iterator methods.
- add `iter` and `iter_mut` methods to `Text`
- implement `IntoIterator` for `Text`, `&Text`, and `&mut Text` traits
- update call sites to iterate over `Text` rather than `Text::lines`
68d5783 (text) Add style and alignment (#807)
Fixes #758, fixes #801
This PR adds:
style and alignment to TextWidget for TextText manual draw to call for Widget implAll places that use Text have been updated and support its new
features expect paragraph which still has a custom implementation.
815757f (widgets) Implement Widget for Widget refs (#833)
Many widgets can be rendered without changing their state.
This commit implements The `Widget` trait for references to
widgets and changes their implementations to be immutable.
This allows us to render widgets without consuming them by passing a ref
to the widget when calling `Frame::render_widget()`.
```rust
// this might be stored in a struct
let paragraph = Paragraph::new("Hello world!");
let [left, right] = area.split(&Layout::horizontal([20, 20]));
frame.render_widget(¶graph, left);
frame.render_widget(¶graph, right); // we can reuse the widget
```
Implemented for all widgets except BarChart (which has an implementation
that modifies the internal state and requires a rewrite to fix.
Other widgets will be implemented in follow up commits.
Fixes:https://github.com/ratatui/ratatui/discussions/164 Replaces PRs: https://github.com/ratatui/ratatui/pull/122 and
https://github.com/ratatui/ratatui/pull/16
Enables:https://github.com/ratatui/ratatui/issues/132 Validated as a viable working solution by:
eb79256
(widgets) Collect iterator of ListItem into List (#775)
Any iterator whose item is convertible into `ListItem` can now be
collected into a `List`.
```rust
let list: List = (0..3).map(|i| format!("Item{i}")).collect();
```
c8dd879 (uncategorized) Add WidgetRef and StatefulWidgetRef traits (#903)
The Widget trait consumes self, which makes it impossible to use in a
boxed context. Previously we implemented the Widget trait for &T, but
this was not enough to render a boxed widget. We now have a new trait
called `WidgetRef` that allows rendering a widget by reference. This
trait is useful when you want to store a reference to one or more
widgets and render them later. Additionally this makes it possible to
render boxed widgets where the type is not known at compile time (e.g.
in a composite layout with multiple panes of different types).
This change also adds a new trait called `StatefulWidgetRef` which is
the stateful equivalent of `WidgetRef`.
Both new traits are gated behind the `unstable-widget-ref` feature flag
as we may change the exact name / approach a little on this based on
further discussion.
Blanket implementation of `Widget` for `&W` where `W` implements
`WidgetRef` and `StatefulWidget` for `&W` where `W` implements
`StatefulWidgetRef` is provided. This allows you to render a widget by
reference and a stateful widget by reference.
A blanket implementation of `WidgetRef` for `Option<W>` where `W`
implements `WidgetRef` is provided. This makes it easier to render
child widgets that are optional without the boilerplate of unwrapping
the option. Previously several widgets implemented this manually. This
commits expands the pattern to apply to all widgets.
```rust
struct Parent {
child: Option<Child>,
}
impl WidgetRef for Parent {
fn render_ref(&self, area: Rect, buf: &mut Buffer) {
self.child.render_ref(area, buf);
}
}
```
```rust
let widgets: Vec<Box<dyn WidgetRef>> = vec![Box::new(Greeting), Box::new(Farewell)];
for widget in widgets {
widget.render_ref(buf.area, &mut buf);
}
assert_eq!(buf, Buffer::with_lines(["Hello Goodbye"]));
```
87bf1dd (uncategorized) Replace Rect::split with Layout::areas and spacers (#904)
In a recent commit we added Rec::split, but this feels more ergonomic as
Layout::areas. This also adds Layout::spacers to get the spacers between
the areas.
dab08b9 (uncategorized) Show space constrained UIs conditionally (#895)
With this PR the constraint explorer demo only shows space constrained
UIs instead:
Smallest (15 row height):
<img width="759" alt="image"
src="https://github.com/ratatui/ratatui/assets/1813121/37a4a027-6c6d-4feb-8104-d732aee298ac">
Small (20 row height):
<img width="759" alt="image"
src="https://github.com/ratatui/ratatui/assets/1813121/f76e025f-0061-4f09-9c91-2f7b00fcfb9e">
Medium (30 row height):
<img width="758" alt="image"
src="https://github.com/ratatui/ratatui/assets/1813121/81b070da-1bfb-40c5-9fbc-c1ab44ce422e">
Full (40 row height):
<img width="760" alt="image"
src="https://github.com/ratatui/ratatui/assets/1813121/7bb8a8c4-1a77-4bbc-a346-c8b5c198c6d3">
2a12f7b (uncategorized) Impl Widget for &BarChart (#897)
BarChart had some internal mutations that needed to be removed to
implement the Widget trait for &BarChart to bring it in line with the
other widgets.
9ec43ef (uncategorized) Constraint Explorer example (#893)
Here's a constraint explorer demo put together with `@joshka`
https://github.com/ratatui/ratatui/assets/1813121/08d7d8f6-d013-44b4-8331-f4eee3589cce
It allows users to interactive explore how the constraints behave with respect to each other and compare that across flex modes. It allows users to swap constraints out for other constraints, increment or decrement the values, add and remove constraints, and add spacing
It is also a good example for how to structure a simple TUI with several Ratatui code patterns that are useful for refactoring.
Fixes:https://github.com/ratatui/ratatui/issues/792
4ee4e6d
(uncategorized) Make spacing work in Flex::SpaceAround and Flex::SpaceBetween (#892)
This PR implements user provided spacing gaps for `SpaceAround` and
`SpaceBetween`.
https://github.com/ratatui/ratatui/assets/1813121/2e260708-e8a7-48ef-aec7-9cf84b655e91
Now user provided spacing gaps always take priority in all Flex modes.
dd5ca3a (uncategorized) Better weights for constraints (#889)
This PR is a split of reworking the weights from #888
This keeps the same ranking of weights, just uses a different numerical
value so that the lowest weight is `WEAK` (`1.0`).
No tests are changed as a result of this change, and running the
following multiple times did not cause any errors for me:
```rust
for i in {0..100}
do
cargo test --lib --
if [ $? -ne 0 ]; then
echo "Test failed. Exiting loop."
break
fi
done
```
aeec163 (uncategorized) Change rounding to make tests stable (#888)
This fixes some unstable tests
be4fdaa
(uncategorized) Change priority of constraints and add split_with_spacers ✨ (#788)
Follow up to https://github.com/ratatui/ratatui/pull/783
This PR introduces different priorities for each kind of constraint.
This PR also adds tests that specifies this behavior. This PR resolves a
number of broken tests.
Fixes https://github.com/ratatui/ratatui/issues/827
With this PR, the layout algorithm will do the following in order:
1. Ensure that all the segments are within the user provided area and
ensure that all segments and spacers are aligned next to each other
2. if a user provides a `layout.spacing`, it will enforce it.
3. ensure proportional elements are all proportional to each other
4. if a user provides a `Fixed(v)` constraint, it will enforce it.
5. `Min` / `Max` binding inequality constraints
6. `Length`
7. `Percentage`
8. `Ratio`
9. collapse `Min` or collapse `Max`
10. grow `Proportional` as much as possible
11. grow spacers as much as possible
This PR also returns the spacer areas as `Rects` to the user. Users can
then draw into the spacers as they see fit (thanks `@joshka` for the
idea). Here's a screenshot with the modified flex example:
<img width="569" alt="image"
src="https://github.com/ratatui/ratatui/assets/1813121/46c8901d-882c-43b0-ba87-b1d455099d8f">
This PR introduces a `strengths` module that has "default" weights that
give stable solutions as well as predictable behavior.
d713201
(uncategorized) Add Color::from_hsl ✨ (#772)
This PR adds `Color::from_hsl` that returns a valid `Color::Rgb`.
```rust
let color: Color = Color::from_hsl(360.0, 100.0, 100.0);
assert_eq!(color, Color::Rgb(255, 255, 255));
let color: Color = Color::from_hsl(0.0, 0.0, 0.0);
assert_eq!(color, Color::Rgb(0, 0, 0));
```
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).
Related #763
405a125 (uncategorized) Add wide and tall proportional border set (#848)
Adds `PROPORTIONAL_WIDE` and `PROPORTIONAL_TALL` border sets.
symbols::border::PROPORTIONAL_WIDE
▄▄▄▄
█xx█
█xx█
▀▀▀▀
symbols::border::PROPORTIONAL_TALL
█▀▀█
█xx█
█xx█
█▄▄█
Fixes:https://github.com/ratatui/ratatui/issues/834
9df6ceb (uncategorized) Table column calculation uses layout spacing ✨ (#824)
This uses the new `spacing` feature of the `Layout` struct to allocate
columns spacing in the `Table` widget.
This changes the behavior of the table column layout in the following
ways:
1. Selection width is always allocated.
- if a user does not want a selection width ever they should use
`HighlightSpacing::Never`
2. Column spacing is prioritized over other constraints
- if a user does not want column spacing, they should use
`Table::new(...).column_spacing(0)`
---------
f299463 (uncategorized) Add one eighth wide and tall border sets ✨ (#831)
This PR adds the
[`McGugan`](https://www.willmcgugan.com/blog/tech/post/ceo-just-wants-to-draw-boxes/)
border set, which allows for tighter borders.
For example, with the `flex` example you can get this effect (top is
mcgugan wide, bottom is mcgugan tall):
<img width="759" alt="image"
src="https://github.com/ratatui/ratatui/assets/1813121/756bb50e-f8c3-4eec-abe8-ce358058a526">
<img width="759" alt="image"
src="https://github.com/ratatui/ratatui/assets/1813121/583485ef-9eb2-4b45-ab88-90bd7cb14c54">
As of this PR, `MCGUGAN_WIDE` has to be styled manually, like so:
```rust
let main_color = color_for_constraint(*constraint);
let cell = buf.get_mut(block.x, block.y + 1);
cell.set_style(Style::reset().fg(main_color).reversed());
let cell = buf.get_mut(block.x, block.y + 2);
cell.set_style(Style::reset().fg(main_color).reversed());
let cell = buf.get_mut(block.x + block.width.saturating_sub(1), block.y + 1);
cell.set_style(Style::reset().fg(main_color).reversed());
let cell = buf.get_mut(block.x + block.width.saturating_sub(1), block.y + 2);
cell.set_style(Style::reset().fg(main_color).reversed());
```
`MCGUGAN_TALL` has to be styled manually, like so:
```rust
let main_color = color_for_constraint(*constraint);
for x in block.x + 1..(block.x + block.width).saturating_sub(1) {
let cell = buf.get_mut(x, block.y);
cell.set_style(Style::reset().fg(main_color).reversed());
let cell = buf.get_mut(x, block.y + block.height - 1);
cell.set_style(Style::reset().fg(main_color).reversed());
}
```
ae6a2b0 (uncategorized) Add spacing feature to flex example ✨ (#830)
This adds the `spacing` using `+` and `-` to the flex example
cddf4b2 (uncategorized) Implement Display for Text, Line, Span (#826)
This PR adds:
std::fmt::Display for Text, Line, and Span structs.
Display implementation displays actual content while ignoring style.
5131c81 (uncategorized) Add layout spacing ✨ (#821)
This adds a `spacing` feature for layouts.
Spacing can be added between items of a layout.
de97a1f (uncategorized) Add flex to layout ✨
This PR adds a new way to space elements in a `Layout`.
Loosely based on
[flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/), this
PR adds a `Flex` enum with the following variants:
- Start
- Center
- End
- SpaceAround
- SpaceBetween
<img width="380" alt="image" src="https://github.com/ratatui/ratatui/assets/1813121/b744518c-eae7-4e35-bbc4-fe3c95193cde">
It also adds two more variants, to make this backward compatible and to
make it replace `SegmentSize`:
- StretchLast (default in the `Flex` enum, also behavior matches old
default `SegmentSize::LastTakesRemainder`)
- Stretch (behavior matches `SegmentSize::EvenDistribution`)
The `Start` variant from above matches `SegmentSize::None`.
This allows `Flex` to be a complete replacement for `SegmentSize`, hence
this PR also deprecates the `segment_size` constructor on `Layout`.
`SegmentSize` is still used in `Table` but under the hood `segment_size`
maps to `Flex` with all tests passing unchanged.
I also put together a simple example for `Flex` layouts so that I could
test it visually, shared below:
https://github.com/ratatui/ratatui/assets/1813121/c8716c59-493f-4631-add5-feecf4bd4e06
9a3815b (uncategorized) Add Constraint::Fixed and Constraint::Proportional ✨ (#783)
425a651 (uncategorized) Add comprehensive tests for Length interacting with other constraints ✨ (#802)
8f56fab (uncategorized) Accept Color and Modifier for all Styles (#720) [breaking]
* feat: accept Color and Modifier for all Styles
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.:
```rust
Line::styled("hello", Style::new().red());
Line::styled("world", Style::new().bold());
// can now be simplified to
Line::styled("hello", Color::Red);
Line::styled("world", Modifier::BOLD);
Fixes https://github.com/ratatui/ratatui/issues/694
BREAKING CHANGE:All style related methods now accept `S: Into<Style>`
instead of `Style`. This means that if you are already passing an
ambiguous type that implements `Into<Style>` you will need to remove
the `.into()` call.
`Block` style methods can no longer be called from a const context as
trait functions cannot (yet) be const.
* feat: add tuple conversions to Style
Adds conversions for various Color and Modifier combinations
* chore: add unit tests
### Bug Fixes
- [ee54493](https://github.com/ratatui/ratatui/commit/ee544931633ada25d84daa95e4e3a0b17801cb8b)
*(buffer)* Don't panic in set_style ([#714](https://github.com/ratatui/ratatui/issues/714))
````text
This fixes a panic in set_style when the area to be styled is
outside the buffer's bounds.
c959bd2 (calendar) CalendarEventStore panic (#822)
CalendarEventStore::today() panics if the system's UTC offset cannot
be determined. In this circumstance, it's better to use now_utc
instead.
a67815e (chart) Exclude unnamed datasets from legend (#753)
A dataset with no name won't display an empty line anymore in the legend.
If no dataset have name, then no legend is ever displayed.
3e7810a (example) Increase layout cache size (#815)
This was causing very bad performances especially on scrolling.
It's also a good usage demonstration.
50b81c9 (examples/scrollbar) Title wasn't displayed because of background reset (#795)
b3a57f3 (list) Modify List and List example to support saving offsets. (#667)
The current `List` example will unselect and reset the position of a
list.
This PR will save the last selected item, and updates `List` to honor
its offset, preventing the list from resetting when the user
`unselect()`s a `StatefulList`.
6645d2e (table) Ensure that default and new() match (#751) [breaking]
In https://github.com/ratatui/ratatui/pull/660 we introduced the
segment_size field to the Table struct. However, we forgot to update
the default() implementation to match the new() implementation. This
meant that the default() implementation picked up SegmentSize::default()
instead of SegmentSize::None.
Additionally the introduction of Table::default() in an earlier PR,
https://github.com/ratatui/ratatui/pull/339, was also missing the
default for the column_spacing field (1).
This commit fixes the default() implementation to match the new()
implementation of these two fields by implementing the Default trait
manually.
BREAKING CHANGE: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.
b0ed658 (table) Render missing widths as equal (#710)
Previously, if `.widths` was not called before rendering a `Table`, no
content would render in the area of the table. This commit changes that
behaviour to default to equal widths for each column.
Fixes #510.
f71bf18 (uncategorized) Bug with flex stretch with spacing and proportional constraints (#829)
This PR fixes a bug with layouts when using spacing on proportional
constraints.
cc6737b (uncategorized) Make SpaceBetween with one element Stretch 🐛 (#813)
When there's just one element, `SpaceBetween` should do the same thing
as `Stretch`.
f2eab71 (uncategorized) Broken tests in table.rs (#784)
* fix: broken tests in table.rs
* fix: Use default instead of raw
8dd177a (uncategorized) Fix PR write permission to upload unsigned commit comment (#770)
cf86123 (scrollbar) Rewrite scrollbar implementation (#847)
Implementation was simplified and calculates the size of the thumb a
bit more proportionally to the content that is visible.
fd4703c (block) Move padding and title into separate files (#837)
bc274e2
(block) Remove deprecated title_on_bottom (#757) [breaking]
Block::title_on_bottom was deprecated in v0.22. Use Block::title and Title::position instead.
e0aa6c5 (chart) Replace deprecated apply (#812)
Fixes #793
7f42ec9 (colors_rgb) Impl widget on mutable refs (#865)
This commit refactors the colors_rgb example to implement the Widget
trait on mutable references to the app and its sub-widgets. This allows
the app to update its state while it is being rendered.
Additionally the main and run functions are refactored to be similar to
the other recent examples. This uses a pattern where the App struct has
a `run` method that takes a terminal as an argument, and the main
function is in control of initializing and restoring the terminal and
installing the error hooks.
813f707 (example) Improve constraints and flex examples (#817)
This PR is a follow up to
https://github.com/ratatui/ratatui/pull/811.
It improves the UI of the layouts by
- thoughtful accessible color that represent priority in constraints
resolving
- using QUADRANT_OUTSIDE symbol set for block rendering
- adding a scrollbar
- panic handling
- refactoring for readability
to name a few. Here are some example gifs of the outcome:


---------
bb5444f (example) Add scroll to flex example (#811)
This commit adds `scroll` to the flex example. It also adds more examples to showcase how constraints interact. It improves the UI to make it easier to understand and short terminal friendly.
<img width="380" alt="image" src="https://github.com/ratatui/ratatui/assets/1813121/30541efc-ecbe-4e28-b4ef-4d5f1dc63fec"/>
---------
6d15b25 (layout) Move the remaining types (#743)
- alignment -> layout/alignment.rs
- corner -> layout/corner.rs
- direction -> layout/direction.rs
- size -> layout/size.rs
659460e (layout) Move SegmentSize to layout/segment_size.rs (#742)
9574198 (line) Reorder methods for natural reading order (#713)
6364533 (table) Split table into multiple files (#718)
At close to 2000 lines of code, the table widget was getting a bit
unwieldy. This commit splits it into multiple files, one for each
struct, and one for the table itself.
Also refactors the table rendering code to be easier to maintain.
5aba988 (terminal) Extract types to files (#760)
Fields on Frame that were private are now pub(crate).
5254795 (uncategorized) Make layout tests a bit easier to understand (#890)
bd6b91c
(uncategorized) Make patch_style & reset_style chainable (#754) [breaking]
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.
da6c299 (uncategorized) Extract layout::Constraint to file (#739)
6ecaeed (text) Add overview of the relevant methods (#857)
Add an overview of the relevant methods under `Constructor Methods`, `Setter Methods`, and `Other Methods` subtitles.
4b8e54e (examples) Refactor Tabs example (#861)
- Used a few new techniques from the 0.26 features (ref widgets, text rendering,
dividers / padding etc.)
- Updated the app to a simpler application approach
- Use color_eyre
- Make it look pretty (colors, new proportional borders)

---------
Fixes https://github.com/ratatui/ratatui/issues/819
Co-authored-by: Josh McKinney <joshka@users.noreply.github.com>
5b7ad2a (examples) Update gauge example (#863)
- colored gauges
- removed box borders
- show the difference between ratio / percentage and unicode / no unicode better
- better application approach (consistent with newer examples)
- various changes for 0.26 features
- impl `Widget` for `&App`
- use color_eyre
for gauge.tape
- change to get better output from the new code
---------
Fixes: https://github.com/ratatui/ratatui/issues/846
Co-authored-by: Josh McKinney <joshka@users.noreply.github.com>
f383625 (examples) Add note about example versions to all examples (#871)
847bacf (examples) Refactor demo2 (#836)
Simplified a bunch of the logic in the demo2 example
- Moved destroy mode to its own file.
- Moved error handling to its own file.
- Removed AppContext
- Implemented Widget for &App. The app state is small enough that it
doesn't matter here and we could just copy or clone the app state on
every frame, but for larger apps this can be a significant performance
improvement.
- Made the tabs stateful
- Made the term module just a collection of functions rather than a
struct.
- Changed to use color_eyre for error handling.
- Changed keyboard shortcuts and rearranged the bottom bar.
- Use strum for the tabs enum.
804c841 (examples) Update list example and list.tape (#864)
This PR adds:
- subjectively better-looking list example
- change list example to a todo list example
- status of a TODO can be changed, further info can be seen under the list.
eb1484b (examples) Update tabs example and tabs.tape (#855)
This PR adds:
for tabs.rs
- general refactoring on code
- subjectively better looking front
- add tailwind colors
for tabs.tape
- change to get better output from the new code
Here is the new output:

330a899 (examples) Update table example and table.tape (#840)
In table.rs
- added scrollbar to the table
- colors changed to use style::palette::tailwind
- now colors can be changed with keys (l or →) for the next color, (h or
←) for the previous color
- added a footer for key info
For table.tape
- typing speed changed to 0.75s from 0.5s
- screen size changed to fit
- pushed keys changed to show the current example better
41de884 (examples) Document incompatible examples better (#844)
Examples often take advantage of unreleased API changes, which makes
them not copy-paste friendly.
3464894 (examples) Add warning about examples matching the main branch (#778)
fb93db0 (examples) Simplify docs using new layout methods (#731)
Use the new `Layout::horizontal` and `vertical` constructors and
`Rect::split_array` through all the examples.
d6b8513 (examples) Refactor chart example to showcase scatter (#703)
fe84141 (layout) Document the difference in the split methods (#750)
* docs(layout): document the difference in the split methods
* fix: doc suggestion
86168aa
(uncategorized) Fix docstring for Max constraints (#898)
11e4f6a (uncategorized) Adds better documentation for constraints and flex 📚 (#818)
1746a61 (uncategorized) Update links to templates repository 📚 (#810)
This PR updates links to the `templates` repository.
43b2b57 (uncategorized) Fix typo in Table widget description (#797)
2b4aa46 (uncategorized) GitHub admonition syntax for examples README.md (#791)
* docs: GitHub admonition syntax for examples README.md
* docs: Add link to stable release
388aa46 (uncategorized) Update crate, lib and readme links (#771)
Link to the contributing, changelog, and breaking changes docs at the
top of the page instead of just in the main part of the doc. This
makes it easier to find them.
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
⚠️ List of breaking changes can be found here.
We are thrilled to announce the new version of ratatui - a Rust library that's all about cooking up TUIs 🐭
In this version, we made improvements on widgets such as List, Table and Layout and changed some of the defaults for a better user experience.
Also, we renewed our website and updated our documentation/tutorials to get started with ratatui: https://ratatui.rs 🚀
✨ Release highlights: https://ratatui.rs/highlights/v025/
⚠️ List of breaking changes can be found here.
💖 We also enabled GitHub Sponsors for our organization, consider sponsoring us if you like ratatui: https://github.com/sponsors/ratatui
aef4956
(list) List::new now accepts IntoIterator<Item = Into<ListItem>> (#672) [breaking]
This allows to build list like
```
List::new(["Item 1", "Item 2"])
```
8bfd666
(paragraph) Add line_count and line_width unstable helper methods
This is an unstable feature that may be removed in the future
1229b96
(rect) Add offset method (#533)
The offset method creates a new Rect that is moved by the amount
specified in the x and y direction. These values can be positive or
negative. This is useful for manual layout tasks.
```rust
let rect = area.offset(Offset { x: 10, y -10 });
```
edacaf7
(buffer) Deprecate Cell::symbol field (#624)
The Cell::symbol field is now accessible via a getter method (`symbol()`). This will
allow us to make future changes to the Cell internals such as replacing `String` with
`compact_str`.
6b2efd0 (layout) Accept IntoIterator for constraints (#663)
Layout and Table now accept IntoIterator for constraints with an Item
that is AsRef<Constraint>. This allows pretty much any collection of
constraints to be passed to the layout functions including arrays,
vectors, slices, and iterators (without having to call collect() on
them).
753e246 (layout) Allow configuring layout fill (#633)
The layout split will generally fill the remaining area when `split()`
is called. This change allows the caller to configure how any extra
space is allocated to the `Rect`s. This is useful for cases where the
caller wants to have a fixed size for one of the `Rect`s, and have the
other `Rect`s fill the remaining space.
For now, the method and enum are marked as unstable because the exact
name is still being bikeshedded. To enable this functionality, add the
`unstable-segment-size` feature flag in your `Cargo.toml`.
To configure the layout to fill the remaining space evenly, use
`Layout::segment_size(SegmentSize::EvenDistribution)`. The default
behavior is `SegmentSize::LastTakesRemainder`, which gives the last
segment the remaining space. `SegmentSize::None` will disable this
behavior. See the docs for `Layout::segment_size()` and
`layout::SegmentSize` for more information.
Fixes https://github.com/ratatui/ratatui/issues/536
1e2f0be (layout) Add parameters to Layout::new() (#557) [breaking]
Adds a convenience function to create a layout with a direction and a
list of constraints which are the most common parameters that would be
generally configured using the builder pattern. The constraints can be
passed in as any iterator of constraints.
```rust
let layout = Layout::new(Direction::Horizontal, [
Constraint::Percentage(50),
Constraint::Percentage(50),
]);
```
c862aa5 (list) Support line alignment (#599)
The `List` widget now respects the alignment of `Line`s and renders them as expected.
ebf1f42
(style) Implement From trait for crossterm to Style related structs (#686)
e49385b (table) Add a Table::segment_size method (#660)
It controls how to distribute extra space to an underconstrained table.
The default, legacy behavior is to leave the extra space unused. The
new options are LastTakesRemainder which gets all space to the rightmost
column that can used it, and EvenDistribution which divides it amongst
all columns.
b8f71c0 (widgets/chart) Add option to set the position of legend (#378)
5bf4f52
(uncategorized) Implement From trait for termion to Style related structs (#692)
* feat(termion): implement from termion color
* feat(termion): implement from termion style
* feat(termion): implement from termion `Bg` and `Fg`
d19b266 (uncategorized) Add Constraint helpers (e.g. from_lengths) (#641)
Adds helper methods that convert from iterators of u16 values to the
specific Constraint type. This makes it easy to create constraints like:
```rust
// a fixed layout
let constraints = Constraint::from_lengths([10, 20, 10]);
// a centered layout
let constraints = Constraint::from_ratios([(1, 4), (1, 2), (1, 4)]);
let constraints = Constraint::from_percentages([25, 50, 25]);
// a centered layout with a minimum size
let constraints = Constraint::from_mins([0, 100, 0]);
// a sidebar / main layout with maximum sizes
let constraints = Constraint::from_maxes([30, 200]);
```
f69d57c
(rect) Fix underflow in the Rect::intersection method (#678)
56fc410
(block) Make inner aware of title positions (#657)
Previously, when computing the inner rendering area of a block, all
titles were assumed to be positioned at the top, which caused the
height of the inner area to be miscalculated.
ec7b387
(doc) Do not access deprecated Cell::symbol field in doc example (#626)
37c70db (table) Add widths parameter to new() (#664) [breaking]
This prevents creating a table that doesn't actually render anything.
1f88da7 (table) Fix new clippy lint which triggers on table widths tests (#630)
* fix(table): new clippy lint in 1.74.0 triggers on table widths tests
36d8c53 (table) Widths() now accepts AsRef<[Constraint]> (#628)
This allows passing an array, slice or Vec of constraints, which is more
ergonomic than requiring this to always be a slice.
The following calls now all succeed:
```rust
Table::new(rows).widths([Constraint::Length(5), Constraint::Length(5)]);
Table::new(rows).widths(&[Constraint::Length(5), Constraint::Length(5)]);
// widths could also be computed at runtime
let widths = vec![Constraint::Length(5), Constraint::Length(5)];
Table::new(rows).widths(widths.clone());
Table::new(rows).widths(&widths);
```
34d099c (tabs) Fixup tests broken by semantic merge conflict (#665)
Two changes without any line overlap caused the tabs tests to break
e4579f0 (tabs) Set the default highlight_style (#635) [breaking]
Previously the default highlight_style was set to `Style::default()`,
which meant that the highlight style was the same as the normal style.
This change sets the default highlight_style to reversed text.
28ac55b (tabs) Tab widget now supports custom padding (#629)
The Tab widget now contains padding_left and padding_right
properties. Those values can be set with functions `padding_left()`,
`padding_right()`, and `padding()` which all accept `Into<Line>`.
Fixes issue https://github.com/ratatui/ratatui/issues/502
df0eb1f (terminal) Insert_before() now accepts lines > terminal height and doesn't add an extra blank line (#596)
Fixes issue with inserting content with height>viewport_area.height and adds
the ability to insert content of height>terminal_height
- Adds TestBackend::append_lines() and TestBackend::clear_region() methods to
support testing the changes
aaeba27 (uncategorized) Truncate table when overflow (#685)
This prevents a panic when rendering an empty right aligned and rightmost table cell
ffa78aa (uncategorized) Add #[must_use] to Style-moving methods (#600)
f767ea7
(list) start_corner is now direction (#673)
The previous name `start_corner` did not communicate clearly the intent of the method.
A new method `direction` and a new enum `ListDirection` were added.
`start_corner` is now deprecated
0576a8a (layout) To natural reading order (#681)
Structs and enums at the top of the file helps show the interaction
between the types without having to find each type in between longer
impl sections.
Also moved the try_split function into the Layout impl as an associated
function and inlined the `layout::split()` which just called try_split.
This makes the code a bit more contained.
4be18ab (readme) Reference awesome-ratatui instead of wiki (#689)
* refactor(readme): link awesome-ratatui instead of wiki
The apps wiki moved to awesome-ratatui
* docs(readme): Update README.md
7ef0afc (widgets) Remove unnecessary dynamic dispatch and heap allocation (#597)
b282a06 (uncategorized) Remove items deprecated since 0.10 (#691) [breaking]
Remove `Axis::title_style` and `Buffer::set_background` which are deprecated since 0.10
7ced7c0 (uncategorized) Define struct WrappedLine instead of anonymous tuple (#608)
It makes the type easier to document, and more obvious for users
1b8b626 (examples) Add animation and FPS counter to colors_rgb (#583)
2169a0d (examples) Add example of half block rendering (#687)
This is a fun example of how to render big text using half blocks
91c67eb (github) Update code owners (#666)
onboard `@Valentin271` as maintainer
3ec4e24 (list) Add documentation to the List widget (#669)
Adds documentation to the List widget and all its sub components like `ListState` and `ListItem`
9f37100 (readme) Update README.md and fix the bug that demo2 cannot run (#595)
Fixes https://github.com/ratatui/ratatui/issues/594
2a87251 (security) Add security policy (#676)
* docs: Create SECURITY.md
* Update SECURITY.md
a15c3b2 (uncategorized) Remove deprecated table constructor from breaking changes (#698)
113b4b7 (uncategorized) Rename template links to remove ratatui from name 📚 (#690)
211160c (uncategorized) Remove simple-tui-rs (#651)
This has not been recently and doesn't lead to good code
910ad00 (rustfmt) Enable format_code_in_doc_comments (#695)
This enables more consistently formatted code in doc comments,
especially since ratatui heavily uses fluent setters.
See https://rust-lang.github.io/rustfmt/?version=v1.6.0#format_code_in_doc_comments
d118565 (table) Cleanup docs and builder methods (#638)
- Refactor the `table` module for better top to bottom readability by
putting types first and arranging them in a logical order (Table, Row,
Cell, other).
- Adds new methods for:
- `Table::rows`
- `Row::cells`
- `Cell::new`
- `Cell::content`
- `TableState::new`
- `TableState::selected_mut`
- Makes `HighlightSpacing::should_add` pub(crate) since it's an internal
detail.
- Adds tests for all the new methods and simple property tests for all
the other setter methods.
dd22e72
(uncategorized) Correct "builder methods" in docs and add must_use on widgets setters (#655)
18e19f6 (uncategorized) Fix breaking changes doc versions (#639)
Moves the layout::new change to unreleasedd section and adds the table change
a58cce2 (uncategorized) Disable default benchmarking (#598)
Disables the default benchmarking behaviour for the lib target to fix unrecognized
criterion benchmark arguments.
See https://bheisler.github.io/criterion.rs/book/faq.html#cargo-bench-gives-unrecognized-option-errors-for-valid-command-line-options for details
59b9c32 (codecov) Adjust threshold and noise settings (#615)
Fixes https://github.com/ratatui/ratatui/issues/612
03401cd (uncategorized) Fix untrusted input in pr check workflow (#680)
Thank you so much to everyone that contributed to this release!
Here is the list of contributors who have contributed to ratatui for the first time!
@rikonaka@danny-burrows@SOF3@jan-ferdinand@rhaskia@asomers@progval@TylerBloom@YeungKC@lyuhaNothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
In this version, we've introduced features like window size API, enhanced chart rendering, and more. The list of \*breaking changes\* can be found her…
We are excited to announce the new version of ratatui - a Rust library that's all about cooking up TUIs 🐭
In this version, we've introduced features like window size API, enhanced chart rendering, and more. The list of *breaking changes* can be found here ⚠️. Also, we created various tutorials and walkthroughs in Ratatui Book which is available at https://ratatui.rs 🚀
✨ Release highlights: https://ratatui.rs/highlights/v024
c6c3f88
(backend) Implement common traits for WindowSize (#586)
d077903 (backend) Backend provides window_size, add Size struct (#276)
For image (sixel, iTerm2, Kitty...) support that handles graphics in
terms of `Rect` so that the image area can be included in layouts.
For example: an image is loaded with a known pixel-size, and drawn, but
the image protocol has no mechanism of knowing the actual cell/character
area that been drawn on. It is then impossible to skip overdrawing the
area.
Returning the window size in pixel-width / pixel-height, together with
columns / rows, it can be possible to account the pixel size of each cell
/ character, and then known the `Rect` of a given image, and also resize
the image so that it fits exactly in a `Rect`.
Crossterm and termwiz also both return both sizes from one syscall,
while termion does two.
Add a `Size` struct for the cases where a `Rect`'s `x`/`y` is unused
(always zero).
`Size` is not "clipped" for `area < u16::max_value()` like `Rect`. This
is why there are `From` implementations between the two.
301366c (barchart) Render charts smaller than 3 lines (#532)
The bar values are not shown if the value width is equal the bar width
and the bar is height is less than one line
Add an internal structure `LabelInfo` which stores the reserved height
for the labels (0, 1 or 2) and also whether the labels will be shown.
Fixes ratatui#513
32e4619 (block) Allow custom symbols for borders (#529) [breaking]
Adds a new `Block::border_set` method that allows the user to specify
the symbols used for the border.
Added two new border types: `BorderType::QuadrantOutside` and
`BorderType::QuadrantInside`. These are used to draw borders using the
unicode quadrant characters (which look like half block "pixels").
```
▛▀▀▜
▌ ▐
▙▄▄▟
▗▄▄▖
▐ ▌
▝▀▀▘
```
Fixes: https://github.com/ratatui/ratatui/issues/528
BREAKING CHANGES:
- BorderType::to_line_set is renamed to to_border_set
- BorderType::line_symbols is renamed to border_symbols
4541336 (canvas) Implement half block marker (#550)
* feat(canvas): implement half block marker
A useful technique for the terminal is to use half blocks to draw a grid
of "pixels" on the screen. Because we can set two colors per cell, and
because terminal cells are about twice as tall as they are wide, we can
draw a grid of half blocks that looks like a grid of square pixels.
This commit adds a new `HalfBlock` marker that can be used in the Canvas
widget and the associated HalfBlockGrid.
Also updated demo2 to use the new marker as it looks much nicer.
Adds docs for many of the methods and structs on canvas.
Changes the grid resolution method to return the pixel count
rather than the index of the last pixel.
This is an internal detail with no user impact.
082cbcb (frame) Remove generic Backend parameter (#530) [breaking]
This change simplifies UI code that uses the Frame type. E.g.:
```rust
fn draw<B: Backend>(frame: &mut Frame<B>) {
// ...
}
```
Frame was generic over Backend because it stored a reference to the
terminal in the field. Instead it now directly stores the viewport area
and current buffer. These are provided at creation time and are valid
for the duration of the frame.
BREAKING CHANGE: Frame is no longer generic over Backend. Code that
accepted a Frame<Backend> will now need to accept a Frame.
d67fa2c
(line) Add Line::raw constructor (#511)
* feat(line): add `Line::raw` constructor
There is already `Span::raw` and `Text::raw` methods
and this commit simply adds `Line::raw` method for symmetry.
Multi-line content is converted to multiple spans with the new line removed
cbf86da (rect) Add is_empty() to simplify some common checks (#534)
- add `Rect::is_empty()` that checks whether either height or width == 0
- refactored `Rect` into layout/rect.rs from layout.rs. No public API change as
the module is private and the type is re-exported under the `layout` module.
15641c8
(uncategorized) Add buffer_mut method on Frame ✨ (#548)
638d596 (layout) Use LruCache for layout cache (#487)
The layout cache now uses a LruCache with default size set to 16 entries.
Previously the cache was backed by a HashMap, and was able to grow
without bounds as a new entry was added for every new combination of
layout parameters.
- Added a new method (`layout::init_cache(usize)`) that allows the cache
size to be changed if necessary. This will only have an effect if it is called
prior to any calls to `layout::split()` as the cache is wrapped in a `OnceLock`
8d507c4 (backend) Add feature flag for underline-color (#570)
Windows 7 doesn't support the underline color attribute, so we need to
make it optional. This commit adds a feature flag for the underline
color attribute - it is enabled by default, but can be disabled by
passing `--no-default-features` to cargo.
We could specially check for Windows 7 and disable the feature flag
automatically, but I think it's better for this check to be done by the
crossterm crate, since it's the one that actually knows about the
underlying terminal.
To disable the feature flag in an application that supports Windows 7,
add the following to your Cargo.toml:
```toml
ratatui = { version = "0.24.0", default-features = false, features = ["crossterm"] }
```
Fixes https://github.com/ratatui/ratatui/issues/555
c3155a2 (barchart) Add horizontal labels(#518)
Labels were missed in the initial implementation of the horizontal
mode for the BarChart widget. This adds them.
Fixes https://github.com/ratatui/ratatui/issues/499
c9b8e7c (barchart) Render value labels with unicode correctly (#515)
An earlier change introduced a bug where the width of value labels with
unicode characters was incorrectly using the string length in bytes
instead of the unicode character count. This reverts the earlier change.
c8ab2d5 (chart) Use graph style for top line (#462)
A bug in the rendering caused the top line of the chart to be rendered
using the style of the chart, instead of the dataset style. This is
fixed by only setting the style for the width of the text, and not the
entire row.
0c7d547 (docs) Don't fail rustdoc due to termion (#503)
Windows cannot compile termion, so it is not included in the docs.
Rustdoc will fail if it cannot find a link, so the docs fail to build
on windows.
This replaces the link to TermionBackend with one that does not fail
during checks.
Fixes https://github.com/ratatui/ratatui/issues/498
0c52ff4 (gauge) Fix gauge widget colors (#572)
The background colors of the gauge had a workaround for the issue we had
with VHS / TTYD rendering the background color of the gauge. This
workaround is no longer necessary in the updated versions of VHS / TTYD.
Fixes https://github.com/ratatui/ratatui/issues/501
11076d0 (rect) Fix arithmetic overflow edge cases (#543)
Fixes https://github.com/ratatui/ratatui/issues/258
21303f2 (rect) Prevent overflow in inner() and area() (#523)
ebd3680 (stylize) Add Stylize impl for String (#466) [breaking]
Although the `Stylize` trait is already implemented for `&str` which
extends to `String`, it is not implemented for `String` itself. This
commit adds an impl of Stylize that returns a Span<'static> for `String`
so that code can call Stylize methods on temporary `String`s.
E.g. the following now compiles instead of failing with a compile error
about referencing a temporary value:
let s = format!("hello {name}!", "world").red();
BREAKING CHANGE: This may break some code that expects to call Stylize
methods on `String` values and then use the String value later. This
will now fail to compile because the String is consumed by set_style
instead of a slice being created and consumed.
This can be fixed by cloning the `String`. E.g.:
let s = String::from("hello world");
let line = Line::from(vec![s.red(), s.green()]); // fails to compile
let line = Line::from(vec![s.clone().red(), s.green()]); // works
Fixes https://discord.com/channels/1070692720437383208/1072907135664529508/1148229700821450833
2fd85af (barchart) Simplify internal implementation (#544)
Replace `remove_invisible_groups_and_bars` with `group_ticks`
`group_ticks` calculates the visible bar length in ticks. (A cell contains 8 ticks).
It is used for 2 purposes:
1. to get the bar length in ticks for rendering
2. since it delivers only the values of the visible bars, If we zip these values
with the groups and bars, then we will filter out the invisible groups and bars
27c5637 (readme) Fix links to CONTRIBUTING.md and BREAKING-CHANGES.md (#577)
e098731
(barchart) Add documentation to BarChart (#449)
Add documentation to the `BarChart` widgets and its sub-modules.
3cf0b83 (color) Document true color support (#477)
* refactor(style): move Color to separate color mod
* docs(color): document true color support
e5caf17 (custom_widget) Make button sticky when clicking with mouse (#561)
ad2dc56 (examples) Update examples readme (#576)
remove VHS bug info, tweak colors_rgb image, update some of the instructions. add demo2
b61f65b (examples) Update theme to Aardvark Blue (#574)
This is a nicer theme that makes the colors pop
61af0d9 (examples) Make custom widget example into a button (#539)
The widget also now supports mouse
5c785b2 (examples) Move example gifs to github (#460)
- A new orphan branch named "images" is created to store the example
images
ca9bcd3 (examples) Add descriptions and update theme (#460)
- Use the OceanicMaterial consistently in examples
1e20475 (stylize) Improve docs for style shorthands (#491)
The Stylize trait was introduced in 0.22 to make styling less verbose.
This adds a bunch of documentation comments to the style module and
types to make this easier to discover.
dd9a8df
(table) Add documentation for block and header methods of the Table widget (#505)
42f8169 (terminal) Add docs for terminal module (#486)
- moves the impl Terminal block up to be closer to the type definition
51fdcbe (title) Add documentation to title (#443)
This adds documentation for Title and Position
d4976d4 (widgets) Update the list of available widgets (#496)
6c7bef8 (uncategorized) Replace colons with dashes in README.md for consistency (#566)
88ae348
(uncategorized) Update Frame docstring to remove reference to generic backend (#564)
089f8ba (uncategorized) Add double quotes to instructions for features (#560)
346e7b4 (uncategorized) Add summary to breaking changes (#549)
401a7a7
(uncategorized) Improve clarity in documentation for Frame and Terminal 📚 (#545)
9cfb133 (uncategorized) Document alpha release process (#542)
Fixes https://github.com/ratatui/ratatui/issues/412
4548a9b (uncategorized) Add BREAKING-CHANGES.md (#538)
Document the breaking changes in each version. This document is
manually curated by summarizing the breaking changes in the changelog.
c0991cc (uncategorized) Make library and README consistent (#526)
* docs: make library and README consistent
Generate the bulk of the README from the library documentation, so that
they are consistent using cargo-rdme.
- Removed the Contributors section, as it is redundant with the github
contributors list.
- Removed the info about the other backends and replaced it with a
pointer to the documentation.
- add docsrs example, vhs tape and images that will end up in the README
1414fbc (uncategorized) Import prelude::* in doc examples (#490)
This commit adds `prelude::*` all doc examples and widget::* to those
that need it. This is done to highlight the use of the prelude and
simplify the examples.
- Examples in Type and module level comments show all imports and use
`prelude::*` and `widget::*` where possible.
- Function level comments hide imports unless there are imports other
than `prelude::*` and `widget::*`.
74c5244 (uncategorized) Add logo and favicon to docs.rs page (#473)
927a5d8 (uncategorized) Fix documentation lint warnings (#450)
94af2a2 (buffer) Allow with_lines to accept Vec<Into<Line>> (#494)
This allows writing unit tests without having to call set_style on the
expected buffer.
1278131 (changelog) Make the scopes lowercase in the changelog (#479)
82b40be (ci) Improve checking the PR title (#464)
- Use [`action-semantic-pull-request`](https://github.com/amannn/action-semantic-pull-request)
- Allow only reading the PR contents
- Enable merge group
a20bd6a (deps) Update lru requirement from 0.11.1 to 0.12.0 (#581)
Updates the requirements on [lru](https://github.com/jeromefroe/lru-rs) to permit the latest version.
- [Changelog](https://github.com/jeromefroe/lru-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jeromefroe/lru-rs/compare/0.11.1...0.12.0)
---
updated-dependencies:
- dependency-name: lru
dependency-type: direct:production
...
5213f78 (deps) Bump actions/checkout from 3 to 4 (#580)
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)
---
updated-dependencies:
- dependency-name: actions/checkout
dependency-type: direct:production
update-type: version-update:semver-major
...
6cbdb06 (examples) Refactor some examples (#578)
* chore(examples): Simplify timeout calculation with `Duration::saturating_sub`
12f9291 (github) Create dependabot.yml (#575)
* chore: Create dependabot.yml
* Update .github/dependabot.yml
5498a88
(spans) Remove deprecated Spans type (#426)
The `Spans` type (plural, not singular) was replaced with a more ergonomic `Line` type
in Ratatui v0.21.0 and marked deprecated but left for backwards compatibility. This is now
removed.
- `Line` replaces `Spans`
- `Buffer::set_line` replaces `Buffer::set_spans`
fbf1a45 (uncategorized) Simplify constraints (#556)
Use bare arrays rather than array refs / Vecs for all constraint
examples.
a7bf4b3 (uncategorized) Use modern modules syntax (#492)
Move xxx/mod.rs to xxx.rs
af36282 (uncategorized) Only run check pr action on pull_request_target events (#485)
322e46f (uncategorized) Prevent PR merge with do not merge labels ♻️ (#484)
983ea7f (uncategorized) Fix check for if breaking change label should be added ♻️ (#483)
384e616 (uncategorized) Add a check for if breaking change label should be added ♻️ (#481)
47ae602 (uncategorized) Check that PR title matches conventional commit guidelines ♻️ (#459)
343c6cd (lint) Move formatting and doc checks first (#465)
Putting the formatting and doc checks first to ensure that more critical
errors are caught first (e.g. a conventional commit error or typo should
not prevent the formatting and doc checks from running).
c95a75c (makefile) Remove termion dependency from doc lint (#470)
Only build termion on non-windows targets
b996102 (makefile) Add format target (#468)
- add format target to Makefile.toml that actually fixes the formatting
- rename fmt target to lint-format
- rename style-check target to lint-style
- rename typos target to lint-typos
- rename check-docs target to lint-docs
- add section to CONTRIBUTING.md about formatting
572df75 (uncategorized) Put commit id first in changelog (#463)
878b6fc (uncategorized) Ignore benches from code coverage (#461)
Thank you so much to everyone that contributed to this release!
Here is the list of contributors who have contributed to ratatui for the first time!
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Here is a blog post that highlights the new features and breaking changes along with a retrospective about the project: https://blog.orhun.dev/ratatui…
We are thrilled to release the new version of ratatui 🐭, the official successor* of tui-rs.
In this version, we improved the existing widgets such as Barchart and Scrollbar. We also made improvmements in the testing/internal APIs to provide a smoother testing/development experience. Additionally, we have addressed various bugs and implemented enhancements.
Here is a blog post that highlights the new features and breaking changes along with a retrospective about the project: https://blog.orhun.dev/ratatui-0-23-0
(barchart) Add direction attribute. (horizontal bars support) (#325) (0dca6a6)
* feat(barchart): Add direction attribute
Enable rendering the bars horizontally. In some cases this allow us to
make more efficient use of the available space.
(cell) Add voluntary skipping capability for sixel (#215) (e4bcf78)
> Sixel is a bitmap graphics format supported by terminals.
> "Sixel mode" is entered by sending the sequence ESC+Pq.
> The "String Terminator" sequence ESC+\ exits the mode.
The graphics are then rendered with the top left positioned at the
cursor position.
It is actually possible to render sixels in ratatui with just
`buf.get_mut(x, y).set_symbol("^[Pq ... ^[\")`. But any buffer covering
the "image area" will overwrite the graphics. This is most likely the same
buffer, even though it consists of empty characters `' '`, except for
the top-left character that starts the sequence.
Thus, either the buffer or cells must be specialized to avoid drawing
over the graphics. This patch specializes the `Cell` with a
`set_skip(bool)` method, based on James' patch:
https://github.com/TurtleTheSeaHobo/tui-rs/tree/sixel-support
I unsuccessfully tried specializing the `Buffer`, but as far as I can tell
buffers get merged all the way "up" and thus skipping must be set on the
Cells. Otherwise some kind of "skipping area" state would be required,
which I think is too complicated.
Having access to the buffer now it is possible to skip all cells but the
first one which can then `set_symbol(sixel)`. It is up to the user to
deal with the graphics size and buffer area size. It is possible to get
the terminal's font size in pixels with a syscall.
An image widget for ratatui that uses this `skip` flag is available at
https://github.com/benjajaja/ratatu-image.
(list) Add option to always allocate the "selection" column width (#394) (4d70169)
* feat(list): add option to always allocate the "selection" column width
Before this option was available, selecting a item in a list when nothing was selected
previously made the row layout change (the same applies to unselecting) by adding the width
of the "highlight symbol" in the front of the list, this option allows to configure this
behavior.
* style: change "highlight_spacing" doc comment to use inline code-block for reference
(release) Add automated nightly releases (#359) (aad164a)
* feat(release): add automated nightly releases
* refactor(release): rename the alpha workflow
* refactor(release): simplify the release calculation
(scrollbar) Add optional track symbol (#360) (1727fa5) [breaking]
The track symbol is now optional, simplifying composition with other
widgets.
(table) Add support for line alignment in the table widget (#392) (7748720)
* feat(table): enforce line alignment in table render
* test(table): add table alignment render test
(widgets::table) Add option to always allocate the "selection" constraint (#375) (f63ac72)
* feat(table): add option to configure selection layout changes
Before this option was available, selecting a row in the table when no row was selected
previously made the tables layout change (the same applies to unselecting) by adding the width
of the "highlight symbol" in the front of the first column, this option allows to configure this
behavior.
* refactor(table): refactor "get_columns_widths" to return (x, width)
and "render" to make use of that
* refactor(table): refactor "get_columns_widths" to take in a selection_width instead of a boolean
also refactor "render" to make use of this change
* fix(table): rename "highlight_set_selection_space" to "highlight_spacing"
* style(table): apply doc-comment suggestions from code review
(uncategorized) Expand serde attributes for TestBuffer (#389)
(57ea871)
(uncategorized) Add weak constraints to make rects closer to each other in size ✨ (#395) (6153371)
Also make `Max` and `Min` constraints MEDIUM strength for higher priority over equal chunks
(barchart) Empty groups causes panic (#333) (9c95673)
This unlikely to happen, since nobody wants to add an empty group.
Even we fix the panic, things will not render correctly.
So it is better to just not add them to the BarChart.
(block) Fixed title_style not rendered (#349) (#363) (49a82e0)
(cargo) Adjust minimum paste version (#348) (8db9fb4)
ratatui is using features that are currently only available in paste 1.0.2; specifying the minimum version to be 1.0 will consequently cause a compilation error if cargo is only able to use a version less than 1.0.2.
(example) Fix typo (#337) (daf5890)
the existential feels
(layout) Don't leave gaps between chunks (#408) (56455e0)
Previously the layout used the floor of the calculated start and width
as the value to use for the split Rects. This resulted in gaps between
the split rects.
This change modifies the layout to round to the nearest column instead
of taking the floor of the start and width. This results in the start
and end of each rect being rounded the same way and being strictly
adjacent without gaps.
Because there is a required constraint that ensures that the last end is
equal to the area end, there is no longer the need to fixup the last
item width when the fill (as e.g. width = x.99 now rounds to x+1 not x).
The colors example has been updated to use Ratio(1, 8) instead of
Percentage(13), as this now renders without gaps for all possible sizes,
whereas previously it would have left odd gaps between columns.
(layout) Ensure left <= right (#410) (f4ed3b7)
The recent refactor missed the positive width constraint
(release) Fix the last tag retrieval for alpha releases (#416) (b6b2da5)
(release) Set the correct permissions for creating alpha releases (#400) (778c320)
(scrollbar) Move symbols to symbols module (#330) (7539f77) [breaking]
The symbols and sets are moved from `widgets::scrollbar` to
`symbols::scrollbar`. This makes it consistent with the other symbol
sets and allows us to make the scrollbar module private rather than
re-exporting it.
(table) Fix unit tests broken due to rounding (#419) (dc55211)
The merge of the table unit tests after the rounding layout fix was not
rebased correctly, this addresses the broken tests, makes them more
concise while adding comments to help clarify that the rounding behavior
is working as expected.
(uncategorized) Correct minor typos in documentation (#331) (13fb11a)
(barchart) Reduce some calculations (#430) (fc727df)
Calculating the label_offset is unnecessary, if we just render the
group label after rendering the bars. We can just reuse bar_y.
(layout) Simplify and doc split() (#405) (de25de0)
* test(layout): add tests for split()
* refactor(layout): simplify and doc split()
This is mainly a reduction in density of the code with a goal of
improving mainatainability so that the algorithm is clear.
(layout) Simplify split() function (#396) (5195099)
Removes some unnecessary code and makes the function more readable.
Instead of creating a temporary result and mutating it, we just create
the result directly from the list of changes.
(examples) Fix the instructions for generating demo GIF (#442) (7a70602)
(examples) Show layout constraints (#393) (10dbd6f)
Shows the way that layout constraints interact visually

(examples) Add color and modifiers examples (#345) (6ad4bd4)
The intent of these examples is to show the available colors and
modifiers.
- added impl Display for Color


(examples) Update block example (#351) (554805d)

(examples) Add examples readme with gifs (#303) (add578a)
This commit adds a readme to the examples directory with gifs of each
example. This should make it easier to see what each example does
without having to run it.
I modified the examples to fit better in the gifs. Mostly this was just
removing the margins, but for the block example I cleaned up the code a
bit to make it more readable and changed it so the background bug is not
triggered.
For the table example, the combination of Min, Length, and Percent
constraints was causing the table to panic when the terminal was too
small. I changed the example to use the Max constraint instead of the
Length constraint.
The layout example now shows information about how the layout is
constrained on each block (which is now a paragraph with a block).
(layout::Constraint) Add doc-comments for all variants (#371) (c8ddc16)
(lib) Extract feature documentation from Cargo.toml (#438) (8b36683)
* docs(lib): extract feature documentation from Cargo.toml
* chore(deps): make `document-features` optional dependency
* docs(lib): document the serde feature from features section
(project) Make the project description cooler (#441) (47fe4ad)
* docs(project): make the project description cooler
* docs(lib): simplify description
(readme) Fix widget docs links (#346) (2920e04)
Add scrollbar, clear. Fix Block link. Sort
(uncategorized) Improve scrollbar doc comment (#329) (c3f87f2)
(bench) Used iter_batched to clone widgets in setup function (#383)
(149d489)
Replaced `Bencher::iter` by `Bencher::iter_batched` to clone the widget in the setup function instead of in the benchmark timing.
(paragraph) Add documentation for "scroll"'s "offset" (#355) (ab5e616)
* style(paragraph): add documentation for "scroll"'s "offset"
* style(paragraph): add more text to the scroll doc-comment
(block) Add benchmarks (#368) (e18393d)
Added benchmarks to the block widget to uncover eventual performance issues
(canvas) Add unit tests for line (#437) (ad3413e)
Also add constructor to simplify creating lines
(list) Added benchmarks (#377) (664fb4c)
Added benchmarks for the list widget (render and render half scrolled)
(sparkline) Added benchmark (#384) (3293c6b)
Added benchmark for the `sparkline` widget testing a basic render with different amount of data
(styled_grapheme) Test StyledGrapheme methods (#433) (292a11d)
(table) Add test for consistent table-column-width (#404) (4cd843e)
(test_backend) Add tests for TestBackend coverage (#434) (b35f19e)
These are mostly to catch any future bugs introduced in the test backend
(changelog) Show full commit message (#423) (a937500)
This allows someone reading the changelog to search for information
about breaking changes or implementation of new functionality.
- refactored the commit template part to a macro instead of repeating it
- added a link to the commit and to the release
- updated the current changelog for the alpha and unreleased changes
- Automatically changed the existing * lists to - lists
(codecov) Fix yaml syntax (#407) (ea48af1)
a yaml file cannot contain tabs outside of strings
(docs) Add doc comment bump to release documentation (#382) (8b28672)
(github) Rename tui-rs-revival references to ratatui-org (#340)
(964190a)
(make) Add task descriptions to Makefile.toml (#398) (268bbed)
(toolchain) Bump msrv to 1.67 (#361) (8cd3205) [breaking]
* chore(toolchain)!: bump msrv to 1.67
(traits) Add Display and FromStr traits (#425) (98155dc)
Use strum for most of these, with a couple of manual implementations,
and related tests
(uncategorized) Use vhs to create demo.gif (#390) (8c55158)
The bug that prevented braille rendering is fixed, so switch to VHS for
rendering the demo gif

(uncategorized) Implement Hash common traits (#381)
(8c4a2e0)
Reorder the derive fields to be more consistent:
Debug, Default, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash
Hash trait won't be impl in this PR due to rust std design.
If we need hash trait for f64 related structs in the future,
we should consider wrap f64 into a new type.
(uncategorized) Implement Eq & PartialEq common traits (#357)
(181706c)
Reorder the derive fields to be more consistent:
Debug, Default, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash
(uncategorized) Implement Clone & Copy common traits (#350)
(440f62f)
Implement `Clone & Copy` common traits for most structs in src.
Only implement `Copy` for structs that are simple and trivial to copy.
Reorder the derive fields to be more consistent:
Debug, Default, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash
(uncategorized) Implement Debug & Default common traits (#339)
(bf49446)
Implement `Debug & Default` common traits for most structs in src.
Reorder the derive fields to be more consistent:
Debug, Default, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash
(examples) Fix cargo make run-examples (#327) (e2cb11c)
Enables the all-widgets feature so that the calendar example runs correctly
(uncategorized) Forbid unsafe code (#332) (0fb1ed8)
This indicates good (high level) code and is used by tools like cargo-geiger.
(coverage) Exclude examples directory from coverage (#373) (de9f52f)
(uncategorized) Don't fail fast (#364) (9191ad6)
Run all the tests rather than canceling when one test fails. This allows
us to see all the failures, rather than just the first one if there are
multiple. Specifically this is useful when we have an issue in one
toolchain or backend.
Thank you so much to everyone that contributed to this release!
Here is the list of contributors who have contributed to ratatui for the first time!
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
_(barchart)_ Set custom text value in the bar
tui-term a pseudoterminal library (#268)Thank you so much to everyone that contributed to this release!
Here is the list of contributors who have contributed to ratatui for the first time!
_(backend)_ Add termwiz backend and example
FromStr implementation for Color (#180)Masked to display secure data (#168) [breaking]vec![] in user_input example (#26)Spans with Line (#178)assert_buffer_eq! and Debug implementation (#161)Thank you so much to everyone that contributed to this release!
Here is the list of contributors who have contributed to ratatui for the first time!
_(uncategorized)_ Fixup remaining tui references
Thank you so much to everyone that contributed to this release!
_(ci)_ Fix deprecation warnings on CI
This marks the first release of ratatui, a community-maintained fork of tui.
The purpose of this release is to include bug fixes and small changes into the repository thus no new features are added. We have transferred all the pull requests from the original repository and worked on the low hanging ones to incorporate them in this "maintenance" release.
Here is a list of changes:
offset() to TableState (#10)width() to ListItem (#17)Paragraphtypos for checking typos (#91)committed for checking conventional commits (#77)rust-version to 1.59 in Cargo.toml (#57)tuiThank you so much to everyone that contributed to this release!
@orhun@mindoodoo@sayanarijit@Owletti@UncleScientist@rhysd@ckaznable@imuxin@mrjackwills@conradludgate@kianmeng@chaosprintAnd most importantly, special thanks to Florian Dehau for creating this awesome library 💖 We look forward to building on the strong foundations that the original crate laid out.
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →