# Changelog
All notable changes to this project will be documented in this file.
## [0.26.0](https://github.com/ratatui-org/ratatui/releases/tag/0.26.0) - 2024-02-02
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**:
⚠️ List of breaking changes can be found [here](https://github.com/ratatui-org/ratatui/blob/main/BREAKING-CHANGES.md).
💖 Consider sponsoring us at !
### Features
- [79ceb9f](https://github.com/ratatui-org/ratatui/commit/79ceb9f7b6ce7d7079fd7a1e1de8b160086206d0)
_(line)_ Add alignment convenience functions ([#856](https://github.com/ratatui-org/ratatui/issues/856))
```text
This adds convenience functions `left_aligned()`, `centered()` and
`right_aligned()` plus unit tests. Updated example code.
```
- [0df9354](https://github.com/ratatui-org/ratatui/commit/0df935473f59d9bcf16ea5092878e59ee129d876)
_(padding)_ Add new constructors for padding ([#828](https://github.com/ratatui-org/ratatui/issues/828))
````text
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.
```
````
Fixes:https://github.com/ratatui-org/ratatui/issues/798
- [d726e92](https://github.com/ratatui-org/ratatui/commit/d726e928d2004d2a99caeeb00b95ce27dbc04bc0)
_(paragraph)_ Add alignment convenience functions ([#866](https://github.com/ratatui-org/ratatui/issues/866))
```text
Added convenience functions left_aligned(), centered() and
right_aligned() plus unit tests. Updated example code.
```
- [c1ed5c3](https://github.com/ratatui-org/ratatui/commit/c1ed5c3637dc4574612ac2029249ba700e9192b5)
_(span)_ Add alignment functions ([#873](https://github.com/ratatui-org/ratatui/issues/873))
```text
Implemented functions that convert Span into a
left-/center-/right-aligned Line. Implemented unit tests.
```
Closes #853
- [b80264d](https://github.com/ratatui-org/ratatui/commit/b80264de877e7ca240cea15716379622d822bc08)
_(text)_ Add alignment convenience functions ([#862](https://github.com/ratatui-org/ratatui/issues/862))
```text
Adds convenience functions `left_aligned()`, `centered()` and
`right_aligned()` plus unit tests.
```
- [23f6938](https://github.com/ratatui-org/ratatui/commit/23f6938498a7c31916a091d5b79c9d95a0575344)
_(block)_ Add `Block::bordered` ([#736](https://github.com/ratatui-org/ratatui/issues/736))
````text
This avoid creating a block with no borders and then settings Borders::ALL. i.e.
```diff
- Block::default().borders(Borders::ALL);
+ Block::bordered();
```
````
- [ffd5fc7](https://github.com/ratatui-org/ratatui/commit/ffd5fc79fcaf8bfff1a49c55f8d4b503a9e6dfed)
_(color)_ Add Color::from_u32 constructor ([#785](https://github.com/ratatui-org/ratatui/issues/785))
````text
Convert a u32 in the format 0x00RRGGBB to a Color.
```rust
let white = Color::from_u32(0x00FFFFFF);
let black = Color::from_u32(0x00000000);
```
````
- [4f2db82](https://github.com/ratatui-org/ratatui/commit/4f2db82a774a3faea7db9659f30684e9635c24b2)
_(color)_ Use the FromStr implementation for deserialization ([#705](https://github.com/ratatui-org/ratatui/issues/705))
```text
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](https://github.com/ratatui-org/ratatui/commit/1cbe1f52abb7ab1cd5bd05030e7857ee1762f44a)
_(constraints)_ Rename `Constraint::Proportional` to `Constraint::Fill` ([#880](https://github.com/ratatui-org/ratatui/issues/880))
`Constraint::Fill` is a more intuitive name for the behavior, and it is
shorter.
Resolves #859
- [dfd6db9](https://github.com/ratatui-org/ratatui/commit/dfd6db988faa7a45cbe99b01024c086c4fcf7577)
_(demo2)_ Add destroy mode to celebrate commit 1000! ([#809](https://github.com/ratatui-org/ratatui/issues/809))
````text
```shell
cargo run --example demo2 --features="crossterm widget-calendar"
```
Press `d` to activate destroy mode and Enjoy!
![Destroy
Demo2](https://github.com/ratatui-org/ratatui/blob/1d39444e3dea6f309cf9035be2417ac711c1abc9/examples/demo2-destroy.gif?raw=true)
Vendors a copy of tui-big-text to allow us to use it in the demo.
````
- [540fd2d](https://github.com/ratatui-org/ratatui/commit/540fd2df036648674a2f6d37f7b12326d5978bbd)
_(layout)_ Change `Flex::default()` ([#881](https://github.com/ratatui-org/ratatui/issues/881)) [**breaking**]
````text
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-org/ratatui/issues/843
Thanks to @joshka for the direction
````
- [bbcfa55](https://github.com/ratatui-org/ratatui/commit/bbcfa55a88c1916598ea0442217ac7f6a99ea96f)
_(layout)_ Add Rect::contains method ([#882](https://github.com/ratatui-org/ratatui/issues/882))
```text
This is useful for performing hit tests (i.e. did the user click in an
area).
```
- [736605e](https://github.com/ratatui-org/ratatui/commit/736605ec88aac4877b19dd66ded97b26d933407f)
_(layout)_ Add default impl for Position ([#869](https://github.com/ratatui-org/ratatui/issues/869))
- [1e75596](https://github.com/ratatui-org/ratatui/commit/1e755967c53e9a1803cc7fcc46ad0946c78f0eda)
_(layout)_ Increase default cache size to 500 ([#850](https://github.com/ratatui-org/ratatui/issues/850))
```text
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()`.
```
Fixes:https://github.com/ratatui-org/ratatui/issues/820
- [2819eea](https://github.com/ratatui-org/ratatui/commit/2819eea82bfde48562b830b4ef1c998dacae8b69)
_(layout)_ Add Position struct ([#790](https://github.com/ratatui-org/ratatui/issues/790))
```text
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](https://github.com/ratatui-org/ratatui/commit/1561d64c80e6498f90807a1607d84a1405d3e0bb)
_(layout)_ Add Rect -> Size conversion methods ([#789](https://github.com/ratatui-org/ratatui/issues/789))
```text
- add Size::new() constructor
- add Rect::as_size()
- impl From for Size
- document and add tests for Size
```
- [f13fd73](https://github.com/ratatui-org/ratatui/commit/f13fd73d9ec108af723a9cd11f4262f2b09c9d25)
_(layout)_ Add `Rect::clamp()` method ([#749](https://github.com/ratatui-org/ratatui/issues/749))
````text
* 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](https://github.com/ratatui-org/ratatui/commit/98bcf1c0a57a340229684345497b2d378979de04)
_(layout)_ Add Rect::split method ([#729](https://github.com/ratatui-org/ratatui/issues/729))
````text
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](https://github.com/ratatui-org/ratatui/commit/0494ee52f1f0070f1ccf4532f7301fd59d4a5c10)
_(layout)_ Accept Into for constructors ([#744](https://github.com/ratatui-org/ratatui/issues/744))
````text
This allows Layout constructors to accept any type that implements
Into instead of just AsRef. 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](https://github.com/ratatui-org/ratatui/commit/7ab12ed8ce8f6cdb0712d132b4dfc4cccfda08da)
_(layout)_ Add horizontal and vertical constructors ([#728](https://github.com/ratatui-org/ratatui/issues/728))
````text
* 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](https://github.com/ratatui-org/ratatui/commit/4278b4088d2ab1d94aa5d73d7a0c321a46dbd9de)
_(line)_ Implement iterators for Line ([#896](https://github.com/ratatui-org/ratatui/issues/896))
```text
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](https://github.com/ratatui-org/ratatui/commit/5d410c6895de49e77c7e0d1884be63d797724448)
_(line)_ Implement Widget for Line ([#715](https://github.com/ratatui-org/ratatui/issues/715))
````text
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](https://github.com/ratatui-org/ratatui/commit/c977293f14b019ee520379bf5eaafb44cef04a01)
_(line)_ Add style field, setters and docs ([#708](https://github.com/ratatui-org/ratatui/issues/708)) [**breaking**]
```text
- 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](https://github.com/ratatui-org/ratatui/commit/bbf2f906fbe7e593fdeb5dd7530d3479788f77a5)
_(rect.rs)_ Implement Rows and Columns iterators in Rect ([#765](https://github.com/ratatui-org/ratatui/issues/765))
```text
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](https://github.com/ratatui-org/ratatui/commit/fe06f0c7b06e50cd5d7916dab9ccb5e28f5a6511)
_(serde)_ Support TableState, ListState, and ScrollbarState ([#723](https://github.com/ratatui-org/ratatui/issues/723))
````text
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](https://github.com/ratatui-org/ratatui/commit/37c183636b573e7637af5fbab9ae5c6f2d3fec6b)
_(span)_ Implement Widget on Span ([#709](https://github.com/ratatui-org/ratatui/issues/709))
````text
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](https://github.com/ratatui-org/ratatui/commit/e1e85aa7af2a7624b12a0ad7f0aa2413b409475d)
_(style)_ Add material design color palette ([#786](https://github.com/ratatui-org/ratatui/issues/786))
````text
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](https://github.com/ratatui-org/ratatui/commit/bf678507395a528befcf5c5e3180368cb8f4b826)
_(style)_ Add tailwind color palette ([#787](https://github.com/ratatui-org/ratatui/issues/787))
````text
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](https://github.com/ratatui-org/ratatui/commit/27e9216cea7f25fcf172fe0a8f11e7cca222b055)
_(table)_ Remove allow deprecated attribute used previously for segment_size ✨ ([#875](https://github.com/ratatui-org/ratatui/issues/875))
- [a489d85](https://github.com/ratatui-org/ratatui/commit/a489d85f2dda561ea18f1431f6e44f0335549eca)
_(table)_ Deprecate SegmentSize on table ([#842](https://github.com/ratatui-org/ratatui/issues/842))
```text
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](https://github.com/ratatui-org/ratatui/commit/c69ca47922619332f76488f5d9e70541b496fe1c)
_(table)_ Collect iterator of `Row` into `Table` ([#774](https://github.com/ratatui-org/ratatui/issues/774)) [**breaking**]
```text
Any iterator whose item is convertible into `Row` can now be
collected into a `Table`.
Where previously, `Table::new` accepted `IntoIterator- `, it
now accepts `IntoIterator>`.
```
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](https://github.com/ratatui-org/ratatui/commit/2faa879658a439d233edc4ac886fb42c17ff971a)
_(table)_ Accept Text for highlight_symbol ([#781](https://github.com/ratatui-org/ratatui/issues/781))
````text
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](https://github.com/ratatui-org/ratatui/commit/e64e194b6bc5f89c68fe73d430e63c264af6ca4f)
_(table)_ Implement FromIterator for widgets::Row ([#755](https://github.com/ratatui-org/ratatui/issues/755))
```text
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::
()`
to be used at the end of an iterator chain, rather than wrapping the
entire iterator chain in `Row::new`.
```
- [803a72d](https://github.com/ratatui-org/ratatui/commit/803a72df27190e273556e089e42036bfc001f003)
_(table)_ Accept Into for widths ([#745](https://github.com/ratatui-org/ratatui/issues/745))
````text
This allows Table constructors to accept any type that implements
Into instead of just AsRef. 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](https://github.com/ratatui-org/ratatui/commit/f025d2bfa26eac11ef5c2a63943a4e177abfc800)
_(table)_ Add Table::footer and Row::top_margin methods ([#722](https://github.com/ratatui-org/ratatui/issues/722))
```text
* feat(table): Add a Table::footer method
```
- [f29c73f](https://github.com/ratatui-org/ratatui/commit/f29c73fb1cf746aea0adfaed4a8b959e0466b830)
_(tabs)_ Accept Iterators of `Line` in constructors ([#776](https://github.com/ratatui-org/ratatui/issues/776)) [**breaking**]
```text
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`.
```
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](https://github.com/ratatui-org/ratatui/commit/b459228e26b9429b8a09084d76251361f7f5bfd3)
_(termwiz)_ Add `From` termwiz style impls ([#726](https://github.com/ratatui-org/ratatui/issues/726))
```text
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](https://github.com/ratatui-org/ratatui/commit/9ba7354335a106607fe0670e1205a038ec54aa1b)
_(text)_ Implement iterators for Text ([#900](https://github.com/ratatui-org/ratatui/issues/900))
```text
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](https://github.com/ratatui-org/ratatui/commit/68d5783a6912c644b922b7030facff4b1172a434)
_(text)_ Add style and alignment ([#807](https://github.com/ratatui-org/ratatui/issues/807))
Fixes #758, fixes #801
This PR adds:
- `style` and `alignment` to `Text`
- impl `Widget` for `Text`
- replace `Text` manual draw to call for Widget impl
All places that use `Text` have been updated and support its new
features expect paragraph which still has a custom implementation.
- [815757f](https://github.com/ratatui-org/ratatui/commit/815757fcbbc147050f8ce9418a4e91fd871d011f)
_(widgets)_ Implement Widget for Widget refs ([#833](https://github.com/ratatui-org/ratatui/issues/833))
````text
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-org/ratatui/discussions/164
Replaces PRs: https://github.com/ratatui-org/ratatui/pull/122 and
https://github.com/ratatui-org/ratatui/pull/16
Enables:https://github.com/ratatui-org/ratatui/issues/132
Validated as a viable working solution by:
https://github.com/ratatui-org/ratatui/pull/836
- [eb79256](https://github.com/ratatui-org/ratatui/commit/eb79256ceea151130c6b80930b51098b9ad43f5b)
_(widgets)_ Collect iterator of `ListItem` into `List` ([#775](https://github.com/ratatui-org/ratatui/issues/775))
````text
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](https://github.com/ratatui-org/ratatui/commit/c8dd87918d44fff6d4c3c78e1fc821a3275db1ae)
_(uncategorized)_ Add WidgetRef and StatefulWidgetRef traits ([#903](https://github.com/ratatui-org/ratatui/issues/903))
````text
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` 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,
}
impl WidgetRef for Parent {
fn render_ref(&self, area: Rect, buf: &mut Buffer) {
self.child.render_ref(area, buf);
}
}
```
```rust
let widgets: Vec> = 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](https://github.com/ratatui-org/ratatui/commit/87bf1dd9dfb8bf2e6c08c488d4a38dac21e14304)
_(uncategorized)_ Replace Rect::split with Layout::areas and spacers ([#904](https://github.com/ratatui-org/ratatui/issues/904))
```text
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](https://github.com/ratatui-org/ratatui/commit/dab08b99b6a2a4c8ced6f780af7a37a0f3c34f6b)
_(uncategorized)_ Show space constrained UIs conditionally ([#895](https://github.com/ratatui-org/ratatui/issues/895))
```text
With this PR the constraint explorer demo only shows space constrained
UIs instead:
Smallest (15 row height):
Small (20 row height):
Medium (30 row height):
Full (40 row height):
```
- [2a12f7b](https://github.com/ratatui-org/ratatui/commit/2a12f7bddf0b286e63439c2d1fa894dcfbfde6c0)
_(uncategorized)_ Impl Widget for &BarChart ([#897](https://github.com/ratatui-org/ratatui/issues/897))
```text
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](https://github.com/ratatui-org/ratatui/commit/9ec43eff1c7a62631fab99e4874ccd15fe7b210a)
_(uncategorized)_ Constraint Explorer example ([#893](https://github.com/ratatui-org/ratatui/issues/893))
```text
Here's a constraint explorer demo put together with @joshka
```
https://github.com/ratatui-org/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-org/ratatui/issues/792
---
- [4ee4e6d](https://github.com/ratatui-org/ratatui/commit/4ee4e6d78a136b5a1e4942f25b9afe34f7dd5d0c)
_(uncategorized)_ Make spacing work in `Flex::SpaceAround` and `Flex::SpaceBetween` ([#892](https://github.com/ratatui-org/ratatui/issues/892))
```text
This PR implements user provided spacing gaps for `SpaceAround` and
`SpaceBetween`.
```
https://github.com/ratatui-org/ratatui/assets/1813121/2e260708-e8a7-48ef-aec7-9cf84b655e91
Now user provided spacing gaps always take priority in all `Flex` modes.
- [dd5ca3a](https://github.com/ratatui-org/ratatui/commit/dd5ca3a0c83bc1efc281133707eec04864567e69)
_(uncategorized)_ Better weights for constraints ([#889](https://github.com/ratatui-org/ratatui/issues/889))
````text
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](https://github.com/ratatui-org/ratatui/commit/aeec16369bdf26dc96af46cc580df191078464ae)
_(uncategorized)_ Change rounding to make tests stable ([#888](https://github.com/ratatui-org/ratatui/issues/888))
```text
This fixes some unstable tests
```
- [be4fdaa](https://github.com/ratatui-org/ratatui/commit/be4fdaa0c7c863daa50c0109cd5f96005365029d)
_(uncategorized)_ Change priority of constraints and add `split_with_spacers` ✨ ([#788](https://github.com/ratatui-org/ratatui/issues/788))
```text
Follow up to https://github.com/ratatui-org/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-org/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:
This PR introduces a `strengths` module that has "default" weights that
give stable solutions as well as predictable behavior.
```
- [d713201](https://github.com/ratatui-org/ratatui/commit/d7132011f921cb87593914bd7d2e24ac676ec911)
_(uncategorized)_ Add `Color::from_hsl` ✨ ([#772](https://github.com/ratatui-org/ratatui/issues/772))
````text
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](https://github.com/ratatui-org/ratatui/commit/405a125c8235b983993e3774361821b67a340aa0)
_(uncategorized)_ Add wide and tall proportional border set ([#848](https://github.com/ratatui-org/ratatui/issues/848))
```text
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-org/ratatui/issues/834
- [9df6ceb](https://github.com/ratatui-org/ratatui/commit/9df6cebb58e97ac795868fa0af96a8aaf9c794c0)
_(uncategorized)_ Table column calculation uses layout spacing ✨ ([#824](https://github.com/ratatui-org/ratatui/issues/824))
```text
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](https://github.com/ratatui-org/ratatui/commit/f299463847e8aa4b61619e5a5c02c5855d8fdb7b)
_(uncategorized)_ Add one eighth wide and tall border sets ✨ ([#831](https://github.com/ratatui-org/ratatui/issues/831))
````text
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):
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](https://github.com/ratatui-org/ratatui/commit/ae6a2b0007ee7195de14d36420e2e30853fbb2f4)
_(uncategorized)_ Add spacing feature to flex example ✨ ([#830](https://github.com/ratatui-org/ratatui/issues/830))
```text
This adds the `spacing` using `+` and `-` to the flex example
```
- [cddf4b2](https://github.com/ratatui-org/ratatui/commit/cddf4b2930f573fafad64a4ddd7fe5753f7540e2)
_(uncategorized)_ Implement Display for Text, Line, Span ([#826](https://github.com/ratatui-org/ratatui/issues/826))
Issue:https://github.com/ratatui-org/ratatui/issues/816
This PR adds:
`std::fmt::Display` for `Text`, `Line`, and `Span` structs.
Display implementation displays actual content while ignoring style.
- [5131c81](https://github.com/ratatui-org/ratatui/commit/5131c813ce5de078be0458c9a067bca2d6b38921)
_(uncategorized)_ Add layout spacing ✨ ([#821](https://github.com/ratatui-org/ratatui/issues/821))
```text
This adds a `spacing` feature for layouts.
Spacing can be added between items of a layout.
```
- [de97a1f](https://github.com/ratatui-org/ratatui/commit/de97a1f1da4fd146034f7c8f20264f4d558cc1a0)
_(uncategorized)_ Add flex to layout ✨
```text
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
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-org/ratatui/assets/1813121/c8716c59-493f-4631-add5-feecf4bd4e06
- [9a3815b](https://github.com/ratatui-org/ratatui/commit/9a3815b66d8b6e4ff9f6475666f5742701e256bb)
_(uncategorized)_ Add Constraint::Fixed and Constraint::Proportional ✨ ([#783](https://github.com/ratatui-org/ratatui/issues/783))
- [425a651](https://github.com/ratatui-org/ratatui/commit/425a65140b61695169c996784974488ad2fd16ea)
_(uncategorized)_ Add comprehensive tests for Length interacting with other constraints ✨ ([#802](https://github.com/ratatui-org/ratatui/issues/802))
- [c50ff08](https://github.com/ratatui-org/ratatui/commit/c50ff08a630ae59c9aac10f69fe3ce67c2db449c)
_(uncategorized)_ Add frame count ✨ ([#766](https://github.com/ratatui-org/ratatui/issues/766))
- [8f56fab](https://github.com/ratatui-org/ratatui/commit/8f56fabcdd34cb3938736f3302902a7fead64ee5)
_(uncategorized)_ Accept Color and Modifier for all Styles ([#720](https://github.com/ratatui-org/ratatui/issues/720)) [**breaking**]
````text
* feat: accept Color and Modifier for all Styles
All style related methods now accept `S: Into