You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
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.
```
This avoid creating a block with no borders and then settings Borders::ALL. i.e.
```diff
- Block::default().borders(Borders::ALL);
+ Block::bordered();
```
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.
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!
![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.
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
This is useful for performing hit tests (i.e. did the user click in an
area).
736605e (layout) Add default impl for Position (#869)
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()`.
* 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
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 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`
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);
```
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);
```
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`.
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`
All 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.
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-org/ratatui/assets/1813121/37a4a027-6c6d-4feb-8104-d732aee298ac">
Small (20 row height):
<img width="759" alt="image"
src="https://github.com/ratatui-org/ratatui/assets/1813121/f76e025f-0061-4f09-9c91-2f7b00fcfb9e">
Medium (30 row height):
<img width="758" alt="image"
src="https://github.com/ratatui-org/ratatui/assets/1813121/81b070da-1bfb-40c5-9fbc-c1ab44ce422e">
Full (40 row height):
<img width="760" alt="image"
src="https://github.com/ratatui-org/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
constraint-explorer-demo.mov
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.
4ee4e6d (uncategorized) Make spacing work in Flex::SpaceAround and Flex::SpaceBetween (#892)
This PR implements user provided spacing gaps for `SpaceAround` and
`SpaceBetween`.
gap-spacearound-spacebetween.mov
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-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:
<img width="569" alt="image"
src="https://github.com/ratatui-org/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.
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).
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-org/ratatui/assets/1813121/756bb50e-f8c3-4eec-abe8-ce358058a526">
<img width="759" alt="image"
src="https://github.com/ratatui-org/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 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-org/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:
flex.mov
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-org/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-org/ratatui/commit/ee544931633ada25d84daa95e4e3a0b17801cb8b)
*(buffer)* Don't panic in set_style ([#714](https://github.com/ratatui-org/ratatui/issues/714))
````text
This fixes a panic in set_style when the area to be styled is
outside the buffer's bounds.
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-org/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-org/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.
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-org/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:
![constraints](https://github.com/ratatui-org/ratatui/assets/381361/8eed34cf-e959-472f-961b-d439bfe3324e)
![flex](https://github.com/ratatui-org/ratatui/assets/381361/3195a56c-9cb6-4525-bc1c-b969c0d6a812)
---------
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-org/ratatui/assets/1813121/30541efc-ecbe-4e28-b4ef-4d5f1dc63fec"/>
---------
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.
Fields on Frame that were private are now pub(crate).
4d262d2 (widget) Move borders to widgets/borders.rs (#832)
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)
Documentation
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.
- 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)
![Made with VHS](https://vhs.charm.sh/vhs-4WW21XTtepDhUSq4ZShO56.gif)
---------
Fixes https://github.com/ratatui-org/ratatui/issues/819
Co-authored-by: Josh McKinney <[email protected]>
- 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 featuers
- impl `Widget` for `&App`
- use color_eyre
for gauge.tape
- change to get better output from the new code
---------
Fixes: https://github.com/ratatui-org/ratatui/issues/846
Co-authored-by: Josh McKinney <[email protected]>
f383625 (examples) Add note about example versions to all examples (#871)
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:
![tabs](https://github.com/ratatui-org/ratatui/assets/30180366/0a9371a5-e90d-42ba-aba5-70cbf66afd1f)
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
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 in the main part of the doc. This
makes it easier to find them.
Rearrange the links to be in a more logical order.
Use link refs for all the links
Fix up the CI link to point to the right workflow
Performance
1d3fbc1 (buffer) Apply SSO technique to text buffer in buffer::Cell (#601) [breaking]
Use CompactString instead of String to store the Cell::symbol field.
This saves reduces the size of memory allocations at runtime.
Testing
663bbde (layout) Convert layout tests to use rstest (#879)
ba20372 (contributing) Remove part about squashing commits (#874)
Removes the part about squashing commits from the CONTRIBUTING file.
We no longer require that because github squashes commits when merging.
This will cleanup the CONTRIBUTING file a bit which is already quite
dense.
d49bbb2 (ci) Update the job description for installing cargo-nextest (#839)
8d77b73 (ci) Use cargo-nextest for running tests (#717)
* chore(ci): use cargo-nextest for running tests
* refactor(make): run library tests before doc tests
b7a4793 (ci) Bump alpha release for breaking changes (#495)
Automatically detect breaking changes based on commit messages
and bump the alpha release number accordingly.
E.g. v0.23.1-alpha.1 will be bumped to v0.24.0-alpha.0 if any commit
since v0.23.0 has a breaking change.
fc0879f (layout) Comment tests that may fail on occasion (#814)
These fails seem to fail on occasion, locally and on CI.
This issue will be revisited in the PR on constraint weights:
https://github.com/ratatui-org/ratatui/pull/788
f8367fd (uncategorized) Allow Buffer::with_lines to accept IntoIterator (#901)
This can make it easier to use `Buffer::with_lines` with iterators that
don't necessarily produce a `Vec`. For example, this allows using
`Buffer::with_lines` with `&[&str]` directly, without having to call
`collect` on it first.
78f1c14 (uncategorized) Small fixes to constraint-explorer (#894)
984afd5 (uncategorized) Cache dependencies in the CI workflow to speed up builds (#883)
6e76729 (uncategorized) Move example vhs tapes to a folder (#867)
151db6a (uncategorized) Add commit footers to git-cliff config (#805)
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
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/
💖 Consider sponsoring us at https://github.com/sponsors/ratatui-org!
Features
79ceb9f
(line) Add alignment convenience functions (#856)
0df9354
(padding) Add new constructors for padding (#828)
Fixes:Create constructors for Padding that make it more clear #798
d726e92
(paragraph) Add alignment convenience functions (#866)
c1ed5c3
(span) Add alignment functions (#873)
Closes Add Alignment convenience methods to Line, Text and Paragraph (and perhaps Span). #853
b80264d
(text) Add alignment convenience functions (#862)
23f6938
(block) Add
Block::bordered
(#736)ffd5fc7
(color) Add Color::from_u32 constructor (#785)
4f2db82
(color) Use the FromStr implementation for deserialization (#705)
1cbe1f5
(constraints) Rename
Constraint::Proportional
toConstraint::Fill
(#880)Constraint::Fill
is a more intuitive name for the behavior, and it isshorter.
Resolves Rename
Constraint::Proportional
toConstraint::Fill
#859dfd6db9
(demo2) Add destroy mode to celebrate commit 1000! (#809)
540fd2d
(layout) Change
Flex::default()
(#881) [breaking]bbcfa55
(layout) Add Rect::contains method (#882)
736605e
(layout) Add default impl for Position (#869)
1e75596
(layout) Increase default cache size to 500 (#850)
Fixes:Increase Layout cache size #820
2819eea
(layout) Add Position struct (#790)
1561d64
(layout) Add Rect -> Size conversion methods (#789)
f13fd73
(layout) Add
Rect::clamp()
method (#749)98bcf1c
(layout) Add Rect::split method (#729)
0494ee5
(layout) Accept Into for constructors (#744)
7ab12ed
(layout) Add horizontal and vertical constructors (#728)
4278b40
(line) Implement iterators for Line (#896)
5d410c6
(line) Implement Widget for Line (#715)
c977293
(line) Add style field, setters and docs (#708) [breaking]
BREAKING CHANGE:
Line::style
is now a field ofLine
instead of beingstored in each
Span
.bbf2f90
(rect.rs) Implement Rows and Columns iterators in Rect (#765)
fe06f0c
(serde) Support TableState, ListState, and ScrollbarState (#723)
37c1836
(span) Implement Widget on Span (#709)
e1e85aa
(style) Add material design color palette (#786)
bf67850
(style) Add tailwind color palette (#787)
27e9216
(table) Remove allow deprecated attribute used previously for segment_size ✨ (#875)
a489d85
(table) Deprecate SegmentSize on table (#842)
c69ca47
(table) Collect iterator of
Row
intoTable
(#774) [breaking]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 beinferred.
2faa879
(table) Accept Text for highlight_symbol (#781)
e64e194
(table) Implement FromIterator for widgets::Row (#755)
803a72d
(table) Accept Into for widths (#745)
f025d2b
(table) Add Table::footer and Row::top_margin methods (#722)
f29c73f
(tabs) Accept Iterators of
Line
in constructors (#776) [breaking]BREAKING CHANGE:Calls to
Tabs::new()
whose argument is collected from an iteratorwill 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 tobe a
Vec<_>
.b459228
(termwiz) Add
From
termwiz style impls (#726)9ba7354
(text) Implement iterators for Text (#900)
68d5783
(text) Add style and alignment (#807)
Fixes Add Style and Alignment to Text #758, fixes Implement Widget for Text #801
This PR adds:
style
andalignment
toText
Widget
forText
Text
manual draw to call for Widget implAll places that use
Text
have been updated and support its newfeatures expect paragraph which still has a custom implementation.
815757f
(widgets) Implement Widget for Widget refs (#833)
Fixes:State, borrowing widgets, etc #164
Replaces PRs: feat(widgets)!: make widgets optionally reusable #122 and
feat(widget): add render_ref method to Widget trait #16
Enables:List: Create a WidgetList where each item in the list is a Widget rather than Text #132
Validated as a viable working solution by:
docs(examples): refactor demo2 #836
eb79256
(widgets) Collect iterator of
ListItem
intoList
(#775)c8dd879
(uncategorized) Add WidgetRef and StatefulWidgetRef traits (#903)
87bf1dd
(uncategorized) Replace Rect::split with Layout::areas and spacers (#904)
dab08b9
(uncategorized) Show space constrained UIs conditionally (#895)
2a12f7b
(uncategorized) Impl Widget for &BarChart (#897)
9ec43ef
(uncategorized) Constraint Explorer example (#893)
constraint-explorer-demo.mov
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:#792
4ee4e6d
(uncategorized) Make spacing work in
Flex::SpaceAround
andFlex::SpaceBetween
(#892)gap-spacearound-spacebetween.mov
Now user provided spacing gaps always take priority in all
Flex
modes.dd5ca3a
(uncategorized) Better weights for constraints (#889)
aeec163
(uncategorized) Change rounding to make tests stable (#888)
be4fdaa
(uncategorized) Change priority of constraints and add
split_with_spacers
✨ (#788)d713201
(uncategorized) Add
Color::from_hsl
✨ (#772)Related Support hsluv color constructor #763
405a125
(uncategorized) Add wide and tall proportional border set (#848)
symbols::border::PROPORTIONAL_WIDE
symbols::border::PROPORTIONAL_TALL
Fixes:#834
9df6ceb
(uncategorized) Table column calculation uses layout spacing ✨ (#824)
f299463
(uncategorized) Add one eighth wide and tall border sets ✨ (#831)
ae6a2b0
(uncategorized) Add spacing feature to flex example ✨ (#830)
cddf4b2
(uncategorized) Implement Display for Text, Line, Span (#826)
Issue:implement
Display
forText
,Line
,Span
#816This PR adds:
std::fmt::Display
forText
,Line
, andSpan
structs.Display implementation displays actual content while ignoring style.
5131c81
(uncategorized) Add layout spacing ✨ (#821)
de97a1f
(uncategorized) Add flex to layout ✨
flex.mov
9a3815b
(uncategorized) Add Constraint::Fixed and Constraint::Proportional ✨ (#783)
425a651
(uncategorized) Add comprehensive tests for Length interacting with other constraints ✨ (#802)
c50ff08
(uncategorized) Add frame count ✨ (#766)
8f56fab
(uncategorized) Accept Color and Modifier for all Styles (#720) [breaking]
Line::styled("hello", Color::Red);
Line::styled("world", Modifier::BOLD);
c959bd2
(calendar) CalendarEventStore panic (#822)
CalendarEventStore::today()
panics if the system's UTC offset cannotbe determined. In this circumstance, it's better to use
now_utc
instead.
0614190
(cd) Fix grepping the last release (#762)
a67815e
(chart) Exclude unnamed datasets from legend (#753)
3e7810a
(example) Increase layout cache size (#815)
50b81c9
(examples/scrollbar) Title wasn't displayed because of background reset (#795)
b3a57f3
(list) Modify List and List example to support saving offsets. (#667)
6645d2e
(table) Ensure that default and new() match (#751) [breaking]
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)
Fixes Table: Make it more difficult to render a table without
widths
set #510.f71bf18
(uncategorized) Bug with flex stretch with spacing and proportional constraints (#829)
cc6737b
(uncategorized) Make SpaceBetween with one element Stretch 🐛 (#813)
7a8af8d
(uncategorized) Update templates links (#808)
f2eab71
(uncategorized) Broken tests in table.rs (#784)
8dd177a
(uncategorized) Fix PR write permission to upload unsigned commit comment (#770)
Refactor
cf86123
(scrollbar) Rewrite scrollbar implementation (#847)
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. UseBlock::title
andTitle::position
instead.a62632a
(buffer) Split buffer module into files (#721)
e0aa6c5
(chart) Replace deprecated apply (#812)
Fixes fix apply deprecation in chart #793
7f42ec9
(colors_rgb) Impl widget on mutable refs (#865)
813f707
(example) Improve constraints and flex examples (#817)
bb5444f
(example) Add scroll to flex example (#811)
6d15b25
(layout) Move the remaining types (#743)
659460e
(layout) Move SegmentSize to layout/segment_size.rs (#742)
ba036cd
(layout) Move Layout to layout/layout.rs (#741)
8724aeb
(layout) Move Margin to margin.rs (#740)
9574198
(line) Reorder methods for natural reading order (#713)
6364533
(table) Split table into multiple files (#718)
5aba988
(terminal) Extract types to files (#760)
4d262d2
(widget) Move borders to widgets/borders.rs (#832)
5254795
(uncategorized) Make layout tests a bit easier to understand (#890)
bd6b91c
(uncategorized) Make
patch_style
&reset_style
chainable (#754) [breaking]da6c299
(uncategorized) Extract layout::Constraint to file (#739)
Documentation
6ecaeed
(text) Add overview of the relevant methods (#857)
50374b2
(backend) Fix broken book link (#733)
e1cc849
(breaking) Fix typo (#702)
49df5d4
(example) Fix markdown syntax for note (#730)
4b8e54e
(examples) Refactor Tabs example (#861)
5b7ad2a
(examples) Update gauge example (#863)
f383625
(examples) Add note about example versions to all examples (#871)
847bacf
(examples) Refactor demo2 (#836)
804c841
(examples) Update list example and list.tape (#864)
eb1484b
(examples) Update tabs example and tabs.tape (#855)
330a899
(examples) Update table example and table.tape (#840)
Fixes:Update table example #800
41de884
(examples) Document incompatible examples better (#844)
3464894
(examples) Add warning about examples matching the main branch (#778)
fb93db0
(examples) Simplify docs using new layout methods (#731)
d6b8513
(examples) Refactor chart example to showcase scatter (#703)
fe84141
(layout) Document the difference in the split methods (#750)
48b0380
(scrollbar) Complete scrollbar documentation (#823)
e67d3c6
(table) Fix typo (#707)
065b6b0
(terminal) Document buffer diffing better (#852)
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)
43b2b57
(uncategorized) Fix typo in Table widget description (#797)
2b4aa46
(uncategorized) GitHub admonition syntax for examples README.md (#791)
388aa46
(uncategorized) Update crate, lib and readme links (#771)
Performance
1d3fbc1
(buffer) Apply SSO technique to text buffer in
buffer::Cell
(#601) [breaking]Testing
663bbde
(layout) Convert layout tests to use rstest (#879)
f780be3
(layout) Parameterized tests 🚨 (#858)
Miscellaneous Tasks
ba20372
(contributing) Remove part about squashing commits (#874)
d49bbb2
(ci) Update the job description for installing cargo-nextest (#839)
8d77b73
(ci) Use cargo-nextest for running tests (#717)
b7a4793
(ci) Bump alpha release for breaking changes (#495)
fab943b
(contributing) Add deprecation notice guideline (#761)
fc0879f
(layout) Comment tests that may fail on occasion (#814)
f8367fd
(uncategorized) Allow Buffer::with_lines to accept IntoIterator (#901)
78f1c14
(uncategorized) Small fixes to constraint-explorer (#894)
984afd5
(uncategorized) Cache dependencies in the CI workflow to speed up builds (#883)
6e76729
(uncategorized) Move example vhs tapes to a folder (#867)
151db6a
(uncategorized) Add commit footers to git-cliff config (#805)
Fixes:Changelog truncating body text orhun/git-cliff#297
c24216c
(uncategorized) Add comment on PRs with unsigned commits (#768)
Contributors
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!Sponsors
Shout out to our new sponsors!
This discussion was created from the release v0.26.0.
Beta Was this translation helpful? Give feedback.
All reactions