ratatui
A library that's all about cooking up terminal user interfaces
0.30.2
46M downloads/mo
#1297 most downloaded on crates.io
ratatui/ratatui
What this package is like to depend on
Last release 2 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
5 releases in the last 12 months
see the full history below
Release timeline
87 releases · Feb 2023 to Jun 2026Releases
latest 60 of 87-
0.30.219 Jun 2026Release notes
Open source →We are excited to announce the new version of
ratatui- a Rust library that's all about cooking up TUIs 👨🍳🐀✨ Release highlights: https://ratatui.rs/highlights/v0302/
⚠️ List of breaking changes can be found here.
Features
-
90639c1 (uncategorized) Add Termina backend by
@joshkain #2561Summary
- add the
ratatui-terminabackend crate using the publishedtermina
crate - expose the backend through the
terminafeature and Ratatui
prelude/backend re-exports - add a small Termina event-loop example and wire the backend into CI,
xtask, README generation, and docs
Refs #1784
Validation
cargo +nightly fmtcargo check -p ratatui-termina --all-features --all-targetscargo check -p ratatui --no-default-features --features terminacargo check -p xtaskcargo check -p release-headercargo xtask check-backend terminacargo xtask test-backend terminacargo xtask rdme --checkmarkdownlint-cli2 ARCHITECTURE.md ratatui-termina/README.md .github/ISSUE_TEMPLATE/bug_report.md
- add the
Bug Fixes
-
fce3c80 (widgets) Require thread-safe shadow effects by
@joshkain #2584Summary
- require custom shadow effects to preserve the auto traits expected by
Block-backed widgets - document the CellEffect auto-trait contract
- add a public widget regression test for the affected ratatui::widgets
re-exports
Fixes #2583
- require custom shadow effects to preserve the auto traits expected by
-
e306ce6 (buffer) Create updates for "uncovered" cells by
@benjajajain #2587When a wide cell from the previous buffer is replaced by a short/normal
cell, the trailing cell does not get an update if its content does not
change. But if the wide cell has a background (or other) style, the
terminal did render the trailing cell with that style.Force trailing cells to update if background, underline, or modifiers
are different than the wide cell. We can ignore foreground.Fixes #2585 (see that for the detailed visual reports)
-
81e667f (scrollbar) Keep a large thumb within the track at the end by
@satyakwokin #2594Closes #2582.
Problem
When the content is shorter than the viewport, the thumb is large
relative to the track. With the position at the end,part_lengths
clampedthumb_starttotrack_length - 1whilethumb_lengthwas
clamped independently to[1, track_length], sothumb_start + thumb_lengthcould exceedtrack_length.bar_symbolslays outbegin + track_start + thumb + track_end + end
and zips it against the cells of the area. When the thumb overruns the
track,track_endsaturates to0but the thumb still emits more cells
than the track can hold, so the trailingendsymbol is pushed past the
end of the area. The last visible cell ends up being a thumb (█) where
the end arrow (▼) should be.Concretely, for the issue's repro (
VerticalRight,content_length = 9,position = 8, height24): track is22,thumb_length = 17,
thumb_start = 6, and6 + 17 = 23 > 22.This is a regression from v0.30.0, where
thumb_lengthwas derived as
thumb_end - thumb_startand therefore always fit within the track.Fix
Clamp
thumb_starttotrack_length - thumb_length(instead of
track_length - 1) so the thumb always fits within the track and the
end symbol is preserved.Test
Two regression tests, both fail on
mainand pass with the fix:thumb_stays_within_track_for_large_thumb_at_endchecks
part_lengthsdirectly with the issue's parameters — asserts
thumb_start + thumb_length <= track_lengthand that the parts sum to
the track length.render_scrollbar_keeps_end_symbol_for_large_thumbrenders the #2582
case (both arrows, large thumb at the end) and asserts the end symbol is
drawn rather than overwritten by a thumb cell.
All existing scrollbar tests still pass.
Miscellaneous Tasks
-
c75d778 (ci) Add cargo-udeps dependency check by
@joshkain #2599Adds cargo xtask udeps and runs it from CI as a required job.
This complements cargo-machete rather than replacing it. cargo-machete
is a fast static source scan, which is why it missed the package-level
unused deps fixed in #2598 when the same dependency names were still
referenced by example crates. cargo-udeps compiles the workspace and
checks rustc dep-info, so it can catch unused dependency declarations
for the package being checked.To make the new job pass, this also removes the remaining true-positive
unused dev-deps and records explicit cargo-udeps ignores for current
false positives / intentional cases: ratatui-core critical-section,
ratatui-crossterm's duplicate crossterm version feature shape, and
ratatui-termwiz's doc-example-only ratatui dev-dependency.I searched existing issues and PRs for udeps / cargo-udeps / "cargo
udeps". I did not find prior ratatui discussion about adopting
cargo-udeps; the only hits were Dependabot PR bodies for
taiki-e/install-action release notes mentioning cargo-udeps version
updates, for example #1971, #2095, #2194, and #2522.Validation:- cargo xtask udeps
- cargo xtask format --check
-
4a63d41 (uncategorized) Remove unused dependencies by
@KikiKianin #2598Audit removes these dependencies that are not used:
ratatui/Cargo.toml — Removed from [dev-dependencies]:
- futures
- rand_chacha
- tokio
- tracing
- tracing-appender
- tracing-subscriber
ratatui-core/Cargo.toml — Moved from [dependencies] →
[dev-dependencies]:- indoc
Continuous Integration
-
36854ef (uncategorized) Add auto-merge required gate by
@joshkain #2596Summary
This makes GitHub auto-merge usable for Ratatui PRs once maintainers are
happy with the change but CI is still running.The workflow change adds a single aggregate
requiredjob to the main
CI workflow. The repository now has auto-merge
enabled
and anensure checks pass
ruleset
that requires thatrequiredstatus context onmain.Why
Without a required status context, GitHub's auto-merge button is not
useful for the maintainer flow we want. The goal is to let a maintainer
review a PR, decide it is ready, click auto-merge, and move on without
coming back later just to check whether the remaining jobs finished.This does not relax the merge policy. GitHub's own auto-merge behavior
is to merge only after all required reviews and required status checks
are satisfied. This change gives GitHub a stable required status to wait
on automatically.Precedent
I have been using this same auto-merge pattern in
ratatui/tui-widgets, where
it has worked well for the intended maintainer flow: once a PR looks
ready, I can enable auto-merge and let GitHub merge it after the
remaining checks and review requirements are satisfied.How it works
The new
requiredjob depends on the main CI jobs in
.github/workflows/ci.ymland always runs after them. It fails if any
required dependency fails, is cancelled, or is skipped.The repository ruleset requires only this aggregate
requiredcontext
instead of requiring every individual matrix job separately. That gives
GitHub one stable status to wait on while preserving the existing CI
coverage.Things to know
- Auto-merge is opt-in per PR. Maintainers still choose when to click
it. - It does not skip review requirements, status checks, labels, or any
other protection rule. - A PR with auto-merge enabled can still show as blocked while checks or
required reviews are pending. That is expected. - If something needs to merge normally, maintainers can still use the
regular merge path or an allowed ruleset bypass. This is a convenience
path, not a hard blocker. - Existing open PRs may need a rebase or synchronize event after this
lands so they pick up the newrequiredworkflow job. - If a new required CI job is added later, it should be added to the
required.needslist or it will not be represented by the aggregate
gate. - Jobs that are intentionally allowed to fail should be handled
carefully before adding them torequired.needs, because skipped,
cancelled, and failed dependencies make the aggregate fail.
Current PR state
Auto-merge is already enabled on this PR. If you approve it and the
required checks pass, GitHub will squash-merge it automatically;
approving it is enough to let the PR merge once the remaining
requirements are satisfied.GitHub docs
- Automatically merging a pull
request - Managing auto-merge for pull requests in your
repository - About
rulesets - Require status checks to pass before
merging - About status
checks - Troubleshooting required status
checks
Validation
ruby -e 'require "yaml"; YAML.load_file(".github/workflows/ci.yml"); puts "ok"'actionlint .github/workflows/ci.yml- Verified
ratatui/ratatuihasallow_auto_merge: true - Verified the active
ensure checks passruleset requires status
contextrequired - Verified this PR has squash auto-merge enabled and is blocked pending
checks/review
- Auto-merge is opt-in per PR. Maintainers still choose when to click
New Contributors
Full Changelog: ratatui-v0.30.1...ratatui-v0.30.2
Release notes
Open source →We are excited to announce the new version of
ratatui- a Rust library that's all about cooking up TUIs 👨🍳🐀✨ Release highlights: https://ratatui.rs/highlights/v0302/
⚠️ List of breaking changes can be found here.
Features
-
90639c1 (uncategorized) Add Termina backend by
@joshkain #2561Summary
- add the
ratatui-terminabackend crate using the publishedterminacrate - expose the backend through the
terminafeature and Ratatui prelude/backend re-exports - add a small Termina event-loop example and wire the backend into CI, xtask, README generation, and docs
Refs #1784
Validation
cargo +nightly fmtcargo check -p ratatui-termina --all-features --all-targetscargo check -p ratatui --no-default-features --features terminacargo check -p xtaskcargo check -p release-headercargo xtask check-backend terminacargo xtask test-backend terminacargo xtask rdme --checkmarkdownlint-cli2 ARCHITECTURE.md ratatui-termina/README.md .github/ISSUE_TEMPLATE/bug_report.md
- add the
Bug Fixes
-
fce3c80 (widgets) Require thread-safe shadow effects by
@joshkain #2584Summary
- require custom shadow effects to preserve the auto traits expected by Block-backed widgets
- document the CellEffect auto-trait contract
- add a public widget regression test for the affected ratatui::widgets re-exports
Fixes #2583
-
e306ce6 (buffer) Create updates for "uncovered" cells by
@benjajajain #2587When a wide cell from the previous buffer is replaced by a short/normal cell, the trailing cell does not get an update if its content does not change. But if the wide cell has a background (or other) style, the terminal did render the trailing cell with that style.
Force trailing cells to update if background, underline, or modifiers are different than the wide cell. We can ignore foreground.
Fixes #2585 (see that for the detailed visual reports)
-
81e667f (scrollbar) Keep a large thumb within the track at the end by
@satyakwokin #2594Closes #2582.
Problem
When the content is shorter than the viewport, the thumb is large relative to the track. With the position at the end,
part_lengthsclampedthumb_starttotrack_length - 1whilethumb_lengthwas clamped independently to[1, track_length], sothumb_start + thumb_lengthcould exceedtrack_length.bar_symbolslays outbegin + track_start + thumb + track_end + endand zips it against the cells of the area. When the thumb overruns the track,track_endsaturates to0but the thumb still emits more cells than the track can hold, so the trailingendsymbol is pushed past the end of the area. The last visible cell ends up being a thumb (█) where the end arrow (▼) should be.Concretely, for the issue's repro (
VerticalRight,content_length = 9,position = 8, height24): track is22,thumb_length = 17,thumb_start = 6, and6 + 17 = 23 > 22.This is a regression from v0.30.0, where
thumb_lengthwas derived asthumb_end - thumb_startand therefore always fit within the track.Fix
Clamp
thumb_starttotrack_length - thumb_length(instead oftrack_length - 1) so the thumb always fits within the track and the end symbol is preserved.Test
Two regression tests, both fail on
mainand pass with the fix:thumb_stays_within_track_for_large_thumb_at_endcheckspart_lengthsdirectly with the issue's parameters — assertsthumb_start + thumb_length <= track_lengthand that the parts sum to the track length.render_scrollbar_keeps_end_symbol_for_large_thumbrenders the #2582 case (both arrows, large thumb at the end) and asserts the end symbol is drawn rather than overwritten by a thumb cell.
All existing scrollbar tests still pass.
Miscellaneous Tasks
-
c75d778 (ci) Add cargo-udeps dependency check by
@joshkain #2599Adds cargo xtask udeps and runs it from CI as a required job.
This complements cargo-machete rather than replacing it. cargo-machete is a fast static source scan, which is why it missed the package-level unused deps fixed in #2598 when the same dependency names were still referenced by example crates. cargo-udeps compiles the workspace and checks rustc dep-info, so it can catch unused dependency declarations for the package being checked.
To make the new job pass, this also removes the remaining true-positive unused dev-deps and records explicit cargo-udeps ignores for current false positives / intentional cases: ratatui-core critical-section, ratatui-crossterm's duplicate crossterm version feature shape, and ratatui-termwiz's doc-example-only ratatui dev-dependency.
I searched existing issues and PRs for udeps / cargo-udeps / "cargo udeps". I did not find prior ratatui discussion about adopting cargo-udeps; the only hits were Dependabot PR bodies for taiki-e/install-action release notes mentioning cargo-udeps version updates, for example #1971, #2095, #2194, and #2522.
Validation:- cargo xtask udeps
- cargo xtask format --check
-
4a63d41 (uncategorized) Remove unused dependencies by
@KikiKianin #2598Audit removes these dependencies that are not used:
ratatui/Cargo.toml — Removed from [dev-dependencies]:
- futures
- rand_chacha
- tokio
- tracing
- tracing-appender
- tracing-subscriber
ratatui-core/Cargo.toml — Moved from [dependencies] → [dev-dependencies]:
- indoc
Continuous Integration
-
36854ef (uncategorized) Add auto-merge required gate by
@joshkain #2596Summary
This makes GitHub auto-merge usable for Ratatui PRs once maintainers are happy with the change but CI is still running.
The workflow change adds a single aggregate
requiredjob to the main CI workflow. The repository now has auto-merge enabled and anensure checks passruleset that requires thatrequiredstatus context onmain.Why
Without a required status context, GitHub's auto-merge button is not useful for the maintainer flow we want. The goal is to let a maintainer review a PR, decide it is ready, click auto-merge, and move on without coming back later just to check whether the remaining jobs finished.
This does not relax the merge policy. GitHub's own auto-merge behavior is to merge only after all required reviews and required status checks are satisfied. This change gives GitHub a stable required status to wait on automatically.
Precedent
I have been using this same auto-merge pattern in
ratatui/tui-widgets, where it has worked well for the intended maintainer flow: once a PR looks ready, I can enable auto-merge and let GitHub merge it after the remaining checks and review requirements are satisfied.How it works
The new
requiredjob depends on the main CI jobs in.github/workflows/ci.ymland always runs after them. It fails if any required dependency fails, is cancelled, or is skipped.The repository ruleset requires only this aggregate
requiredcontext instead of requiring every individual matrix job separately. That gives GitHub one stable status to wait on while preserving the existing CI coverage.Things to know
- Auto-merge is opt-in per PR. Maintainers still choose when to click it.
- It does not skip review requirements, status checks, labels, or any other protection rule.
- A PR with auto-merge enabled can still show as blocked while checks or required reviews are pending. That is expected.
- If something needs to merge normally, maintainers can still use the regular merge path or an allowed ruleset bypass. This is a convenience path, not a hard blocker.
- Existing open PRs may need a rebase or synchronize event after this
lands so they pick up the new
requiredworkflow job. - If a new required CI job is added later, it should be added to the
required.needslist or it will not be represented by the aggregate gate. - Jobs that are intentionally allowed to fail should be handled
carefully before adding them to
required.needs, because skipped, cancelled, and failed dependencies make the aggregate fail.
Current PR state
Auto-merge is already enabled on this PR. If you approve it and the required checks pass, GitHub will squash-merge it automatically; approving it is enough to let the PR merge once the remaining requirements are satisfied.
GitHub docs
- Automatically merging a pull request
- Managing auto-merge for pull requests in your repository
- About rulesets
- Require status checks to pass before merging
- About status checks
- Troubleshooting required status checks
Validation
ruby -e 'require "yaml"; YAML.load_file(".github/workflows/ci.yml"); puts "ok"'actionlint .github/workflows/ci.yml- Verified
ratatui/ratatuihasallow_auto_merge: true - Verified the active
ensure checks passruleset requires status contextrequired - Verified this PR has squash auto-merge enabled and is blocked pending checks/review
New Contributors
Full Changelog: https://github.com/ratatui/ratatui/compare/ratatui-v0.30.1...ratatui-v0.30.2
-
-
0.30.105 Jun 2026Release notes
Open source →"Rats, we're rats; we're the rats." – Rat Movie
We are excited to announce the new version of
ratatui- a Rust library that's all about cooking up TUIs 👨🍳🐀✨ Release highlights: https://ratatui.rs/highlights/v0301/
⚠️ List of breaking changes can be found here.
Features
-
74d6a84 (block) Support shadows by orhun in #2481
Introduce
Block::shadow(...)with a newShadowtype that supports:- presets:
overlay,block,light_shade,medium_shade,
dark_shade - custom symbols via
Shadow::symbol(...) - custom effects via
Shadow::custom(...)
use ratatui::layout::Offset; use ratatui::style::Stylize; use ratatui::widgets::{Block, Shadow}; let popup = Block::bordered().title("Popup").shadow( Shadow::dark_shade() .black() .on_white() .offset(Offset::new(2, 1)), );
Results in:
┌Popup─────┐ │content │▒ └──────────┘▒ ▒▒▒▒▒▒▒▒▒▒▒fixes #1892
- presets:
-
4d30420 (buffer) Add
CellDiffOption::AlwaysUpdateto force cell updates by sxyazi in #2480When this option is used, the cells are updated even when content is identical.
Follow-up for #1605
Trying to resolve #1116
-
39c32c6 (buffer) Add cell diff options by benjajaja in #1605
Problem:Escape sequences always cause a cell to count as "multiwidth",
even when it doesn't render wider than one cell, or not as wide as the
escape sequence would be computed as.Solution:Convert
skip:boolto enum. Add enum optionForceWidthto
force a cell width for diffing.When using the option, this also fixes some bug where diffing is not
idempotent and causes a diff operation for(symbol.len() - 1)times.There are three new specific test cases:
- Rendering hyperlinks by squeezing the escape sequence into the first
cell and forcing the width to the unicode width of the text part.
This is much easier to implement for a Link widget, as it would only
need to get the unicode-width once and not iterate over graphemes
like Spans must do. - Rendering hyperlinks by squeezing the opening sequence into the first
cell with the first grapheme and forcing the width to that of the
first grapheme. Then rendering each grapheme as usual. Then squeezing
the closing sequence into the last cell with the last grapheme and
forcing the width to that of the last grapheme.
This is harder to implement for a Link widget, as it would have to
iterate over graphemes with their width like Spans do. - Kitty image sequence with utf-8 placeholders, similar to 2 but with
known constant grapheme widths.
Link widget that leverages this
https://github.com/benjajaja/tui-link
It would be cooler if we could just add something like
.link(url)to
Spans, because it would much simpler to insert some link and leverage
all the Line/Text/Paragraph wrapping and whatnot. With a custom widget
you need to take care of theAreawhere you'd want to render it, so
it's not that clean. But we could iterate on this later, if even
possible. - Rendering hyperlinks by squeezing the escape sequence into the first
-
6faaddb (core) Implement from slice for line and text by NoOPeEKS in #2371
This PR adds the following implementations of the From trait for Line
and Text structs:- Implements From<&[T]> where T is Into<Span> for Line, allowing using
of slices to construct Lines. - Implements From<&[T]> where T is Into<Line> for Text, allowing using
of slices of various types to construct Texts.
closes #2279
- Implements From<&[T]> where T is Into<Span> for Line, allowing using
-
5fc6ab8 (core) Support layout-cache in no_std environments by junkdog in #2399
this enables "layout-cache" for no_std builds; it's meant for embedded
environments, where the layout engine otherwise consumes all CPU,
capping the framerate at around ~10fps. the same app can refresh 300-500
times per second with layout cache enabled.i had to add
layout-cache = ["dep:critical-section"]to all builds -
it's pretty tiny and shouldn't leave a trace in std-builds. the
alternative is to add an extra layer of features for layout-cache with
std and no_std, but it pollutes the feature space.
-
ee4b7a9 (crossterm) Add the missing hidden modifier by sxyazi in #2413
Fixes sxyazi/yazi#3724, see
sxyazi/yazi#3724 (comment) for a
reproducer.This PR adds the missing
Modifier::HIDDENstyle and introduces a
queue_modifier_diffto testModifierDiff::queue().It also fixes a bug where
CrosstermAttribute::Boldand
CrosstermAttribute::Dimwould be emitted twice when resetting
intensity. For example:#[case(Modifier::DIM, Modifier::BOLD, &[CrosstermAttribute::NormalIntensity, CrosstermAttribute::Bold])]would become:
#[case(Modifier::DIM, Modifier::BOLD, &[CrosstermAttribute::NormalIntensity, CrosstermAttribute::Bold, CrosstermAttribute::Bold])]
-
9d9239a (examples) Add volatility-surface 3D visualization by floor-licker in #2322
A design demonstration of a 3D volatility surface rendering using
Braille canvas with interactive rotation and zoom controls. I built this
for myself for an app I'm currently building but just wanted to share it
with the community as well to inspire more 3D perspective terminal
widgets in the future.Final Demo
Description
Adds a new example demonstrating 3D visualization techniques in the
demo.mov
terminal. There aren't many examples showing how to represent 3D objects
in 2D terminal space so my goal is just to demonstrate more advanced
Canvas and Braille rendering techniques for 3D graphics. The example
visualizes an implied volatility surface which is a common financial
visualization using interactive rotation and zoom controls. You can run
the interactive demo for yourself withcargo run -p volatility-surface<img width="659" height="432" alt="image"
src="https://github.com/user-attachments/assets/68698cb0-c5d5-4b41-a3c3-65ec8fff12f5"
/>Technical Highlights
- Demonstrates how to implement perspective projection in a terminal
- Shows advanced use of
Canvaswidget withMarker::Braille - Example of smooth animation patterns and state management
- Self-contained with synthetic data generation (no external APIs)
-
ae975c7 (examples) Allow overlap spacing in explorer by joshka in #2316
Store spacing as i16 so negative values map to Spacing::Overlap, and
show overlap in the axis label. -
1e0ab0c (ratatui-crossterm) Add IntoCrossterm for Style by 0xferrous in #2323
-
101a63e (render) Add function for applying buffer by musjj in #2566
Add a public API for applying and flushing the terminal buffer.
A minimal usage will look something like this:
use ratatui::Terminal; use ratatui::backend::CrosstermBackend; use ratatui::buffer::Buffer; use ratatui::widgets::Widget; let backend = CrosstermBackend::new(io::stdout()); let mut terminal = Terminal::new(backend)?; terminal.autoresize()?; let mut custom_buffer = Buffer::default(); custom_buffer.resize(terminal.get_frame().area()); custom_buffer.reset(); "Hello World!".render(custom_buffer.area, &mut custom_buffer); terminal.current_buffer_mut().merge(&custom_buffer); terminal.apply_buffer()?;
My primary motivation for this PR is to improve the ECS ergonomics in
bevy_ratatui. But this
should be useful for anyone who wants to commit incremental writes to
the buffer without having to do everything in one monolithic
Terminal::draw
closure.
-
f9d066f (table) Let Cells span multiple columns by karkhaz in #2150
Add a 'column_span' field to table cells. The default value
is 1; larger values will cause cells to span over multiple columns,
being rendered over all columns plus the spaces between them.Fixes #1568.
-
a5b08d6 (widgets) Add Fill widget by Metbcy in #2520
Adds a new
Fillwidget that paints every cell within its area with a
single repeated symbol and style. Integrates withStylizeso the whole
chain works as expected:use ratatui::widgets::{Fill, Widget}; use ratatui::style::Stylize; Fill::new("X").blue().bold().render(area, buf);
Implements
Widget(for bothFilland&Fill) andStyled, accepts
anything that converts into aCow<'a, str>, and degrades gracefully on
empty / multi-grapheme symbols.
-
9094fd2 (widgets) Add line shape with filled area for Canvas and Chart by bananaofhappiness in #2426
This commit adds filled area-chart rendering for both
CanvasandChart.You can now render a line and fill the area between that line and a baseline Y value, which helps highlight magnitude/volume trends.
- In
Canvas, useFilledLine. - In
Chart, useGraphType::Areaand set the baseline viaDataset::fill_to_y(f64).
The
f64baseline is now configured onDataset(not inGraphType), soGraphTypestays a simple enum variant.Under the hood, line rasterization in canvas was refactored to share a reusable Bresenham point iterator, and
FilledLinebuilds on that to paint vertical spans from each line point tofill_to_y.Some screenshots with and without this new type:
// In Canvas use ratatui::widgets::canvas::FilledLine; Canvas::default() .paint(|ctx| { ctx.draw(&FilledLine::new(0.0, 0.0, 10.0, 5.0, 0.0, Color::Red)); }); // In Chart let dataset = Dataset::default() .data(&data) .graph_type(GraphType::Area) .fill_to_y(0.0); // fill to y = 0 Chart::new(vec![dataset]);
- In
-
0a87882 (uncategorized) Add
impl From<u16>forPaddingandMarginby JayanAXHF in #2438 -
556cc7b (uncategorized) Add comment for inner area to popup example by Its-Just-Nans in #2309
-
01a15f9 (uncategorized) Add AsRef impls for widget types by joshka in #2297
Bug Fixes
-
d12bb83 (barchart) Handle empty horizontal charts by fallintoplace in #2553
Fixes #2552
This makes the
BarChartconstructors ignore empty groups, matching the
existing.data(...)builder behavior. Without this,BarChart::horizontal(Vec::<Bar>::new())stores one empty group,
proceeds into horizontal rendering, skips the bar loop, and then
underflows when computing the group label row frombar_y - self.bar_gap.The fix normalizes constructor input through a shared
non_empty_groups
helper fornew,horizontal, andgrouped. Empty horizontal charts
now render nothing instead of panicking, and constructor behavior is
consistent with.data(...).
-
6396b1c (block) Saturate block edge arithmetic by joshka in #2488
Motivation
- Block border and title layout used unchecked
u16arithmetic in
several places. - In debug builds that can panic on tiny or edge-case geometry; in
release builds the same arithmetic wraps. - The original report came from merge-border rendering on tiny areas,
but the same pattern appeared in title layout and spacing helpers as
well.
Description
- Use saturating arithmetic in
Block::inner,render_sides,
render_corners,titles_area, andvertical_space. - Clamp rendered title widths to
u16for layout arithmetic. - Replace unchecked title-width accumulation and cursor-advance math
with bounded arithmetic. - Add debug-only regression tests covering empty areas, maximal padding,
title-area edge cases, and very large title widths.
Testing
- Ran
cargo test -p ratatui-widgets block::tests.
- Block border and title layout used unchecked
-
9143b83 (buffer) Diff for trailing cells when only style changes by gcavelier in #2308
this PR closes #2307 by preventing unnecessary diff updates for trailing
cells when only style changes.This PR was generated by Claude, and validated by me.
Summary
This PR fixes a visual artifact bug where block borders would appear
offset when rendered over a widget that had a foreground color style
applied to the entire area.The Fix
- if !next_trailing.skip && prev_trailing != next_trailing { + // Only emit update if the SYMBOL changed, not just the style. + // The style of hidden trailing cells is not visible, so style + // differences alone should not trigger updates that can cause + // cursor positioning issues on some terminals. + if !next_trailing.skip && prev_trailing.symbol() != next_trailing.symbol() {
This aligns the code with the documented intent: only emit updates when
the symbol (visible content) changes, not when only the style
changes.Changes
File Change ratatui-core/src/buffer/buffer.rs:526-530Compare only symbol, not full cell ratatui-core/src/buffer/buffer.rs:1376-1425Add regression test Test Added
#[test] fn diff_ignores_style_only_changes_in_trailing_cells() { // Verifies that trailing cells with same symbol but different style // do NOT generate diff updates }
Why This Is Safe
- Trailing cells are hidden - they are visually covered by the wide
character - Style is invisible - the fg/bg color of a hidden cell has no
visual effect - Symbol changes still trigger updates - if the symbol changes
(e.g., from" "to"x"), the update is still emitted - Aligns with documented intent - the original comment says
"non-blank content", not "different style"
Related
- The existing test
diff_clears_trailing_cell_for_wide_grapheme
verifies that symbol changes DO trigger updates - This fix complements that behavior by ensuring style-only changes do
NOT trigger updates
- Trailing cells are hidden - they are visually covered by the wide
-
e6b71f2 (build) Correct rust-toolchain->rust-version on cargo-deny-action by sermuns in #2471
closes #2470
-
43bbaae (clippy) Fix beta clippy errors by Logan-Ruf in #2433
Noticed these errors on my other PR and figured I could just fix them
real quick.closes #2432
-
957fbb0 (core) Use correct width for halfwidth dakuten/handakuten by orhun in #2499
unicode-width reports U+FF9E/U+FF9F as zero-width, but terminals render
them as 1 cell.
AdjustsCellWidthtrait accordingly for fixing this behavior.fixes #2188
-
d7646c7 (core) Avoid overflow in BufferDiff forced-width advance by joshka in #2487
Motivation
- Prevent arithmetic overflow when advancing
self.posfor
CellDiffOption::ForcedWidth(NonZeroU16)in
ratatui-core/src/buffer/diff.rs, which could panic in debug or wrap in
release and cause an iterator hang/DoS.
Description
- Replace the unchecked
self.pos += width.get().saturating_sub(1)with
a saturating addition viaself.pos = self.pos.saturating_add(width.get().saturating_sub(1) as usize)to
avoid overflow while preserving existing iterator semantics.
Testing
- Ran
cargo test -p ratatui-core buffer::diff --liband the buffer
diff tests completed successfully (10 passed, 0 failed).
- Prevent arithmetic overflow when advancing
-
77f8006 (core) Avoid cursor position queries during resize by orhun in #2485
Terminal::resize()now clears without callingget_cursor_position(),
so that CPR (Cursor position report) calls does not interfere with
stdin.Fixes #2483
-
18aa467 (examples) Make line-gauge example compatible with macos sequoia's terminal.app by lazo4 in #2474
Part of the fix for #1972
Summary
This fix makes the
line-gaugeexample compatible with the macos
sequoia Terminal.app which doesn't support truecolor. It reuses the
is_true_color_supportedintroduced in #2211 by ffex and uses a color
theme instead of hardcoding the colors.Result on macos sequoia
Notes
This is my first open source contribution, thanks to @ffex for letting
me help on this issue -
ce2c228 (examples) Change flex example colors for MacOS default terminal by ffex in #2211
Part of the fix for #1972
Summary
This fix introduces a function to check if we are in a terminal without
truecolor(24-bit) and changes the default colors to appear fine of the
flex example.Notes
The function "is_true_color_supported” is an old problem and there is no
common way to determine if a terminal supports or not the truecolor.This is the main reason why the function detects specifically the
Terminal.app version before the Tahoe. If there are other known
terminals with this problem, we can add it to this function.
-
ef72dba (examples) Fix import for widget examples by orhun in #2422
closes #2299
-
88441cf (terminal) Fix inline viewport resizing issues by clearing the screen by wyvernbw in #2355
adds a check to the autoresize function to clear the entire screen and
move the inline viewport to the top when the window shrinks horizontally
in order to avoid line wrapping issues.Other libraries like ink purge the history as well, but the
backend::ClearTypetype does not support that. Without this if the
user scrolls up they will see previous broken renders. This should work
well with all terminal emulators and multiplexers.fixes #2086
-
91b6fb7 (tests) Use the correct type for the cell diff test by orhun in #2472
fixes the CI!
-
4493742 (widgets) Handle single y-axis label by fallintoplace in #2550
Fixes #2549.
This prevents
Chartfrom panicking when the Y axis is configured with
exactly one label. The X-axis rendering path already skips label
placement when fewer than two labels are provided; this applies the same
guard to Y-axis labels before the spacing calculation divides by
labels_len - 1.This also updates the
Axis::labelsdocs so they describe the newbehavior:fewer than two labels are not rendered instead of causing a
panic. -
0bdebd6 (widgets) Prevent chart scaling overflow by fallintoplace in #2546
Summary
Fixes #2545.
This changes BarChart and Sparkline scaling to use a
u128intermediate
before division, then caps the scaled ticks at the drawable area. That
prevents debug-build panics and release-build wrapping when publicu64
chart values are large.Validation
cargo test -p ratatui-widgets barchart::testscargo test -p ratatui-widgets sparkline::testscargo check -p ratatui-widgets --all-featurescargo clippy -p ratatui-widgets --all-targets --all-features -- -D warningscargo test -p ratatui-widgets
-
e27a22a (widgets) Inherit the text alignment for Paragraph by 7Bpencil in #2369
Paragraph didn't take into account alignment of the text it was created
from:let lines = vec![ Line::from("one"), Line::from("double"), Line::from("quadruple"), ]; let text = Text::from(lines).centered(); // used to be rendered left-aligned, now centered let paragraph = Paragraph::new(text).block(block);
Now the Paragraph inherits the text alignment.
-
b5c0831 (widgets) Avoid panic if Clear area is outside of buffer by 7Bpencil in #2368
If Clear area is at least partially outside of buffer, panic "index
Demo source code
outside of buffer" happens on Widget::renderuse crossterm::event::{self, Event, KeyModifiers}; use ratatui::{ layout::Rect, text::Line, widgets::{Block, Borders, Clear, Paragraph}, DefaultTerminal, Frame, }; use std::iter; fn main() { ratatui::run(app); } fn app(terminal: &mut DefaultTerminal) { loop { if let Event::Key(key_event) = event::read().expect("failed to read event") { if key_event.kind.is_press() && key_event.modifiers.contains(KeyModifiers::CONTROL) && key_event.code.is_char('c') { break; } } terminal.draw(render).expect("failed to draw frame"); } } fn render(frame: &mut Frame) { { let width = frame.area().width; let area = Rect::new(0, 0, width, 10); let line = Line::from("W".repeat(area.width as usize)); let lines: Vec<Line> = iter::repeat_n(line, area.height as usize).collect(); frame.render_widget(Paragraph::new(lines), area); } { let area = Rect::new(50, 2, 20, 5); let block = Block::default() .title_top(Line::from("Popup-with-Clear").centered()) .borders(Borders::ALL); let lines = vec![ Line::from("one"), Line::from
Note truncated.
Release notes
Open source →"Rats, we're rats; we're the rats." – Rat Movie
We are excited to announce the new version of
ratatui- a Rust library that's all about cooking up TUIs 👨🍳🐀✨ Release highlights: https://ratatui.rs/highlights/v0301/
⚠️ List of breaking changes can be found here.
Features
-
74d6a84 (block) Support shadows by @orhun in #2481
Introduce
Block::shadow(...)with a newShadowtype that supports:- presets:
overlay,block,light_shade,medium_shade,dark_shade - custom symbols via
Shadow::symbol(...) - custom effects via
Shadow::custom(...)
use ratatui::layout::Offset; use ratatui::style::Stylize; use ratatui::widgets::{Block, Shadow}; let popup = Block::bordered().title("Popup").shadow( Shadow::dark_shade() .black() .on_white() .offset(Offset::new(2, 1)), );Results in:
┌Popup─────┐ │content │▒ └──────────┘▒ ▒▒▒▒▒▒▒▒▒▒▒fixes #1892
- presets:
-
4d30420 (buffer) Add
CellDiffOption::AlwaysUpdateto force cell updates by @sxyazi in #2480When this option is used, the cells are updated even when content is identical.
Follow-up for https://github.com/ratatui/ratatui/pull/1605
Trying to resolve https://github.com/ratatui/ratatui/issues/1116
-
39c32c6 (buffer) Add cell diff options by @benjajaja in #1605
Problem:Escape sequences always cause a cell to count as "multiwidth", even when it doesn't render wider than one cell, or not as wide as the escape sequence would be computed as.
Solution:Convert
skip:boolto enum. Add enum optionForceWidthto force a cell width for diffing.When using the option, this also fixes some bug where diffing is not idempotent and causes a diff operation for
(symbol.len() - 1)times.There are three new specific test cases:
- Rendering hyperlinks by squeezing the escape sequence into the first cell and forcing the width to the unicode width of the text part. This is much easier to implement for a Link widget, as it would only need to get the unicode-width once and not iterate over graphemes like Spans must do.
- Rendering hyperlinks by squeezing the opening sequence into the first cell with the first grapheme and forcing the width to that of the first grapheme. Then rendering each grapheme as usual. Then squeezing the closing sequence into the last cell with the last grapheme and forcing the width to that of the last grapheme. This is harder to implement for a Link widget, as it would have to iterate over graphemes with their width like Spans do.
- Kitty image sequence with utf-8 placeholders, similar to 2 but with known constant grapheme widths.
Link widget that leverages this
https://github.com/benjajaja/tui-link
It would be cooler if we could just add something like
.link(url)toSpans, because it would much simpler to insert some link and leverage all the Line/Text/Paragraph wrapping and whatnot. With a custom widget you need to take care of theAreawhere you'd want to render it, so it's not that clean. But we could iterate on this later, if even possible. -
6faaddb (core) Implement from slice for line and text by @NoOPeEKS in #2371
This PR adds the following implementations of the From trait for Line and Text structs:
- Implements From<&[T]> where T is Into<Span> for Line, allowing using of slices to construct Lines.
- Implements From<&[T]> where T is Into<Line> for Text, allowing using of slices of various types to construct Texts.
closes #2279
-
5fc6ab8 (core) Support layout-cache in no_std environments by @junkdog in #2399
this enables "layout-cache" for no_std builds; it's meant for embedded environments, where the layout engine otherwise consumes all CPU, capping the framerate at around ~10fps. the same app can refresh 300-500 times per second with layout cache enabled.
i had to add
layout-cache = ["dep:critical-section"]to all builds - it's pretty tiny and shouldn't leave a trace in std-builds. the alternative is to add an extra layer of features for layout-cache with std and no_std, but it pollutes the feature space.
-
ee4b7a9 (crossterm) Add the missing hidden modifier by @sxyazi in #2413
Fixes https://github.com/sxyazi/yazi/issues/3724, see https://github.com/sxyazi/yazi/issues/3724#issuecomment-3970129744 for a reproducer.
This PR adds the missing
Modifier::HIDDENstyle and introduces aqueue_modifier_diffto testModifierDiff::queue().It also fixes a bug where
CrosstermAttribute::BoldandCrosstermAttribute::Dimwould be emitted twice when resetting intensity. For example:#[case(Modifier::DIM, Modifier::BOLD, &[CrosstermAttribute::NormalIntensity, CrosstermAttribute::Bold])]would become:
#[case(Modifier::DIM, Modifier::BOLD, &[CrosstermAttribute::NormalIntensity, CrosstermAttribute::Bold, CrosstermAttribute::Bold])]
-
9d9239a (examples) Add volatility-surface 3D visualization by @floor-licker in #2322
A design demonstration of a 3D volatility surface rendering using Braille canvas with interactive rotation and zoom controls. I built this for myself for an app I'm currently building but just wanted to share it with the community as well to inspire more 3D perspective terminal widgets in the future.
Final Demo
Description
Adds a new example demonstrating 3D visualization techniques in the terminal. There aren't many examples showing how to represent 3D objects in 2D terminal space so my goal is just to demonstrate more advanced Canvas and Braille rendering techniques for 3D graphics. The example visualizes an implied volatility surface which is a common financial visualization using interactive rotation and zoom controls. You can run the interactive demo for yourself with
cargo run -p volatility-surfacehttps://github.com/user-attachments/assets/aa32a864-54a8-4c67-a3c9-432dd29373fd
<img width="659" height="432" alt="image"
src="https://github.com/user-attachments/assets/68698cb0-c5d5-4b41-a3c3-65ec8fff12f5" />
Technical Highlights
- Demonstrates how to implement perspective projection in a terminal
- Shows advanced use of
Canvaswidget withMarker::Braille - Example of smooth animation patterns and state management
- Self-contained with synthetic data generation (no external APIs)
-
ae975c7 (examples) Allow overlap spacing in explorer by @joshka in #2316
Store spacing as i16 so negative values map to Spacing::Overlap, and show overlap in the axis label.
-
1e0ab0c (ratatui-crossterm) Add IntoCrossterm<ContentStyle> for Style by @0xferrous in #2323
-
101a63e (render) Add function for applying buffer by @musjj in #2566
Add a public API for applying and flushing the terminal buffer.
A minimal usage will look something like this:
use ratatui::Terminal; use ratatui::backend::CrosstermBackend; use ratatui::buffer::Buffer; use ratatui::widgets::Widget; let backend = CrosstermBackend::new(io::stdout()); let mut terminal = Terminal::new(backend)?; terminal.autoresize()?; let mut custom_buffer = Buffer::default(); custom_buffer.resize(terminal.get_frame().area()); custom_buffer.reset(); "Hello World!".render(custom_buffer.area, &mut custom_buffer); terminal.current_buffer_mut().merge(&custom_buffer); terminal.apply_buffer()?;My primary motivation for this PR is to improve the ECS ergonomics in
bevy_ratatui. But this should be useful for anyone who wants to commit incremental writes to the buffer without having to do everything in one monolithicTerminal::drawclosure.
-
f9d066f (table) Let Cells span multiple columns by @karkhaz in #2150
Add a 'column_span' field to table cells. The default value is 1; larger values will cause cells to span over multiple columns, being rendered over all columns plus the spaces between them.
Fixes #1568.
-
a5b08d6 (widgets) Add Fill widget by @Metbcy in #2520
Adds a new
Fillwidget that paints every cell within its area with a single repeated symbol and style. Integrates withStylizeso the whole chain works as expected:use ratatui::widgets::{Fill, Widget}; use ratatui::style::Stylize; Fill::new("X").blue().bold().render(area, buf);Implements
Widget(for bothFilland&Fill) andStyled, accepts anything that converts into aCow<'a, str>, and degrades gracefully on empty / multi-grapheme symbols.
-
9094fd2 (widgets) Add line shape with filled area for Canvas and Chart by @bananaofhappiness in #2426
This commit adds filled area-chart rendering for both
CanvasandChart.You can now render a line and fill the area between that line and a baseline Y value, which helps highlight magnitude/volume trends.
- In
Canvas, useFilledLine. - In
Chart, useGraphType::Areaand set the baseline viaDataset::fill_to_y(f64).
The
f64baseline is now configured onDataset(not inGraphType), soGraphTypestays a simple enum variant.Under the hood, line rasterization in canvas was refactored to share a reusable Bresenham point iterator, and
FilledLinebuilds on that to paint vertical spans from each line point tofill_to_y.Some screenshots with and without this new type: <img width="1460" height="879" alt="изображение" src="https://github.com/user-attachments/assets/c7b534b1-2afb-49c7-9c56-178e6ba9e844" /> <img width="1460" height="881" alt="изображение" src="https://github.com/user-attachments/assets/53592e2c-ee89-4481-9099-be06480d305a" />
// In Canvas use ratatui::widgets::canvas::FilledLine; Canvas::default() .paint(|ctx| { ctx.draw(&FilledLine::new(0.0, 0.0, 10.0, 5.0, 0.0, Color::Red)); }); // In Chart let dataset = Dataset::default() .data(&data) .graph_type(GraphType::Area) .fill_to_y(0.0); // fill to y = 0 Chart::new(vec![dataset]);
- In
-
0a87882 (uncategorized) Add
impl From<u16>forPaddingandMarginby @JayanAXHF in #2438 -
556cc7b (uncategorized) Add comment for inner area to popup example by @Its-Just-Nans in #2309
-
01a15f9 (uncategorized) Add AsRef impls for widget types by @joshka in #2297
Bug Fixes
-
d12bb83 (barchart) Handle empty horizontal charts by @fallintoplace in #2553
Fixes #2552
This makes the
BarChartconstructors ignore empty groups, matching the existing.data(...)builder behavior. Without this,BarChart::horizontal(Vec::<Bar>::new())stores one empty group, proceeds into horizontal rendering, skips the bar loop, and then underflows when computing the group label row frombar_y - self.bar_gap.The fix normalizes constructor input through a shared
non_empty_groupshelper fornew,horizontal, andgrouped. Empty horizontal charts now render nothing instead of panicking, and constructor behavior is consistent with.data(...).
-
6396b1c (block) Saturate block edge arithmetic by @joshka in #2488
Motivation
- Block border and title layout used unchecked
u16arithmetic in several places. - In debug builds that can panic on tiny or edge-case geometry; in release builds the same arithmetic wraps.
- The original report came from merge-border rendering on tiny areas, but the same pattern appeared in title layout and spacing helpers as well.
Description
- Use saturating arithmetic in
Block::inner,render_sides,render_corners,titles_area, andvertical_space. - Clamp rendered title widths to
u16for layout arithmetic. - Replace unchecked title-width accumulation and cursor-advance math with bounded arithmetic.
- Add debug-only regression tests covering empty areas, maximal padding, title-area edge cases, and very large title widths.
Testing
- Ran
cargo test -p ratatui-widgets block::tests.
- Block border and title layout used unchecked
-
9143b83 (buffer) Diff for trailing cells when only style changes by @gcavelier in #2308
this PR closes #2307 by preventing unnecessary diff updates for trailing cells when only style changes.
This PR was generated by Claude, and validated by me.
Summary
This PR fixes a visual artifact bug where block borders would appear offset when rendered over a widget that had a foreground color style applied to the entire area.
The Fix
- if !next_trailing.skip && prev_trailing != next_trailing { + // Only emit update if the SYMBOL changed, not just the style. + // The style of hidden trailing cells is not visible, so style + // differences alone should not trigger updates that can cause + // cursor positioning issues on some terminals. + if !next_trailing.skip && prev_trailing.symbol() != next_trailing.symbol() {This aligns the code with the documented intent: only emit updates when the symbol (visible content) changes, not when only the style changes.
Changes
File Change ratatui-core/src/buffer/buffer.rs:526-530Compare only symbol, not full cell ratatui-core/src/buffer/buffer.rs:1376-1425Add regression test Test Added
#[test] fn diff_ignores_style_only_changes_in_trailing_cells() { // Verifies that trailing cells with same symbol but different style // do NOT generate diff updates }Why This Is Safe
- Trailing cells are hidden - they are visually covered by the wide character
- Style is invisible - the fg/bg color of a hidden cell has no visual effect
- Symbol changes still trigger updates - if the symbol changes
(e.g., from
" "to"x"), the update is still emitted - Aligns with documented intent - the original comment says "non-blank content", not "different style"
Related
- The existing test
diff_clears_trailing_cell_for_wide_graphemeverifies that symbol changes DO trigger updates - This fix complements that behavior by ensuring style-only changes do NOT trigger updates
-
e6b71f2 (build) Correct rust-toolchain->rust-version on cargo-deny-action by @sermuns in #2471
closes #2470
-
43bbaae (clippy) Fix beta clippy errors by @Logan-Ruf in #2433
Noticed these errors on my other PR and figured I could just fix them real quick.
closes #2432
-
957fbb0 (core) Use correct width for halfwidth dakuten/handakuten by @orhun in #2499
unicode-width reports U+FF9E/U+FF9F as zero-width, but terminals render them as 1 cell. Adjusts
CellWidthtrait accordingly for fixing this behavior.fixes #2188
-
d7646c7 (core) Avoid overflow in BufferDiff forced-width advance by @joshka in #2487
Motivation
- Prevent arithmetic overflow when advancing
self.posforCellDiffOption::ForcedWidth(NonZeroU16)inratatui-core/src/buffer/diff.rs, which could panic in debug or wrap in release and cause an iterator hang/DoS.
Description
- Replace the unchecked
self.pos += width.get().saturating_sub(1)with a saturating addition viaself.pos = self.pos.saturating_add(width.get().saturating_sub(1) as usize)to avoid overflow while preserving existing iterator semantics.
Testing
- Ran
cargo test -p ratatui-core buffer::diff --liband the buffer diff tests completed successfully (10 passed, 0 failed).
- Prevent arithmetic overflow when advancing
-
77f8006 (core) Avoid cursor position queries during resize by @orhun in #2485
Terminal::resize()now clears without callingget_cursor_position(), so that CPR (Cursor position report) calls does not interfere with stdin.Fixes #2483
-
18aa467 (examples) Make line-gauge example compatible with macos sequoia's terminal.app by @lazo4 in #2474
Part of the fix for #1972
Summary
This fix makes the
line-gaugeexample compatible with the macos sequoia Terminal.app which doesn't support truecolor. It reuses theis_true_color_supportedintroduced in #2211 by @ffex and uses a color theme instead of hardcoding the colors.Result on macos sequoia
Before: <img width="566" height="138" alt="Capture d’écran 2026-04-06 à 11 47 07" src="https://github.com/user-attachments/assets/1ea37832-8a07-40b0-b0ab-aa77476ef9eb" /> After: <img width="561" height="120" alt="Capture d’écran 2026-04-06 à 11 46 45" src="https://github.com/user-attachments/assets/4bd50bc1-68f9-4601-b361-f610abf8629d" />
Notes
This is my first open source contribution, thanks to @ffex for letting me help on this issue
-
ce2c228 (examples) Change flex example colors for MacOS default terminal by @ffex in #2211
Part of the fix for #1972
Summary
This fix introduces a function to check if we are in a terminal without truecolor(24-bit) and changes the default colors to appear fine of the flex example.
Notes
The function "is_true_color_supported” is an old problem and there is no common way to determine if a terminal supports or not the truecolor.
This is the main reason why the function detects specifically the Terminal.app version before the Tahoe. If there are other known terminals with this problem, we can add it to this function.
-
ef72dba (examples) Fix import for widget examples by @orhun in #2422
closes #2299
-
88441cf (terminal) Fix inline viewport resizing issues by clearing the screen by @wyvernbw in #2355
adds a check to the autoresize function to clear the entire screen and move the inline viewport to the top when the window shrinks horizontally in order to avoid line wrapping issues.
Other libraries like ink purge the history as well, but the
backend::ClearTypetype does not support that. Without this if the user scrolls up they will see previous broken renders. This should work well with all terminal emulators and multiplexers.fixes #2086
-
91b6fb7 (tests) Use the correct type for the cell diff test by @orhun in #2472
fixes the CI!
-
4493742 (widgets) Handle single y-axis label by @fallintoplace in #2550
Fixes #2549.
This prevents
Chartfrom panicking when the Y axis is configured with exactly one label. The X-axis rendering path already skips label placement when fewer than two labels are provided; this applies the same guard to Y-axis labels before the spacing calculation divides bylabels_len - 1.This also updates the
Axis::labelsdocs so they describe the newbehavior:fewer than two labels are not rendered instead of causing a panic.
-
0bdebd6 (widgets) Prevent chart scaling overflow by @fallintoplace in #2546
Summary
Fixes #2545.
This changes BarChart and Sparkline scaling to use a
u128intermediate before division, then caps the scaled ticks at the drawable area. That prevents debug-build panics and release-build wrapping when publicu64chart values are large.Validation
cargo test -p ratatui-widgets barchart::testscargo test -p ratatui-widgets sparkline::testscargo check -p ratatui-widgets --all-featurescargo clippy -p ratatui-widgets --all-targets --all-features -- -D warningscargo test -p ratatui-widgets
-
e27a22a (widgets) Inherit the text alignment for Paragraph by @7Bpencil in #2369
Paragraph didn't take into account alignment of the text it was created from:
let lines = vec![ Line::from("one"), Line::from("double"), Line::from("quadruple"), ]; let text = Text::from(lines).centered(); // used to be rendered left-aligned, now centered let paragraph = Paragraph::new(text).block(block);Now the Paragraph inherits the text alignment.
-
b5c0831 (widgets) Avoid panic if Clear area is outside of buffer by @7Bpencil in #2368
If Clear area is at least partially outside of buffer, panic "index outside of buffer" happens on Widget::render
<details>
<summary>Demo source code</summary>
use crossterm::event::{self, Event, KeyModifiers}; use ratatui::{ layout::Rect, text::Line, widgets::{Block, Borders, Clear, Paragraph}, DefaultTerminal, Frame, }; use std::iter; fn main() { ratatui::run(app); } fn app(terminal: &mut DefaultTerminal) { loop { if let Event::Key(key_event) = event::read().expect("failed to read event") { if key_event.kind.is_press() && key_event.modifiers.contains(KeyModifiers::CONTROL) && key_event.code.is_char('c') { break; } } terminal.draw(render).expect("failed to draw frame"); } } fn render(frame: &mut Frame) { { let width = frame.area().width; let area = Rect::new(0, 0, width, 10); let line = Line::from("W".repeat(area.width as usize)); let lines: Vec<Line> = iter::repeat_n(line, area.height as usize).collect(); frame.render_widget(Paragraph::new(lines), area); } { let area = Rect::new(50, 2, 20, 5); let block = Block::default() .title_top(Line::from("Popup-with-Clear").centered()) .borders(Borders::ALL); let lines = vec![ Line::from("one"), Line::from("double"), Line::from("quadruple"), ]; frame.render_widget(Clear, area); frame.render_widget(Paragraph::new(lines).block(block).centered(), area); } { let area = Rect::new(80, 2, 20, 5); let block = Block::default() .title_top(Line::from("Popup").centered()) .borders(Borders::ALL); let lines = vec![ Line::from("one"), Line::from("double"), Line::from("quadruple"), ]; frame.render_widget(Paragraph::new(lines).block(block).centered(), area); } }</details>
Before the fix:
https://github.com/user-attachments/assets/cebae1df-87b2-48ae-9456-7ad8cb72035c
After the fix:
https://github.com/user-attachments/assets/9e0170f3-9c71-4a28-96b3-3f4b7db8ed37
-
1ce29d6 (uncategorized) Decouple std from serde and palette features by @december1981 in #2460
The std feature now passes through to the deps rather than requiring std to use serde / palette.
-
2a0b4b2 (uncategorized) Ensure consistent thumb size when scrolling by @kdheepak in #2352
This PR removes the use of
f64for calculating scrollbar thumb size and uses integer rounding (rounding up instead of the default rounding down) instead. Using integer rounding seems to fix the problem of thumb size not being consistent.Fixes #2351
-
4986b28 (uncategorized) Allow ratatui-widgets to be used without default features by @jakobhellermann in #2350
Previously, ratatui-widgets was always included with default features.
Additionally, the
stdfeature would always enable thetimecrate.Fixing this gets rid of a few crates:
deranged,num-conv,time-core,time. -
720303e (uncategorized) Align clear() semantics with contract by @joshka in #2320
-
d2b0ce1 (uncategorized) Fix the dependency on time by @asomers in #2306
ratatui-widgets uses time's Month::length(), which requires time-0.3.37 or later.
Refactor
-
d754c5e (app) Simplify render function in the scrollbar example by @marianomarciello in #2388
Divide the render function into two functions for vertical and horizontal scroll.
-
629e4b2 (core) Reintroduce
Cell::skipas a deprecated field by @junkdog in #2437as discussed in https://github.com/ratatui/ratatui/pull/1605#discussion_r2933338973 - this brings back
Cell::skipas a deprecated field in order to avoid breaking the API in a patch release. in terms of noise; the diff() is left pretty intact, but had to#[allow(deprecated)]in a couple of places.Cell::skipvsCellDiffOptionCellDiffOption::ForcedWidthtakes precedence overCell::skip, andCellDiffOption::skipis already skip - soCell::skipcan only override whenCellDiffOption::Noneis set. i believe this is the correct behavior, but probably good to have another pair of eyes on it. @benjajaja maybe has some input too.PartialEq and Hash for
Cell::skipCell::skipis part ofPartialEqandHashas normal fields. another option would be to treatCellDiffOption::NoneasCellDiffOption::SkipwhenCell::skipis set, and only consider the effectiveCellDiffOptionfor the trait impls.
-
ca5c109 (core) Introduce
CellWidthtrait for cell width computation by @junkdog in #2400this PR introduces a
CellWidthtrait for calculating the cell width/span, implemented for&strandCell.The impl for
Cellrespects the newCellDiffOption::ForcedWidth. All width calculations are prefixed with a check if the symbol is ascii before callingsymbol.width(); this micro-optimization probably won't do much on computers, but it helps on embedded.As discussed recently in #1605, this also changes the `CellDiffOption::ForcedWidth(type) from NonZeroUsize to NonZeroU16.
-
9ac167d (style) Add descriptive panic for Color::Reset anstyle conversion by @singhh-piyush in #2423
Color::Resethas no equivalent inanstyle::Color. Previously, convertingColor::Reset.into()fell through to the catch-all arm inFrom<Color> for anstyle::Color, which calledAnsiColor::try_from(color).unwrap()and panicked with the message:called Result::unwrap() on an Err value: Ansi.This replaces the opaque
unwrap()with an explicit, immediately understandable panic:"Color::Reset has no equivalent in anstyle".Fixes #2341
-
f093b02 (uncategorized) Satisfy beta Clippy buffer debug lint by @joshka in #2562
Remove a redundant borrow in
Buffer'sDebugimplementation
Documentation
-
f8b42ad (breaking-changes) Update header for 0.30.0 by @orhun in #2295
-
e82b3b7 (buffer) Run the doctests for Buffer by @orhun in #2319
addresses https://github.com/ratatui/ratatui/pull/2314#pullrequestreview-3621576941
the doctest was not running at all... (due to
fn foo) -
d8c86c3 (canvas) Add usage example for Line widget by @ramadhan-dev-bright in #2473
Added a doc-tested example for the Line struct in canvas to improve documentation and help new users understand how to render lines with color.
-
83c1579 (changelog) Fix doubled words in two entries by @adv0r in #2578
Typo:
in in→inandand and→andinCHANGELOG.md -
fff27e8 (contributing) Add packages needed to run xtasks by @alabhyajindal in #2409
Fixes #2408
-
be718d0 (ratatui-core) Fix terminal rendering grammar by @Zacxxx in #2555
-
095b47d (ratatui-crossterm) Fix doubled article in module docs by @adv0r in #2564
Dear maintainer — AI-authored PR by Composer under @adv0r. Methodology + opt-out at tokens-for-good. A one-line "no thanks" → auto-apology + auto-close + permanent blacklist. Silent close treated the same. Your time matters more than this contribution.
Typo:
See the the [Examples]→See the [Examples]inratatui-crossterm/src/lib.rs. -
160b177 (ratatui-termwiz) Fix doubled article in module docs by @adv0r in #2565
Dear maintainer — AI-authored PR by Composer under @adv0r. Methodology + opt-out at tokens-for-good. A one-line "no thanks" → auto-apology + auto-close + permanent blacklist. Silent close treated the same. Your time matters more than this contribution.
Typo:
See the the [Examples]→See the [Examples]inratatui-termwiz/src/lib.rs. -
8ce5513 (sparkline) Fix typo in doc comment by @adv0r in #2554
-
e6529fd (terminal) Improve terminal and setup docs for app authors by @joshka in #2461
Summary
This updates the terminal and setup docs to better match the rendering behavior Ratatui actually implements, while also making the docs.rs path clearer for application authors.
The main docs changes are split into two commits:
docs: align terminal docs with behavior
- align
Terminal, viewport, frame, and flush docs with the real render pipeline- clarify the boundary between
Terminal::flushandBackend::flush - improve examples for fullscreen, inline, and fixed viewport usage
- clarify the boundary between
docs: improve terminal docs for app authors
- improve setup-path guidance across
ratatui,ratatui-core, and backend crates- clarify viewport choice, escape hatches, and common edge cases
- reduce duplication so crate-level docs explain choices while method docs hold detailed contracts
A small follow-up also fixes the crate-doc heading hierarchy in
ratatui-coreandratatui-crosstermso the generated READMEs no longer needmarkdownlint-disable-next-line heading-incrementsuppressions.Verification
cargo test -p ratatui --doccargo test -p ratatui-core --doccargo test -p ratatui-crossterm --doccargo test -p ratatui-termion --doccargo test -p ratatui-termwiz --doccargo test --workspace --all-targets --no-runcargo doc -p ratatui --no-depscargo doc -p ratatui-core --no-depscargo xtask format --checkcargo xtask readme --check
Note:
cargo doc -p ratatui-core --no-depsstill reports pre-existing warnings outside this pass inlayoutandtextdocs. The terminal-doc warnings introduced during this work were fixed.
-
744dc36 (uncategorized) Remove duplicate word in color and backend module by @lphuc2250gma in #2535
Two one-line typo fixes for duplicated "the" in doc-comments:
ratatui-core/src/style/color.rs— "/// the the older serialization implementation of Color are also able to be deserialized." → "...the older serialization..."ratatui-core/src/backend.rs— "//! See the the [Examples] directory for more examples." → "//! See the [Examples] directory for more examples."
No code/behavior change.
-
3df8c20 (uncategorized) Ask issue authors about PR willingness by @joshka in #2317
Add a contribution question to the bug report and feature request templates so maintainers know whether the reporter wants to work on a fix/PR or needs guidance.
-
53d925a (uncategorized) Add Documentation on the Map Projection / CRS by @C-Loftus in #2324
-
64d964b (uncategorized) Update Terminal docs by @joshka in #2312
Summary
- Improve
TerminalRustdocs to better explain typical app setup, the rendering pipeline, and how diff-based rendering works (including full redraw behavior on viewport size changes). - Clarify viewport concepts and behavior in
Viewport/Terminaldocs, with a more complete inline section (anchoring, scrolling, resize behavior). - Reorder
Terminal::draw/Terminal::try_drawcloser to constructors so the primary rendering entry points are easier to find.
Notes
- Docs-only change; no public API or runtime behavior changes.
- No new tests in this PR.
Test Plan
cargo +nightly fmtcargo +nightly docs-rs -p ratatui-corecargo test -p ratatui-core --doc --features std
- Improve
-
8d73d47 (uncategorized) Fix comment to reflect correct symbol in assertion by @homebrewmellow in #2314
-
fbd5621 (uncategorized) Fix misspellings by @cgzones in #2310
Performance
-
dcea52b (core) Eliminate per-frame Vec allocation in Terminal::flush by @junkdog in #2416
what and how
this PR removes the
Vec<(u16, u16, &Cell)>allocation inTerminal::flushwhen callingBuffer::diff. a new method,Buffer::diff_iteris instead used byTerminal::flush.the existing diff implementation has moved to the
BufferDiffiterator.why (who cares?)
it's the mice. on embedded devices, allocating a short-lived, contiguous block of up to 40-50kb is problematic due to heap fragmentation in combination with tiny heaps. the requirements for a full refresh over 1200 terminal cells is 37.5kb+vec growth padding, but since we're dealing with a contiguous block of memory, the actual memory requirements are considerably higher, depending on user-land allocation patterns.
Testing
-
b696ea3 (core) Split
Terminalinto submodules and expand test coverage by @joshka in #2315- Split the
Terminalimplementation into focused submodules to improve readability and maintainability. - Add characterization tests covering
Terminalinitialization, buffer lifecycle, resizing and autoresize behavior, and rendering paths. - Add inline viewport tests for
compute_inline_sizeandinsert_beforein both fallback and scrolling-regions modes, including an end-to-enddraw -> insert_before -> draw scenarioscenario. - Extend
TestBackendcursor plumbing to support the new terminal tests and assert cursor/ behavior.
- Split the
Miscellaneous Tasks
-
746e9c9 (build) Add symlinks from each crate dir to root LICENSE by @martinvonz in #2370
AFAICT, each crate directory must have its own LICENSE file for it to become part of the published crate. This patch therefore adds LICENSE symlinks from each crate directory to the root LICENSE file. This matches what e.g. clap does (https://github.com/clap-rs/clap).
Since ratatui-macros/LICENSE already exists and with different copyright holders than in the root LICENSE file, I left it unchanged.
-
7b66bd4 (ci) Use latest released cargo-machete action by @sermuns in #2469
-
b6dfafd (markdown) Fix linting issues reported by xtask lint by @Logan-Ruf in #2435
-
fba4448 (ratatui) Unleash the rats v0.30.1
-
0b03fe4 (toml) Migrate from taplo to tombi by @joshka in #2501
Summary
This migrates the repo's TOML tooling from Taplo to Tombi.
The main motivation is maintenance and installability:
- Ratatui previously used Taplo for TOML formatting.
- Taplo's maintenance future has been uncertain; see https://github.com/tamasfe/taplo/issues/715.
- Taplo's current release artifacts are not friendly to
cargo-binstall, which means some setups fall back to building from source. - That source-build path is awkward for CI and was also a blocker while exploring a future Docker/devcontainer setup because of image size and install cost.
Tombi is actively maintained, publishes prebuilt binaries, and has a VS Code extension that lets us keep editor behavior aligned with CI.
What Changed
Tooling and CI
- Replace
taplowithtombiincargo xtask format. - Use
tombi-toml/setup-tombiin the formatting CI job. - Replace
.taplo.tomlwithtombi.toml.
Formatting policy
- Keep the existing 100-column TOML line width.
- Disable schema-driven top-level table ordering for
Cargo.toml. - Disable the corresponding
tables-out-of-orderlint forCargo.toml.
Why disable Cargo schema ordering:
- Tombi can order keys and tables according to schema metadata; see https://tombi-toml.github.io/tombi/docs/comment-directive/tombi-value-directive/#format-rules-table-keys-order.
- The schema order moved sections like
[features]below dependency sections. - That made feature-gated behavior harder to scan.
- It also created noisy migration churn that was not central to the tool switch itself.
Why disable the Cargo lint warning:
- The VS Code warning came from Tombi's
tables-out-of-orderlint rather than from formatting. - Since we are intentionally preserving the existing Cargo manifest
section order, we also disable that lint for
Cargo.tomlto keep diagnostics aligned with the formatter configuration. - Related docs: https://tombi-toml.github.io/tombi/docs/configuration/.
Installation note
- Tombi is better positioned for binary installs than Taplo today, but
it is still not fully in the generic
cargo-binstall/taiki-e/install-actionpath. - Relevant upstream context:
- binary naming / generic installer compatibility: https://github.com/tombi-toml/tombi/issues/1164
- crates.io publishing for
cargo-binstallfallback: https://github.com/tombi-toml/tombi/issues/1686 - earlier crates.io publishing discussion: https://github.com/tombi-toml/tombi/issues/632
- In practice, this still leaves some rough edges around the generic Rust installer path, but Tombi already has usable prebuilt binaries and an official installer action, which is a better place for Ratatui than Taplo's current install story.
- CI now uses
tombi-toml/setup-tombiwith a pinned version, which avoids the GitHub token path by not asking the action to resolvelatestat runtime.
Docs and editor setup
- Update contributor docs to point to Tombi's repo, docs, and installation guide.
- Note that the repo previously used Taplo and link the upstream maintenance discussion at https://github.com/tamasfe/taplo/issues/715.
- Add VS Code extension recommendations for
rust-lang.rust-analyzerandtombi-toml.tombi. - Add committed VS Code workspace settings for shared repo defaults, mainly so the workspace can define formatter behavior that matches CI, including TOML formatter selection and nightly rustfmt args.
- Add a dedicated formatting section to
CONTRIBUTING.mdcovering Rust formatting, TOML formatting, nightlyrustfmt, and the VS Code workspace override workaround.
Why Commit VS Code Settings
This PR adds committed VS Code workspace settings for shared repo defaults only.
The goal is to:
- recommend the expected extensions
- make local editor formatting behave more like CI
- avoid formatter drift between editor usage and the repo's checked-in tooling
This is not intended to standardize everyone's full editor setup.
Nightly rustfmt
The repo already uses unstable rustfmt options in
rustfmt.toml, so formatting Rust code withcargo xtask formatworks best with nightly Rust. This is already how CI behaves.The docs now call this out more clearly:
- install nightly if you want local formatting to match CI
- the reason is to pick up the unstable formatting options configured in
rustfmt.toml
For contributors who cannot or do not want to install nightly, the docs also point to a workaround: use a personal VS Code workspace file with override settings instead of changing the tracked workspace config.
Notes From Implementation
- Tombi
v0.9.19added config support to disable schema-defined ordering per schema, which let us preserve existingCargo.tomlsection order cleanly. - The
tables-out-of-orderwarning seen in VS Code came from Tombi lint, not formatting, so that needed a separate config change. - After disabling Cargo section ordering, the remaining TOML churn was much smaller and mostly mechanical.
Files of Interest
.github/workflows/ci.ymlxtask/src/commands/format.rstombi.toml.vscode/settings.json.vscode/extensions.jsonCONTRIBUTING.md
Verification
cargo xtask format --checkcargo metadata --format-version 1markdownlint-cli2 CONTRIBUTING.md
-
ed46fef (uncategorized) Update versions
-
f30bab9 (uncategorized) Ignore licker as typo
-
c7746e9 (uncategorized) Bump MSRV to 1.88.0 by @orhun in #2396
-
b0a7703 (uncategorized) Escape usernames in changelog with backticks by @kdheepak in #2377
This PR escapes all github usernames in the CHANGELOG.md file by adding a backtick before and after the username.
e.g.:Before
1dc18bf (calendar) Add width and height functions by @joshka in #2198After
1dc18bf (calendar) Add width and height functions by `@joshka` in #2198This change should prevent unnecessary tags in PRs and forks, at least until the next release is made with git cliff changes from release-plz
-
0031fc6 (uncategorized) Remove
@sign from github release and PR by @kdheepak in #2353Previous PR (https://github.com/ratatui/ratatui/pull/2336) didn't solve the problem, and everyone still seems to be getting notifications (e.g. https://github.com/ratatui/ratatui/pull/2348).
This PR removes the
@for GitHub usernames in the autogenerated PR body byrelease-plz.{{ changelog | replace(from=" by @", to=" by ") }}The motivation behind this is that GitHub mentions in PR descriptions trigger notifications for every contributor for every release because their username is part of the changelog.
With this change, in GitHub PR descriptions the changelog will change like so:
Before
1dc18bf (calendar) Add width and height functions by @joshka in #2198After
1dc18bf (calendar) Add width and height functions by joshka in #2198 -
ab5ad3f (uncategorized) Escape username using backticks in changelog by @kdheepak in #2336
The motivation behind this is that GitHub mentions in PR descriptions trigger notifications for every contributor for every release because their username is part of the changelog.
New Contributors
- @musjj made their first contribution in #2566
- @adv0r made their first contribution in #2578
- @fallintoplace made their first contribution in #2550
- @Zacxxx made their first contribution in #2555
- @lphuc2250gma made their first contribution in #2535
- @lazo4 made their first contribution in #2474
- @Metbcy made their first contribution in #2520
- @bananaofhappiness made their first contribution in #2426
- @sermuns made their first contribution in #2469
- @ramadhan-dev-bright made their first contribution in #2473
- @junkdog made their first contribution in #2437
- @december1981 made their first contribution in #2460
- @7Bpencil made their first contribution in #2369
- @JayanAXHF made their first contribution in #2438
- @Logan-Ruf made their first contribution in #2435
- @singhh-piyush made their first contribution in #2423
- @gcavelier made their first contribution in #2308
- @ffex made their first contribution in #2211
- @BenFradet made their first contribution in #2356
- @wyvernbw made their first contribution in #2355
- @NoOPeEKS made their first contribution in #2371
- @alabhyajindal made their first contribution in #2409
- @martinvonz made their first contribution in #2370
- @jakobhellermann made their first contribution in #2350
- @floor-licker made their first contribution in #2322
- @C-Loftus made their first contribution in #2324
- @0xferrous made their first contribution in #2323
- @homebrewmellow made their first contribution in #2314
- @karkhaz made their first contribution in #2150
-
-
0.30.026 Dec 2025Release notes
Open source →"Rats don't just survive; they discover; they create. ... I mean, just look at what they do with the terminal!" – Remy & Orhun
We are excited to announce the biggest release of
ratatuiso far - a Rust library that's all about cooking up TUIs 👨🍳🐀🌠 Added "no_std" support for embedded targets, modularized architecture, major widget & layout upgrades!
✨ Release highlights: https://ratatui.rs/highlights/v030/
⚠️ List of breaking changes can be found here.
Features
-
90a77aa (direction) Add
Direction::perpendicular(self)by@b-guildin #2197 -
56d5e05 (bar) Update label and text_value to accept Into<> by
@Emivvvvvin #1471 [breaking]BREAKING CHANGE:label and text_value now accept
Into<>types, which breaks type inference.- Bar::default().label("foo".into()); + Bar::default().label("foo");- Bar::default().text_value("bar".into()); + Bar::default().text_value("bar"); -
b76ad3b (bar) Impl Styled for Bar by
@Emivvvvvin #1476Related:https://github.com/ratatui/ratatui/issues/683
-
e15fefa (barchar) Add BarChart::grouped constructor by
@joshkain #1513Add a new constructor to the
BarChartwidget that allows creating a grouped barchart with multiple groups of bars.Also add a new constructor to the
BarGroupwidget that allows creating a group of bars with a label. -
369b18e (barchart) Reduce barchart creation verbosity by
@Emivvvvvin #1453Adds constructor methods for BarChart, BarGroup, and Bar
-
1dc18bf (calendar) Add width and height functions by
@joshkain #2198Fixes https://github.com/ratatui/ratatui/issues/2016
-
f18bcbf (canvas) Add quadrant, sextant and octant markers by
@sbarralin #2235 [breaking]The octant marker is an alternative to the Braille marker with the same resolution, but offering densely packed, regular pseudo-pixels, without visible bands between rows and columns.
Quadrant and Sextants are also added to support 2x2 and 2x3.
Sextant and Octant unicode characters that are less widely supported at the moment, which is why
Braillewas left as the default.BREAKING CHANGE:addition of new variants to
Markerand removal of no longer used constants inratatui::symbols::braille. -
26b05de (chart) Render Braille over Blocks in Charts and Canvas by
@j-g00dain #2165This makes it possible to stack charts, and write text over block symbols in Charts and Canvas while still showing the block symbols behind the text.
-
bf84c62 (core) Add a
has_modifier()method toStyleby@sxyaziin #2267Resolves https://github.com/ratatui/ratatui/issues/2264
-
2d713d7 (crossterm) Allow multiple crossterm versions by
@joshkain #1841This commit introduces feature flags to make it possible for widget library authors to depend on a specific version of crossterm without causing version conflicts. This should make it easier for libraries and apps to update crossterm versions more easily.
The available feature flags are
crossterm_0_28andcrossterm_0_29. By default, the latest version is enabled. If a multiple features are enabled we choose the latest version. We will in general support at least the last two major (0.x) versions of crossterm, and will only remove versions in a major version bump. -
d99984f (layout) Add
Flex::SpaceEvenlyby@kdheepakin #1952 [breaking]Resolves https://github.com/ratatui/ratatui/issues/1951
BREAKING CHANGE:Old
Flex::SpaceAroundbehavior is available by usingFlex::SpaceEvenlyand newFlex::SpaceAroundnow distributes space evenly around each element except the middle spacers are twice the size of first and last elementsWith this change, the following variants of
Flexare supported:Flex::Start: Aligns items to the start; excess space appears at the end.Flex::End: Aligns items to the end; excess space appears at the start.Flex::Center: Centers items with equal space on both sides.Flex::SpaceAround(new): Distributes space around items; space between items is twice the edge spacing.Flex::SpaceBetween: Distributes space evenly between items except no space at the edges.Flex::SpaceEvenly(previouslyFlex::SpaceAround): Distributes space evenly between items and edges.Flex::Legacy: Preserves legacy behavior, placing all excess space at the end.
This aligns behavior of
Flexwith CSS flexbox more closely.The following is a screenshot in action:
<img width="1090" alt="image"
src="https://github.com/user-attachments/assets/2c7cd797-27bd-4242-a824-4565d369227b" />
-
9275d34 (layout) Add Offset::new() constructor by
@joshkain #1547 -
7ad9c29 (linegauge) Customized symbols by
@sectorein #1601With this PR any symbol (
&str) can be used to renderfilledandunfilledparts ofLineGaugenow. Before that change, onlysymbols::line::Setwas accepted.Note:New methods are introduced to define those symbols:
filled_symbolandunfilled_symbol. The methodline_setis still there, but marked asdeprecated. -
92a19cb (list) Highlight symbol styling by
@airblast-devin #1595 [breaking]Allow styling for
List's highlight symbolThis change makes it so anything that implements
Into<Line>can be used as a highlight symbol.BREAKING CHANGE:
List::highlight_symbolcan no longer be used in const contextBREAKING CHANGE:
List::highlight_symbolaccepted&str. Conversion methods that rely on type inference will need to be rewritten as the compiler cannot infer the type.closes:https://github.com/ratatui/ratatui/issues/1443
-
e89a526 (no_std) Portable-atomic integration for targets with no atomic types by
@j-g00dain #2076Improves compatibility with no-std targets that don't support atomic types.
We support three different scenarios depending on the target:
- Terminal applications and other std targets (e.g. espidf):
stdenabled,portable-atomicdisabled
- Embedded targets with atomic types, bare metal x86, etc.:
stddisabledportable-atomicdisabled
- Embedded targets without atomic types (e.g. single-core MCUs):
stddisabled,portable-atomicenabled
Turning on
portable-atomictogether withstdwill fall back tostdatomic. -
1399d95 (no_std) Make palette and serde features depends on std by
@j-g00dain #1919 -
b32f781 (no_std) Make
ratatui-macrosno-std by@j-g00dain #1865 -
3e1c72f (no_std) Make ratatui compatible with
#![no_std]by@j-g00dain #1794 [breaking]Resolves #1781
This PR makes it possible to compile ratatui with
#![no_std]. Also makes me answer "We Are So Embedded" to "Are We Embedded Yet?" -
ab48c06 (no_std) Option to disable layout cache for
no_stdcompatibility by@j-g00dain #1795 [breaking]Resolves #1780
BREAKING CHANGE:Disabling
default-featureswill now disable layout cache, which can have a negative impact on performance.Layout::init_cacheandLayout::DEFAULT_CACHE_SIZEare now only available iflayout-cachefeature is enabled. -
09173d1 (no_std) Make
TestBackend::ErrorInfallibleby@j-g00dain #1823 [breaking]BREAKING CHANGE:
TestBackendnow usescore::convert::Infalliblefor error handling instead ofstd::io::Error -
007713e (no_std) Replace
Backend'sio::Errorusages with associatedErrortype by@j-g00dain #1778 [breaking]Resolves #1775
BREAKING CHANGE:Custom backends now have to implement
Backend::ErrorandBackend::clear_region. Additionally some genericBackendusage will have to explicitly set trait bounds forBackend::Error. -
a42a17e (no_std) Make
ratatui-widgetsno_stdby@j-g00dain #1779Resolves #1776
-
5a232a3 (no_std) Remove redundant
stdusages inratatui-widgetsby@j-g00dain #1762 -
ebe10cd (no_std) Remove redundant
stdusages inratatui-coreby@j-g00dain #1753Resolves https://github.com/ratatui/ratatui/issues/1751
-
08b08cc (rect) Centering by
@janTatesain #1814Resolves #617
-
ff729b7 (scrollbar) Support retrieving the current position of state by
@orhunin #1552As of now it is possible to change the position of the Scrollbar but not possible to retrieve the position for further use. e.g.
let mut state = ScrollbarState::default(); state.next();This commit adds a new method "
current_position" (sincepositionis already taken by the fluent setter) for that purpose:let index = state.get_position(); // yaySee #1545 for the concrete usage of this.
-
4c3c054 (serde) Handle null modifiers in serde Style by
@joshkain #2172Allow
Style'sadd_modifierandsub_modifierfields to deserialize fromnull -
b9da192 (serde) Derive Serialize/Deserialize for alignment enums by
@j-g00dain #1957Resolves #1954
-
89b7421 (serde) Derive Serialize/Deserialize for additional structs/enums by
@aurrelandin #1883This PR adds
#[derive(Serialize, Deserialize)]to the following structs:ConstraintDirectionSpacingLayoutAccentedPaletteNonAccentedPalettePalettePaddingBordersBorderTypeListDirectionScrollbarOrientationScrollDirectionRenderDirectionHighlightSpacing
Fixes #1877
-
03f3f6d (style) Allow add/sub modifiers to be omitted in Style serialization. by
@rcorrein #2057It's really useful that Style supports Deserialize, this allows TUI apps to have configurable theming without much extra code.
However, deserializing a style currently fails if
add_modifierandsub_modifierare not specified. That means the following TOML config:[theme.highlight] fg = "white" bg = "black"Will fail to deserialize with "missing field
add_modifier". It should be possible to omit modifiers and have them default to "none". -
ee67347 (symbols) Make
Markernon-exhaustive by@j-g00dain #2236 [breaking]This will allow us to add new markers without causing further breaking changes.
BREAKING CHANGE:
Markeris now non-exhaustive -
985cd05 (symbols) Add dashed borders by
@theotchlxin #1573Adds several new border sets:
- ratatui::symbols::border::LIGHT_DOUBLE_DASHED
- ratatui::symbols::border::HEAVY_DOUBLE_DASHED
- ratatui::symbols::border::LIGHT_TRIPLE_DASHED
- ratatui::symbols::border::HEAVY_TRIPLE_DASHED
- ratatui::symbols::border::LIGHT_QUADRUPLE_DASHED
- ratatui::symbols::border::HEAVY_QUADRUPLE_DASHED
And corresponding variants to the ratatui::widgets::BorderType enum
Fixes:https://github.com/ratatui/ratatui/issues/1355
-
4c301e8 (text) Implement
AddAssignforTextby@acuteenvyin #1956This makes it possible to add a second
Textinstance to a first one using the += operator.let mut text = Text::from("line 1"); text += Text::from("line 2");Style and alignment applied to the second text is ignored (though styles and alignment of lines and spans are copied).
-
ce4856a (widgets) Add the missing constructor to canvas types by
@orhunin #1538Allows constructing
Rectangle,PointsandCircleusing thenewmethod instead of initializing with the public fields directly. -
22610b0 (uncategorized) Support adding an Offset to Position by
@joshkain #2239Adds Position::offset() and arithmetic ops (Position + Offset and Position - Offset)
Fixes:https://github.com/ratatui/ratatui/issues/2018
-
24e3133 (uncategorized) Add Rect::resize() method by
@joshkain #2240Fixes:https://github.com/ratatui/ratatui/issues/1440
-
96d097e (uncategorized) Implement Rect ops for moving by
@joshkain #1596feat:implement Rect ops for moving
Implemented
Add,AddAssign,Sub, andSubAssignonRectforOffset. This makes it possible to move rectslet rect = Rect::new(1, 2, 3, 4); let moved = rect + Offset(1, 2); let moved = rect - Offset(1, 2); let moved = rect + Offset(-1, -2);Additionally Rect, Size, Offset, and Position now all have MIN and MAX consts.
-
e869cb9 (uncategorized) Add Size::area() by
@joshkain #2226Add Size::area() returning u32 to avoid u16 overflow Fixes https://github.com/ratatui/ratatui/issues/2204
-
b6588fd (uncategorized) Implement
From<Size>for(u16, u16)by@0xb002f0in #2223 -
75b78be (uncategorized) Add width() impl for tabs by
@joshkain #2049The purpose of this is to make it easy for apps to easily calculate the total tab width including all dividers and padding.
-
8188ed3 (uncategorized) Implement UnicodeWidthStr for Text/Line/Span by
@joshkain #2030You can now calculate the width of any Text/Line/Span using the UnicodeWidthStr trait instead of the width method on the type. This also makes it possible to use the width_cjk() method if needed.
-
c845fec (uncategorized) Add conversion from Size to Rect by
@joshkain #2028Rect::from(size)returns a new Rect at the origin (0, 0) with the specifiedSize -
017af11 (uncategorized) Preserve block titles when merging borders by
@j-g00dain #1977Resolves #1939
-
6dcd53b (uncategorized) Add ergonomic methods for layouting Rects by
@joshkain #1909This commit introduces new methods for the
Rectstruct that simplify the process of splitting aRectinto sub-rects according to a givenLayout. By putting these methods on theRectstruct, we make it a bit more natural that a layout is applied to theRectitself, rather than passing aRectto theLayoutstruct to be split.Adds:-
Rect::layoutandRect::try_layoutmethods that allow splitting aRectinto an array of sub-rects according to a givenLayout.Rect::layout_vecmethod that returns aVecof sub-rects.Layout::try_areasmethod that returns an array of sub-rects, with compile-time checks for the number of constraints. This is added mainly for consistency with the newRectmethods.
use ratatui_core::layout::{Layout, Constraint, Rect}; let area = Rect::new(0, 0, 10, 10); let layout = Layout::vertical([Constraint::Fill(1); 2]); // Rect::layout() infers the number of constraints at compile time: let [top, main] = area.layout(&layout); // Rect::try_layout() and Layout::try_areas() do the same, but return a // Result: let [top, main] = area.try_layout(&layout)?; let [top, main] = layout.try_areas(area)?; // Rect::layout_vec() returns a Vec of sub-rects: let areas_vec = area.layout_vec(&layout); // you can also explicitly specify the number of constraints: let areas = area.layout::<2>(&layout); let areas = area.try_layout::<2>(&layout)?; let areas = layout.try_areas::<2>(area)?; -
0c3872f (uncategorized) Add Rect::outer() by
@joshkain #1929Fixes:https://github.com/ratatui/ratatui/issues/211
-
7bc78bc (uncategorized) Add ratatui::run() method by
@joshkain #1707This introduces a new
ratatui::run()method which runs a closure with a terminal initialized with reasonable defaults for most applications. This callsratatui::init()before running the closure andratatui::restore()after the closure completes, and returns the result of the closure.A minimal hello world example using the new
ratatui::run()method:fn main() -> Result<(), Box<dyn std::error::Error>> { ratatui::run(|terminal| { loop { terminal.draw(|frame| frame.render_widget("Hello World!", frame.area()))?; if crossterm::event::read()?.is_key_press() { break Ok(()); } } }) }Of course, this also works both with apps that use free methods and structs:
fn run(terminal: &mut DefaultTerminal) -> Result<(), AppError> { ... } ratatui::run(run)?;struct App { ... } impl App { fn new() -> Self { ... } fn run(mut self, terminal: &mut DefaultTerminal) -> Result<(), AppError> { ... } } ratatui::run(|terminal| App::new().run(terminal))?; -
b6fbfcd (uncategorized) Add lifetime to symbol sets by
@joshkain #1935This makes it possible to create symbol sets at runtime with non-static lifetimes.
Fixes:https://github.com/ratatui/ratatui/issues/1722
-
488e5f0 (uncategorized) Make
border!work without importingBordersby@j-g00dain #1918Currently using
border!macro requires explicit import ofBorderswhich is unnecessary. -
671c2b4 (uncategorized) Support merging the borders of blocks by
@j-g00daWhen two borders overlap, they will automatically merge into a single, clean border instead of overlapping.
This improves visual clarity and reduces rendering glitches around corners.
For example:
assert_eq!(Cell::new("┘").merge_symbol("┏", MergeStrategy::Exact).symbol(), "╆"); -
702fff5 (uncategorized) Implement stylize methods directly on Style by
@joshkain #1572 [breaking]This makes it possible to create constants using the shorthand methods.
const MY_STYLE: Style = Style::new().blue().on_black();Rather than implementing Styled for Style and then adding extension methods that implement the Stylize shorthands, this implements the methods as const functions directly on Style.
BREAKING CHANGE:
Styleno longer implementsStyled. Any calls to methods implemented by the blanket implementation of Stylize are now defined directly on Style. Remove the Stylize import if it is no longer used by your code.The
reset()method does not have a direct replacement, as it clashes with the existingreset()method. UseStyle::reset()rather thansome_style.reset()Fixes:#1158
-
4fcd238 (uncategorized) Support no-std for calendar widget by
@joshkain #1852Removes the CalendarEventStore::today() function in no-std environments
-
53cdbbc (uncategorized) Enable serde propagation to backend crates (crossterm, termion) by
@ArjunKrish7356in #1812This PR propagates the serde feature from the main ratatui crate to the ratatui-crossterm and ratatui-termion backend crates. Solves #1805
-
6836a69 (uncategorized) Implement styled for other primitives by
@ascheyin #1684 -
fcb47d6 (uncategorized) Rename Alignment to HorizontalAlignment and add VerticalAlignment by
@joshkain #1735 [breaking]We don't anticipate removing or deprecating the type alias in the near future, but it is recommended to update your imports to use the new name.
Added a VerticalAlignment enum to make the API more consistent. We don't have a specific use case for it yet, but it's better to add it now and be able to use it in the future.
BREAKING-CHANGE:The
Alignmentenum has been renamed toHorizontalAlignmentto better reflect its purpose. A type alias has been added to maintain backwards compatibility, however there are some cases where type aliases are not enough to maintain backwards compatibility. E.g. when using glob imports to import all the enum variants. This should not affect most users, but it is recommended to update your imports to use the new name.- use ratatui::layout::Alignment; + use ratatui::layout::HorizontalAlignment; - use Alignment::*; + use HorizontalAlignment::*; -
2714d6b (uncategorized) Add array and tuple RGB color conversion methods by
@joshkain #1703Other crates (e.g. colorgrad) that deal with colors can convert colors to a tuple of 3 or 4 u8 values. This commit adds conversion methods from these types to a
Color::Rgbinstance. Any alpha value is ignored.Color::from([255, 0, 0]); Color::from((255, 0, 0)); Color::from([255, 0, 0, 255]); Color::from((255, 0, 0, 255)); -
50ba965 (uncategorized) Add a new RatatuiMascot widget by
@Its-Just-Nansin #1584Move the Mascot from Demo2 into a new widget. Make the Rat grey and adjust the other colors.
frame.render_widget(RatatuiMascot::default(), frame.area()); -
1d28c89 (uncategorized) Add conversions for anstyle by
@joshkain #1581https://crates.io/crates/anstyle makes it possible to define colors in an interoperable way. This makes it possible for applications to easily load colors from a variety of formats.
This is gated by the anstyle feature flag which is disabled by default.
Bug Fixes
-
a89d3d6 (buffer) Clear behavior with VS16 wide emojis by
@nornagonin #2063This fixes a bug where certain emojis like ⌨️ would sometimes be "overlaid" onto existing content from the buffer, instead of properly clearing.
This PR was generated by Codex, and validated by me:
- Behavior of the above example code was buggy before this fix (showed overlaying "b" on top of the keyboard emoji), and fixed after.
- The U+FE0F check is not strictly required, but I did note that emoji without this char don't exhibit the buggy behavior, even without the fix.
-
ec30390 (canvas) Round coordinates to nearest grid cell by
@joshkain #1507Previously the canvas coordinates were rounded towards zero, which causes the rendering to be off by one pixel in some cases. It also meant that pixels at the extreme edges of the canvas can only be drawn if the point was exactly on the edge of the canvas. This commit rounds the coordinates to the nearest integer instead. This may change the output for some apps using Canvas / Charts.
-
afd1ce1 (canvas) Lines that start outside the visible grid are now drawn by
@renesatin #1501Previously lines with points that were outside the canvas bounds were not drawn at all. Now they are clipped to the bounds of the canvas so that the portion of the line within the canvas is draw.
To facilitate this, a new
Painter::bounds()method which returns the bounds of the canvas is added.Fixes:https://github.com/ratatui/ratatui/issues/1489
-
2b0a044 (ci) Add contents write permission to release-plz PR by
@marcoieniin #2119https://release-plz.dev/docs/github/quickstart#3-setup-the-workflow
Fixes https://github.com/release-plz/release-plz/issues/2439
-
18e70d3 (crossterm) Terminal should keep Bold when removing Dim by
@MarSikin #1541The Dim removal should behave the same as the logic for Bold removal that sends NormalIntensity sequence and then restores Dim when needed.
-
16b76e3 (demo) Update the width of demo2 tape by
@orhunin #2164fixes #1721
-
dca331c (demo) Support tab key in demo2 example by
@orhunin #1726see #1721
Not sure what caused this - it's been there for a while probably and we didn't realize it since we used
demo2-destroymostly. -
0fd4753 (examples) Run the correct example for chart by
@orhunin #1679fixes #1678
-
39479e2 (examples) Ensure that example projects are not published by
@orhunin #1672 -
9314312 (layout) Feature flag cache related types by
@joshkain #1842 -
2dd1977 (layout-cache) Import
NonZeroUsizeonly whenlayout-cacheis enabled by@j-g00dain #1839This silences unused import warning, when
layout-cacheis disabled. -
564a9d7 (line-gauge) Pad default label to display 3 numbers by
@martinetdin #2053Display the default label of the LineGauge widget padded to fill 3 cells. This makes it so that the label doesn't shift around when going from a single digit to double / triple digits.
To maintain the existing behavior, use a custom label by calling
.label()on the LineGauge. -
a692a6e (lint) Apply rust 1.84 clippy suggestions by
@joshkain #1612The canvas map constants are now statics instead. Fixes https://rust-lang.github.io/rust-clippy/master/index.html#large_const_arrays
-
2e54d5e (macros) Use $crate re-export in text macro by
@airblast-devin #1832 -
79d5165 (no_std) Propagate
stdfeature flag to dependencies by@j-g00dain #1838Disables
stdfeature flags in dependencies and only enables them withratatuiandratatui-core'sstdfeature flag. This partially fixes the issue of still depending onstd, whenstdfeature flag is disabled. -
00da8c6 (no_std) Provide
f64polyfills forno_stdcompatibility by@j-g00dain #1840Related:https://github.com/rust-lang/rust/issues/137578
-
3b13240 (scrollbar) Check for area.is_empty() before rendering by
@farmeroyin #1529This adds the
area.is_empty()back into the scrollbar render method. Without it, the widget panics if the height is 0. -
f57b696 (span) Dont render control characters by
@EdJoPaToin #1312 -
2ce958e (table) Allow display of additional table row, if row height > 1 by
@Lunderbergin #1452 -
0a25bc1 (tests) Update the stderr snapshot for ratatui-macros by
@orhunin #2161New 🦀 broke the CI
-
5fa342c (widgets) Fix centered block title truncation by
@ognis1205in #1973Previously block titles that were aligned center were truncated poorly (aligned to the left, and the last non-fitting title would be truncated on the left and right. This now truncates the titles more obviously centered.
-
f919b25 (uncategorized) String_to_string lint is now part of implicit_clone by
@joshkain #2173 -
1fe64de (uncategorized) Include underline color in anstyle conversion by
@ascheyin #2004Underline color wasn't included in the style conversion logic.
-
c1b8528 (uncategorized) Panic when rendering widgets on too small buffer by
@j-g00dain #1996Fixes panic on overflow on horizontal
BarchartandRatatuiMascotand adds proper tests to all widgets.
-
08b21fa (uncategorized) Fix panic when rendering a
Paragraphout of bounds by@jwodderin #1670Fixes #1667.
-
80bc818 (uncategorized) Fix truncation of left aligned block titles by
@joshkain #1931truncate the right side of left aligned titles rather than the left side of right aligned titles. This is more obvious as the left side of text often contains more important information. And we generally read left to right.
This change makes centered titles overwrite left aligned titles and right aligned titles overwrite centered or left aligned titles.
Fixes:https://github.com/ratatui/ratatui/issues/358
-
21e3b59 (uncategorized) Fix handling of multi-byte chars in bar chart by
@joshkain #1934The split_at method requires that the split point is at a valid utf8 character boundary.
Fixes:https://github.com/ratatui/ratatui/issues/1928
-
e1e4004 (uncategorized) Derive copy for list state by
@janTatesain #1921 -
12cb5a2 (uncategorized) Allow canvas area to exceed u16::MAX by
@Daksh14in #1891This allows Canvas grids where the width * height exceeds u16::MAX by converting values to usize earlier in several methods.
Fixes:https://github.com/ratatui/ratatui/issues/1449
-
09cc9ef (uncategorized) Typo in changelog by
@joshkain #1857 -
c238aca (uncategorized)
padding_right()should set right padding instead of left by@sxyaziin #1837Fixes https://github.com/ratatui/ratatui/issues/1836
-
c90ba97 (uncategorized) Avoid unnecessary imports in minimal build by
@cgzonesin #1787core::ops::Range is only used with the feature
scrolling-regions. Ensure a minimalcargo checkreports no warnings. -
416ebdf (uncategorized) Correct clippy errors introduced by rust 1.86.0 update by
@j-g00dain #1755New version of rust (1.86.0) caused CI to fail.
-
4eac5b2 (uncategorized) Make deprecation notes more helpful by
@joshkain #1702AI coding assistants use the deprecation notes to automatically suggest fixes. This commit updates the deprecation notes to push those tools to suggest the correct replacement methods and types.
Specifically, AI tools often suggest using
Buffer::get(x, y), because of their training data where this was prevalent. When fixing these deprecations, they often incorrectly suggest usingBuffer::get(x, y)instead ofBuffer[(x, y)]. -
35a8642 (uncategorized)
Rect::positions()should be empty when width is 0 and height is nonzero by@jwodderin #1669Fixes #1666.
-
f5fc819 (uncategorized) Avoid extra line break on whitespace only lines when wrapping paragraphs by
@dotdashin #1636Currently whitespace only lines produces an extra line break when trimming is disabled, because both the trimmed as well as the non-trimmed line get inserted. Fix this by only inserting the non-trimmed one.
-
2892bdd (uncategorized) Rust 1.83 clippy lints by
@joshkain #1527https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
-
36e2d1b (uncategorized) Add feature(doc_cfg) when generating docs by
@joshkain #1506 -
4d7704f (uncategorized) Make StatefulWidget and Ref work with unsized State by
@thscharlerin #1505StatefulWidget::State and StatefulWidgetRef::State are now ?Sized.
This allows implementations of the traits to use unsized types for the State associated type. This is turn is useful when doing things like boxing different stateful widget types with State which implements
Any, are slices or any other dynamically sized type.
Refactor
-
8d60e96 (examples) Use crossterm event methods by
@joshkain #1792Crossterm 0.29 introduced methods to easily check / extract the event type. E.g. as_key_press_event() and is_key_press(). This commit updates the examples to use these methods instead of matching on the event type. This makes the code cleaner and easier to read.
Also does a general cleanup of the event handling code in the examples.
-
07bec55 (no_std) Make usages of std explicit in ratatui-core. by
@ed-2100in #1782This commit does the following:
- Adds
#[no_std]tolib.rs. - Adds
extern crate std;tolib.rs. - Updates
ratatui-coreto explicitlyuseitems from std and alloc. - Prefers
use-ing alloc over std when possible.
Explanation:
This allows usages of
stdinratatui-coreto be clearly pointed out and dealt with individually.Eventually, when
stdis to be feature gated, the associated commit will be much cleaner. - Adds
-
f132fa1 (table) Small readability improvements by
@joshkain #1510 -
c7c3498 (uncategorized) Use saturating_add in Rect::new by
@pharrison31415in #2216 -
02e53de (uncategorized) Make use of iter::repeat_n() by
@cgzonesin #1788Applied via clippy --fix. Available since 1.82.0.
-
a195d59 (uncategorized) Move xtask commands to small modules by
@joshkain #1620 -
904b0aa (uncategorized) Move symbols to modules by
@joshkain #1594 -
7c8573f (uncategorized) Rearrange selection_spacing code by
@rayluin #1540 -
217c57c (uncategorized) Modularize backends by
@orhunin #1508Backend code is now moved to
ratatui-crossterm,ratatui-termionandratatui-termwiz. This should be backwards compatible with existing code. -
e461b72 (uncategorized) Move {Stateful,}Widget{,Ref} types into individual files by
@joshkain #1479This is a preparatory refactoring for modularization. No user visible changes.
Documentation
-
40e96a2 (block) Add collapsed border example by
@joshkain #1899 -
d291042 (block) Revise the block example by
@orhunin #1520- Moves the block example from
ratatuitoratatui-widgets - Simplifies the example (bordered, styled, custom borders)
see #1512
- Moves the block example from
-
0951da5 (breaking-changes) Improve migration guide for
Backend::Errorby@j-g00dain #1908Related:https://github.com/fujiapple852/trippy/pull/1588
-
bbe1cf9 (breaking-changes) Change MSRV to 1.85 by
@j-g00dain #1896The minimum supported Rust version is now for
ratatuiv0.30 is 1.85 -
c7912f3 (breaking-changes) Fix header level by
@j-g00dain #1825 -
73488ab (contributing) Fix link to
widgets_block_renderstest by@ognis1205in #2101The
CONTRIBUTING.mdreferencedtests/widgets_block.rs, but the correct path isratatui/tests/widgets_block.rs. Updated the link so that readers can navigate to the test example without 404 error.
-
1197b2a (contributing) Add note about using nightly for formatting by
@joshkain #1816 -
3ae6bf1 (contributing) Use cargo-xtask for instructions by
@orhunin #1509- Updates
CONTRIBUTING.mdabout the usage ofxtask - Removes
Makefile.toml
- Updates
-
22e3e84 (core) Remove link to Paragraph widget by
@orhunin #1683 -
b65788c (examples) Remove duplicated link by
@matthiasbeyerin #2212 -
200b217 (examples) Add VHS tapes and docs for widget examples by
@orhunin #2114fixes #1982
Later on I'll figure out an easy way to regenerate this in the CI and possibly do the same for the app examples' VHS tapes. That's why I haven't added a script or mentioned anything in the docs yet (hint: #1721)
-
861fbdf (examples) Fix a typo by
@j-g00dain #1890Makes CI typos check pass again
-
882cc3c (examples) Update app examples with tapes by
@orhunin #1673 -
4393fae (examples) Move scrollbar example to examples folder by
@orhunin #1665 -
9ea70e2 (examples) Move widget-impl example to examples folder by
@orhunin #1663 -
774ab78 (examples) Move widget-ref-container example to examples folder by
@orhunin #1664see #1512
-
910d16e (examples) Move user-input example to examples folder by
@orhunin #1659 -
dbfb7da (examples) Move table example to examples folder by
@orhunin #1657 -
cb2a58a (examples) Move tracing example to examples folder by
@orhunin #1658 -
7e00b64 (examples) Move panic example to examples folder by
@orhunin #1655 -
8127590 (examples) Move modifiers example to examples folder by
@orhunin #1654 -
7c40c0b (examples) Move popup example to examples folder by
@orhunin #1656see #1512
-
d87354f (examples) Move list example to examples folder by
@orhunin #1653see #1512
also renames it to todo-list
-
621226f (examples) Move inline example to examples folder by
@orhunin #1651 -
9ba7d25 (examples) Move hyperlink example to examples folder by
@orhunin #1650 -
bb94d1c (examples) Move minimal example to examples folder by
@orhunin #1649 -
9f399ac (examples) Move gauge example to examples folder by
@orhunin #1646 -
104d6a6 (examples) Move custom-widget example to examples folder by
@orhunin #1644 -
fa8ca01 (examples) Move flex example to examples folder by
@orhunin #1642 -
f5fde0e (examples) Move constraints example to examples folder by
@orhunin #1641 -
fc70288 (examples) Move constraint-explorer example to examples folder by
@orhunin #1640 -
325f961 (examples) Move hello-world example to examples folder by
@orhunin #1647 -
867c4bc (examples) Move colors-rgb example to examples folder by
@joshkain #1582- docs: move colors-rgb example to examples folder
- docs: update main examples README
-
72334ed (layout) Update documentation to point to
kasuarisolver by@a-kenjiin #2003 -
2be9ccb (layout) Remove unnecessary path prefix by
@j-g00dain #1766 -
b669ceb (layout) Change
cassowarytokasuaricrate reference by@j-g00dain #1765 -
f907c74 (license) Update copyright years by
@LVivonain #1639Update MIT Licence to copyright year 2025
-
68b9f67 (readme) Add
Built with Ratatuibadge for downstream projects by@harilvfsin #1905 -
6e43672 (readme) Reimagine README.md by
@orhunin #1569This is the result of the re-imagination of a more suitable README.md. It is simpler and shorter: not giving more information to the user than they actually need.
Also updates the quickstart code with the up-to-date version and adds link to templates which was missing.
-
8f28247 (readme) Correct examples links by
@HoKim98in #1484 -
260af68 (readme) Include iocraft as an alternative by
@kdheepakin #1483 -
8e5151f (rect) Fix typo in the Rect::outer function comments by
@orhunin #2123 -
40f13c6 (rect) Update the outdated comment for Rect::area() by
@isgin01in #2100The return value of Rect.area() is no longer of u16 type, and the value is not being clumped anymore.
-
9a930a6 (terminal) Made usage of Terminal::get_frame() clearer by
@Blaerizin #2071Closes : https://github.com/ratatui/ratatui/issues/1200
-
b08b4cb (terminal) Add disclaimer
-
-
0.30.0-beta.123 Dec 2025 pre-releaseNothing published for this version
-
0.30.0-beta.031 Oct 2025 pre-releaseNothing published for this version
-
0.30.0-alpha.530 Jun 2025 pre-releaseNothing published for this version
-
0.30.0-alpha.419 May 2025 pre-releaseNothing published for this version
-
0.30.0-alpha.313 May 2025 pre-releaseNothing published for this version
-
0.30.0-alpha.201 Mar 2025 pre-releaseNothing published for this version
-
0.30.0-alpha.115 Jan 2025 pre-releaseNothing published for this version
-
0.30.0-alpha.027 Nov 2024 pre-releaseNothing published for this version
-
0.29.1-alpha.026 Oct 2024 pre-releaseNothing published for this version
-
0.29.021 Oct 2024Release notes
Open source →"Food will come, Remy. Food always comes to those who love to cook." – Gusteau
We are excited to announce the new version of
ratatui- a Rust library that's all about cooking up TUIs 👨🍳🐀✨ Release highlights: https://ratatui.rs/highlights/v029/
⚠️ List of breaking changes can be found here.
Features
-
4c4851c (example) Add drawing feature to the canvas example by
@orhunin #1429fun fact: I had to do 35 pushups for this...
-
e5a7609 (line) Impl From<Cow<str>> for Line by
@joshkain #1373 [breaking]BREAKING-CHANGES:
Linenow implementsFrom<Cow<str>As this adds an extra conversion, ambiguous inferred values may no longer compile.
// given: struct Foo { ... } impl From<Foo> for String { ... } impl From<Foo> for Cow<str> { ... } let foo = Foo { ... }; let line = Line::from(foo); // now fails due to ambiguous type inference // replace with let line = Line::from(String::from(foo));Fixes:https://github.com/ratatui/ratatui/issues/1367
-
2805ddd (logo) Add a Ratatui logo widget by
@joshkain #1307This is a simple logo widget that can be used to render the Ratatui logo in the terminal. It is used in the
examples/ratatui-logo.rsexample, and may be used in your applications' help or about screens.use ratatui::{Frame, widgets::RatatuiLogo}; fn draw(frame: &mut Frame) { frame.render_widget(RatatuiLogo::tiny(), frame.area()); } -
d72968d (scrolling-regions) Use terminal scrolling regions to stop Terminal::insert_before from flickering by
@nfachanin #1341 [breaking]The current implementation of Terminal::insert_before causes the viewport to flicker. This is described in #584 .
This PR removes that flickering by using terminal scrolling regions (sometimes called "scroll regions"). A terminal can have its scrolling region set to something other than the whole screen. When a scroll ANSI sequence is sent to the terminal and it has a non-default scrolling region, the terminal will scroll just inside of that region.
We use scrolling regions to implement insert_before. We create a region on the screen above the viewport, scroll that up to make room for the newly inserted lines, and then draw the new lines. We may need to repeat this process depending on how much space there is and how many lines we need to draw.
When the viewport takes up the entire screen, we take a modified approach. We create a scrolling region of just the top line (could be more) of the viewport, then use that to draw the lines we want to output. When we're done, we scroll it up by one line, into the scrollback history, and then redraw the top line from the viewport.
A final edge case is when the viewport hasn't yet reached the bottom of the screen. This case, we set up a different scrolling region, where the top is the top of the viewport, and the bottom is the viewport's bottom plus the number of lines we want to scroll by. We then scroll this region down to open up space above the viewport for drawing the inserted lines.
Regardless of what we do, we need to reset the scrolling region. This PR takes the approach of always resetting the scrolling region after every operation. So the Backend gets new scroll_region_up and scroll_region_down methods instead of set_scrolling_region, scroll_up, scroll_down, and reset_scrolling_region methods. We chose that approach for two reasons. First, we don't want Ratatui to have to remember that state and then reset the scrolling region when tearing down. Second, the pre-Windows-10 console code doesn't support scrolling region
This PR:
- Adds a new scrolling-regions feature.
- Adds two new Backend methods: scroll_region_up and scroll_region_down.
- Implements those Backend methods on all backends in the codebase.
- The crossterm and termion implementations use raw ANSI escape sequences. I'm trying to merge changes into those two projects separately to support these functions.
- Adds code to Terminal::insert_before to choose between insert_before_scrolling_regions and insert_before_no_scrolling_regions. The latter is the old implementation.
- Adds lots of tests to the TestBackend to for the scrolling-region-related Backend methods.
- Adds versions of terminal tests that show that insert_before doesn't clobber the viewport. This is a change in behavior from before.
-
dc8d058 (table) Add support for selecting column and cell by
@airblast-devin #1331 [breaking]Fixes https://github.com/ratatui-org/ratatui/issues/1250
Adds support for selecting a column and cell in
TableState. The selected column, and cells style can be set byTable::column_highlight_styleandTable::cell_highlight_stylerespectively.The table example has also been updated to display the new functionality:
https://github.com/user-attachments/assets/e5fd2858-4931-4ce1-a2f6-a5ea1eacbecc
BREAKING CHANGE:The Serialized output of the state will now include the "selected_column" field. Software that manually parse the serialized the output (with anything other than the
Serializeimplementation onTableState) may have to be refactored if the "selected_column" field is not accounted for. This does not affect users who rely on theDeserialize, orSerializeimplementation on the state.BREAKING CHANGE:The
Table::highlight_styleis now deprecated in favor ofTable::row_highlight_style.
-
ab6b1fe (tabs) Allow tabs to be deselected by
@joshkain #1413 [breaking]Tabs::select()now acceptsInto<Option<usize>>instead ofusize. This allows tabs to be deselected by passingNone.Tabs::default()is now also implemented manually instead of derivingDefault, and a new methodTabs::titles()is added to set the titles of the tabs.Fixes:https://github.com/ratatui/ratatui/pull/1412
BREAKING CHANGE:
Tabs::select()now acceptsInto<Option<usize>>which breaks any code already using parameter type inference:let selected = 1u8; - let tabs = Tabs::new(["A", "B"]).select(selected.into()) + let tabs = Tabs::new(["A", "B"]).select(selected as usize) -
23c0d52 (text) Improve concise debug view for Span,Line,Text,Style by
@joshkain #1410Improves https://github.com/ratatui/ratatui/pull/1383
The following now round trips when formatted for debug. This will make it easier to use insta when testing text related views of widgets.
Text::from_iter([ Line::from("Hello, world!"), Line::from("How are you?").bold().left_aligned(), Line::from_iter([ Span::from("I'm "), Span::from("doing ").italic(), Span::from("great!").bold(), ]), ]).on_blue().italic().centered() -
60cc15b (uncategorized) Add support for empty bar style to
Sparklineby@fujiapple852in #1326 [breaking]- distinguish between empty bars and bars with a value of 0
- provide custom styling for empty bars
- provide custom styling for individual bars
- inverts the rendering algorithm to be item first
Closes:#1325
BREAKING CHANGE:
Sparkline::datatakesIntoIterator<Item = SparklineBar>instead of&[u64]and is no longer const -
453a308 (uncategorized) Add overlap to layout by
@kdheepakin #1398 [breaking]This PR adds a new feature for the existing
Layout::spacingmethod, and introducing aSpacingenum.Now
Layout::spacingis generic and can take- zero or positive numbers, e.g.
Layout::spacing(1)(current functionality) - negative number, e.g.
Layout::spacing(-1)(new) - variant of the
Spacing(new)
This allows creating layouts with a shared pixel for segments. When
spacing(negative_value)is used, spacing is ignored and all segments will be adjacent and have pixels overlapping.spacing(zero_or_positive_value)behaves the same as before. These are internally converted toSpacing::OverlaporSpacing::Space.Here's an example output to illustrate the layout solve from this PR:
#[test] fn test_layout() { use crate::layout::Constraint::*; let mut terminal = crate::Terminal::new(crate::backend::TestBackend::new(50, 4)).unwrap(); terminal .draw(|frame| { let [upper, lower] = Layout::vertical([Fill(1), Fill(1)]).areas(frame.area()); let (segments, spacers) = Layout::horizontal([Length(10), Length(10), Length(10)]) .flex(Flex::Center) .split_with_spacers(upper); for segment in segments.iter() { frame.render_widget( crate::widgets::Block::bordered() .border_set(crate::symbols::border::DOUBLE), *segment, ); } for spacer in spacers.iter() { frame.render_widget(crate::widgets::Block::bordered(), *spacer); } let (segments, spacers) = Layout::horizontal([Length(10), Length(10), Length(10)]) .flex(Flex::Center) .spacing(-1) // new feature .split_with_spacers(lower); for segment in segments.iter() { frame.render_widget( crate::widgets::Block::bordered() .border_set(crate::symbols::border::DOUBLE), *segment, ); } for spacer in spacers.iter() { frame.render_widget(crate::widgets::Block::bordered(), *spacer); } }) .unwrap(); dbg!(terminal.backend()); }┌────────┐╔════════╗╔════════╗╔════════╗┌────────┐ └────────┘╚════════╝╚════════╝╚════════╝└────────┘ ┌─────────┐╔════════╔════════╔════════╗┌─────────┐ └─────────┘╚════════╚════════╚════════╝└─────────┘Currently drawing a border on top of an existing border overwrites it. Future PRs will allow for making the border drawing handle overlaps better.
- zero or positive numbers, e.g.
-
7bdccce (uncategorized) Add an impl of
DoubleEndedIteratorforColumnsandRowsby@fujiapple852[breaking]BREAKING-CHANGE:The
pubmodifier has been removed from fields on thelayout::rect::Columnsandlayout::rect::Rowsiterators. These fields were not intended to be public and should not have been accessed directly.Fixes:#1357
Bug Fixes
-
4f5503d (color) Hsl and hsluv are now clamped before conversion by
@joshkain #1436 [breaking]The
from_hslandfrom_hsluvfunctions now clamp the HSL and HSLuv values before converting them to RGB. This ensures that the input values are within the expected range before conversion.Also note that the ranges of Saturation and Lightness values have been aligned to be consistent with the palette crate. Saturation and Lightness for
from_hslare now in the range [0.0..1.0] whilefrom_hsluvare in the range [0.0..100.0]. -
b7e4885 (color) Fix doc test for from_hsl by
@joshkain #1421 -
3df685e (rect) Rect::area now returns u32 and Rect::new() no longer clamps area to u16::MAX by
@joshkain #1378 [breaking]This change fixes the unexpected behavior of the Rect::new() function to be more intuitive. The Rect::new() function now clamps the width and height of the rectangle to keep each bound within u16::MAX. The Rect::area() function now returns a u32 instead of a u16 to allow for larger areas to be calculated.
Previously, the Rect::new() function would clamp the total area of the rectangle to u16::MAX, by preserving the aspect ratio of the rectangle.
BREAKING CHANGE:Rect::area() now returns a u32 instead of a u16.
-
514d273 (terminal) Use the latest, resized area when clearing by
@roberthin #1427 -
0f48239 (terminal) Resize() now resizes fixed viewports by
@Patryk27in #1353Terminal::resize()on a fixed viewport used to do nothing due to an accidentally shadowed variable. This now works as intended. -
a52ee82 (text) Truncate based on alignment by
@Lunderbergin #1432This is a follow-up PR to https://github.com/ratatui/ratatui/pull/987, which implemented alignment-aware truncation for the
Linewidget. However, the truncation only checked theLine::alignmentfield, and any alignment inherited from a parent'sText::alignmentfield would not be used.This commit updates the truncation of
Lineto depend both on the individualLine::alignment, and on any alignment inherited from the parent'sText::alignment. -
611086e (uncategorized) Sparkline docs / doc tests by
@joshkain #1437 -
b9653ba (uncategorized) Prevent calender render panic when terminal height is small by
@adrodgersin #1380Fixes:#1379
-
da821b4 (uncategorized) Clippy lints from rust 1.81.0 by
@fujiapple852in #1356 -
68886d1 (uncategorized) Add
unstable-backend-writerfeature by@Patryk27in #1352https://github.com/ratatui/ratatui/pull/991 created a new unstable feature, but forgot to add it to Cargo.toml, making it impossible to use on newer versions of rustc - this commit fixes it.
Refactor
-
6db16d6 (color) Use palette types for Hsl/Hsluv conversions by
@orhunin #1418 [breaking]BREAKING-CHANGE:Previously
Color::from_hslaccepted components as individual f64 parameters. It now accepts a singlepalette::Hslvalue and is gated behind apalettefeature flag.- Color::from_hsl(360.0, 100.0, 100.0) + Color::from_hsl(Hsl::new(360.0, 100.0, 100.0))Fixes:https://github.com/ratatui/ratatui/issues/1414
-
edcdc8a (layout) Rename element to segment in layout by
@kdheepakin #1397This PR renames
elementtosegmentin a couple of functions in the layout calculations for clarity.elementcan refer tosegments orspacers and functions that take onlysegments should usesegmentas the variable names. -
1153a9e (uncategorized) Consistent result expected in layout tests by
@farmeroyin #1406Fixes #1399 I've looked through all the
assert_eqand made sure that they follow theexpected, resultpattern. I wasn't sure if it was desired to actually pass result and expected as variables to the assert_eq statements, so I've left everything that seems to have followed the pattern as is. -
20c88aa (uncategorized) Avoid unneeded allocations by
@mo8itin #1345
Documentation
-
b13e2f9 (backend) Added link to stdio FAQ by
@Valentin271in #1349 -
b88717b (constraint) Add note about percentages by
@joshkain #1368 -
381ec75 (readme) Reduce the length by
@joshkain #1431Motivation for this is that there's a bunch of stuff at the bottom of the Readme that we don't really keep up to date. Instead it's better to link to the places that we do keep this info.
-
4728f0e (uncategorized) Tweak readme by
@joshkain #1419 -
4069aa8 (uncategorized) Fix missing breaking changes link by
@joshkain #1416 -
870bc6a (uncategorized) Use
Frame::area()instead ofsize()in examples by@hosseinnedaeein #1361Frame::size()is deprecated
Performance
Styling
Miscellaneous Tasks
- 67c0ea2 (block) Deprecate block::Title by
@joshkain #1372ratatui::widgets::block::Titleis deprecated in favor of usingLineto represent titles. This removes an unnecessary layer of wrapping (string -> Span -> Line -> Title).This struct will be removed in a future release of Ratatui (likely 0.31). For more information see:
https://github.com/ratatui/ratatui/issues/738
To update your code:
Block::new().title(Title::from("foo")); // becomes any of Block::new().title("foo"); Block::new().title(Line::from("foo")); Block::new().title(Title::from("foo").position(Position::TOP)); // becomes any of Block::new().title_top("foo"); Block::new().title_top(Line::from("foo")); Block::new().title(Title::from("foo").position(Position::BOTTOM)); // becomes any of Block::new().title_bottom("foo"); Block::new().title_bottom(Line::from("foo"));-
6515097 (cargo) Check in Cargo.lock by
@joshkain #1434When kept up to date, this makes it possible to build any git version with the same versions of crates that were used for any version, without it, you can only use the current versions. This makes bugs in semver compatible code difficult to detect.
The Cargo.lock file is not used by downstream consumers of the crate, so it is safe to include it in the repository (and recommended by the Rust docs).
See:- https://doc.rust-lang.org/cargo/faq.html#why-have-cargolock-in-version-control
- https://blog.rust-lang.org/2023/08/29/committing-lockfiles.html
- https://github.com/rust-lang/cargo/issues/8728
-
c777beb (ci) Bump git-cliff-action to v4 by
@orhunin #1350See:https://github.com/orhun/git-cliff-action/releases/tag/v4.0.0
-
69e0cd2 (deny) Allow Zlib license in cargo-deny configuration by
@orhunin #1411 -
bc10af5 (style) Make Debug output for Text/Line/Span/Style more concise by
@joshkain #1383Given:```rust
Text::from_iter([ Line::from("without line fields"), Line::from("with line fields").bold().centered(), Line::from_iter([ Span::from("without span fields"), Span::from("with span fields") .green() .on_black() .italic() .not_dim(), ]), ])
Debug:``` Text [Line [Span("without line fields")], Line { style: Style::new().add_modifier(Modifier::BOLD), alignment: Some(Center), spans: [Span("with line fields")] }, Line [Span("without span fields"), Span { style: Style::new().green().on_black().add_modifier(Modifier::ITALIC).remove_modifier(Modifier::DIM), content: "with span fields" }]]Fixes: https://github.com/ratatui/ratatui/issues/1382
-
f6f7794 (uncategorized) Remove leftover prelude refs / glob imports from example code by
@joshkain #1430 -
9fd1bee (uncategorized) Make Positions iterator fields private by
@joshkain #1424 [breaking]BREAKING CHANGE:The Rect Positions iterator no longer has public fields. The
rectandcurrent_positionfields have been made private as they were not intended to be accessed directly. -
c32baa7 (uncategorized) Add benchmark for
Tableby@airblast-devin #1408 -
5ad623c (uncategorized) Remove usage of prelude by
@joshkain #1390This helps make the doc examples more explicit about what is being used. It will also makes it a bit easier to do future refactoring of Ratatui, into several crates, as the ambiguity of where types are coming from will be reduced.
Additionally, several doc examples have been simplified to use Stylize, and necessary imports are no longer hidden.
This doesn't remove the prelude. Only the internal usages.
-
f4880b4 (deps) Pin unicode-width to 0.2.0 by
@orhunin #1403 [breaking]We pin unicode-width to avoid breaking applications when there are breaking changes in the library.
Discussion in #1271
Continuous Integration
- 5635b93 (uncategorized) Add cargo-machete and remove unused deps by
@Veetahain #1362https://github.com/bnjbvr/cargo-machete
New Contributors
@roberthmade their first contribution in #1427@du-obmade their first contribution in #1333@farmeroymade their first contribution in #1406@adrodgersmade their first contribution in #1380@Veetahamade their first contribution in #1362@hosseinnedaeemade their first contribution in #1361@Patryk27made their first contribution in #1352
Full Changelog: https://github.com/ratatui/ratatui/compare/v0.28.1...v0.29.0
-
0.29.0-alpha.019 Oct 2024 pre-releaseNothing published for this version
-
0.28.2-alpha.612 Oct 2024 pre-releaseNothing published for this version
-
0.28.2-alpha.505 Oct 2024 pre-releaseNothing published for this version
-
0.28.2-alpha.428 Sep 2024 pre-releaseNothing published for this version
-
0.28.2-alpha.321 Sep 2024 pre-releaseNothing published for this version
-
0.28.2-alpha.214 Sep 2024 pre-releaseNothing published for this version
-
0.28.2-alpha.107 Sep 2024 pre-releaseNothing published for this version
-
0.28.2-alpha.031 Aug 2024 pre-releaseNothing published for this version
-
0.28.125 Aug 2024Release notes
Open source →Features
-
ed51c4b (terminal) Add ratatui::init() and restore() methods by
@joshkain #1289These are simple opinionated methods for creating a terminal that is useful to use in most apps. The new init method creates a crossterm backend writing to stdout, enables raw mode, enters the alternate screen, and sets a panic handler that restores the terminal on panic.
A minimal hello world now looks a bit like:
use ratatui::{ crossterm::event::{self, Event}, text::Text, Frame, }; fn main() { let mut terminal = ratatui::init(); loop { terminal .draw(|frame: &mut Frame| frame.render_widget(Text::raw("Hello World!"), frame.area())) .expect("Failed to draw"); if matches!(event::read().expect("failed to read event"), Event::Key(_)) { break; } } ratatui::restore(); }A type alias
DefaultTerminalis added to represent this terminal type and to simplify any cases where applications need to pass this terminal around. It is equivalent to:Terminal<CrosstermBackend<Stdout>>We also added
ratatui::try_init()andtry_restore(), for situations where you might want to handle initialization errors yourself instead of letting the panic handler fire and cleanup. Simple Apps should prefer theinitandrestorefunctions over these functions.Corresponding functions to allow passing a
TerminalOptionswith aViewport(e.g. inline, fixed) are also available (init_with_options, andtry_init_with_options).The existing code to create a backend and terminal will remain and is not deprecated by this approach. This just provides a simple one line initialization using the common options.
Bug Fixes
-
aed60b9 (terminal) Terminal::insert_before would crash when called while the viewport filled the screen by
@nfachanin #1329Reimplement Terminal::insert_before. The previous implementation would insert the new lines in chunks into the area between the top of the screen and the top of the (new) viewport. If the viewport filled the screen, there would be no area in which to insert lines, and the function would crash.
The new implementation uses as much of the screen as it needs to, all the way up to using the whole screen.
This commit:
- adds a scrollback buffer to the
TestBackendso that tests can inspect and assert the state of the scrollback buffer in addition to the screen - adds functions to
TestBackendto assert the state of the scrollback - adds and updates
TestBackendtests to test the behavior of the scrollback and the new asserting functions - reimplements
Terminal::insert_before, including adding two new helper functionsTerminal::draw_linesandTerminal::scroll_up. - updates the documentation for
Terminal::insert_beforeto clarify some of the edge cases - updates terminal tests to assert the state of the scrollback buffer
- adds a new test for the condition that causes the bug
- adds a conversion constructor
Cell::from(char)
Fixes:https://github.com/ratatui/ratatui/issues/999
- adds a scrollback buffer to the
-
fdd5d8c (text) Remove trailing newline from single-line Display trait impl by
@LucasPickeringin #1320 -
2fb0b8a (uncategorized) Fix u16 overflow in Terminal::insert_before. by
@nfachanin #1323If the amount of characters in the screen above the viewport was greater than u16::MAX, a multiplication would overflow. The multiply was used to compute the maximum chunk size. The fix is to just do the multiplication as a usize and also do the subsequent division as a usize.
There is currently another outstanding issue that limits the amount of characters that can be inserted when calling Terminal::insert_before to u16::MAX. However, this bug can still occur even if the viewport and the amount of characters being inserted are both less than u16::MAX, since it's dependant on how large the screen is above the viewport.
Fixes #1322
Documentation
-
3631b34 (examples) Add widget implementation example by
@joshkain #1147This new example documents the various ways to implement widgets in Ratatui. It demonstrates how to implement the
Widgettrait on a type, a reference, and a mutable reference. It also shows how to use theWidgetReftrait to render boxed widgets. -
d5477b5 (examples) Use ratatui::crossterm in examples by
@joshkain #1315 -
730dfd4 (examples) Show line gauge in demo example by
@montmorillin #1309 -
9ed85fd (table) Fix incorrect backticks in
TableStatedocs by@airblast-devin #1342 -
6d1bd99 (uncategorized) Minor grammar fixes by
@mattain #1330 -
097ee86 (uncategorized) Remove superfluous doc(inline) by
@EdJoPaToin #1310It's no longer needed since #1260
-
3fdb5e8 (uncategorized) Fix typo in terminal.rs by
@mrjackwillsin #1313
Testing
-
0d5f3c0 (uncategorized) Avoid unneeded allocations in assertions by
@mo8itin #1335A vector can be compared to an array.
Miscellaneous Tasks
-
65da535 (ci) Update release strategy by
@orhunin #1337closes #1232
Now we can trigger point releases by pushing a tag (follow the instructions in
RELEASE.md). This will create a release with generated changelog.There is still a lack of automation (e.g. updating
CHANGELOG.md), but this PR is a good start towards improving that. -
57d8b74 (ci) Use cargo-docs-rs to lint docs by
@joshkain #1318 -
23516bc (uncategorized) Rename ratatui-org to ratatui by
@joshkain #1334All urls updated to point at https://github.com/ratatui
To update your repository remotes, you can run the following commands:
git remote set-url origin https://github.com/ratatui/ratatui
Build
-
0256269 (uncategorized) Simplify Windows build by
@joshkain #1317Termion is not supported on Windows, so we need to avoid building it.
Adds a conditional dependency to the Cargo.toml file to only include termion when the target is not Windows. This allows contributors to build using the
--all-featuresflag on Windows rather than needing to specify the features individually.
New Contributors
@nfachanmade their first contribution in #1329@LucasPickeringmade their first contribution in #1320@montmorillmade their first contribution in #1309
Full Changelog: https://github.com/ratatui/ratatui/compare/v0.28.0...v0.28.1
-
-
0.28.1-alpha.224 Aug 2024 pre-releaseNothing published for this version
-
0.28.1-alpha.117 Aug 2024 pre-releaseNothing published for this version
-
0.28.1-alpha.010 Aug 2024 pre-releaseNothing published for this version
-
0.28.007 Aug 2024Release notes
Open source →"If you are what you eat, then I only want to eat the good stuff." – Remy
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 upgraded to Crossterm 0.28.0, introducing enhanced functionality and performance improvements. New features include GraphType::Bar, lines in bar charts, and enhanced scroll/navigation methods. We have also refined the terminal module and added brand new methods for cursor positions and text operations.
✨ Release highlights: https://ratatui.rs/highlights/v028/
⚠️ List of breaking changes can be found here.
Features
-
8d4a102 (barchart) Allow axes to accept Lines by
@joshkain #1273 [breaking] -
a23ecd9 (buffer) Add Buffer::cell, cell_mut and index implementations by
@joshkain #1084Code which previously called
buf.get(x, y)orbuf.get_mut(x, y)should now use index operators, or be transitioned tobuff.cell()orbuf.cell_mut()for safe access that avoids panics by returningOption<&Cell>andOption<&mut Cell>.The new methods accept
Into<Position>instead ofxandycoordinates, which makes them more ergonomic to use.let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 10)); let cell = buf[(0, 0)]; let cell = buf[Position::new(0, 0)]; let symbol = buf.cell((0, 0)).map(|cell| cell.symbol()); let symbol = buf.cell(Position::new(0, 0)).map(|cell| cell.symbol()); buf[(0, 0)].set_symbol("🐀"); buf[Position::new(0, 0)].set_symbol("🐀"); buf.cell_mut((0, 0)).map(|cell| cell.set_symbol("🐀")); buf.cell_mut(Position::new(0, 0)).map(|cell| cell.set_symbol("🐀"));The existing
get()andget_mut()methods are marked as deprecated. These are fairly widely used and we will leave these methods around on the buffer for a longer time than our normal deprecation approach (2 major release)Addresses part of: https://github.com/ratatui/ratatui/issues/1011
-
afe1534 (chart) Accept
IntoIteratorfor axis labels by@EdJoPaToin #1283 [breaking]BREAKING CHANGES: #1273 is already breaking and this only advances the already breaking part
-
5b51018 (chart) Add GraphType::Bar by
@joshkain #1205 -
f97e07c (frame) Replace Frame::size() with Frame::area() by
@EdJoPaToin #1293Area is the more correct term for the result of this method. The Frame::size() method is marked as deprecated and will be removed around Ratatui version 0.30 or later.
Fixes:https://github.com/ratatui/ratatui/pull/1254#issuecomment-2268061409
-
5b89bd0 (layout) Add Size::ZERO and Position::ORIGIN constants by
@EdJoPaToin #1253 -
b2aa843 (layout) Enable serde for Margin, Position, Rect, Size by
@EdJoPaToin #1255 -
36d49e5 (table) Select first, last, etc to table state by
@robertpsoanein #1198Add select_previous, select_next, select_first & select_last to TableState
Used equivalent API as in ListState
-
3bb374d (terminal) Add Terminal::try_draw() method by
@joshkain #1209This makes it easier to write fallible rendering methods that can use the
?operatorterminal.try_draw(|frame| { some_method_that_can_fail()?; another_faillible_method()?; Ok(()) })?; -
3725262 (text) Add
AddandAddAssignimplementations forLine,Span, andTextby@joshkain #1236This enables:
let line = Span::raw("Red").red() + Span::raw("blue").blue(); let line = Line::raw("Red").red() + Span::raw("blue").blue(); let line = Line::raw("Red").red() + Line::raw("Blue").blue(); let text = Line::raw("Red").red() + Line::raw("Blue").blue(); let text = Text::raw("Red").red() + Line::raw("Blue").blue(); let mut line = Line::raw("Red").red(); line += Span::raw("Blue").blue(); let mut text = Text::raw("Red").red(); text += Line::raw("Blue").blue(); line.extend(vec![Span::raw("1"), Span::raw("2"), Span::raw("3")]); -
c34fb77 (text) Remove unnecessary lifetime from ToText trait by
@joshkain #1234 [breaking]BREAKING CHANGE:The ToText trait no longer has a lifetime parameter. This change simplifies the trait and makes it easier implement.
-
c68ee6c (uncategorized) Add
get/set_cursor_position()methods to Terminal and Backend by@EdJoPaToin #1284 [breaking]The new methods return/accept
Into<Position>which can be either a Position or a (u16, u16) tuple.backend.set_cursor_position(Position { x: 0, y: 20 })?; let position = backend.get_cursor_position()?; terminal.set_cursor_position((0, 20))?; let position = terminal.set_cursor_position()?; -
b70cd03 (uncategorized) Add ListState / TableState scroll_down_by() / scroll_up_by() methods by
@josueBarretogitin #1267Implement new methods
scroll_down_by(u16)andscroll_up_by(u16)for bothListstateandTablestate.Closes:#1207
Bug Fixes
-
864cd9f (testbackend) Prevent area mismatch by
@EdJoPaToin #1252Removes the height and width fields from TestBackend, which can get out of sync with the Buffer, which currently clamps to 255,255.
This changes the
TestBackendserde representation. It should be possible to read older data, but data generated after this change can't be read by older versions. -
7e1bab0 (buffer) Dont render control characters by
@EdJoPaToin #1226 -
c08b522 (chart) Allow removing all the axis labels by
@EdJoPaToin #1282axis.labels(vec![])removes all the labels correctly.This makes calling axis.labels with an empty Vec the equivalent of not calling axis.labels. It's likely that this is never used, but it prevents weird cases by removing the mix-up of
Option::NoneandVec::is_empty, and simplifies the implementation code. -
03f3124 (paragraph) Line_width, and line_count include block borders by
@airblast-devin #1235The
line_width, andline_countmethods forParagraphwould not take into account theBlockif one was set. This will now correctly calculate the values including theBlock's width/height.Fixes:#1233
-
3ca920e (span) Prevent panic on rendering out of y bounds by
@EdJoPaToin #1257 -
84cb164 (terminal) Make terminal module private by
@joshkain #1260 [breaking]This is a simplification of the public API that is helpful for new users that are not familiar with how rust re-exports work, and helps avoid clashes with other modules in the backends that are named terminal.
BREAKING CHANGE:The
terminalmodule is now private and can not be used directly. The types under this module are exported from the root of the crate.- use ratatui::terminal::{CompletedFrame, Frame, Terminal, TerminalOptions, ViewPort}; + use ratatui::{CompletedFrame, Frame, Terminal, TerminalOptions, ViewPort}; -
29c8c84 (uncategorized) Ignore newlines in Span's Display impl by
@SUPERCILEXin #1270 -
cd93547 (uncategorized) Remove unnecessary synchronization in layout cache by
@SUPERCILEXin #1245Layout::init_cache no longer returns bool and takes a NonZeroUsize instead of usize
The cache is a thread-local, so doesn't make much sense to require synchronized initialization.
-
b344f95 (uncategorized) Only apply style to first line when rendering a
Lineby@joshkain #1247A
Linewidget should only apply its style to the first line when rendering and not the entire area. This is because theLinewidget should only render a single line of text. This commit fixes the issue by clamping the area to a single line before rendering the text. -
7ddfbc0 (uncategorized) Unnecessary allocations when creating Lines by
@SUPERCILEXin #1237 -
84f3341 (uncategorized) Clippy lints from rust 1.80.0 by
@joshkain #1238
Refactor
-
bb68bc6 (backend) Return
SizefromBackend::sizeinstead ofRectby@EdJoPaToin #1254 [breaking]The
Backend::sizemethod returns aSizeinstead of aRect. There is no need for the position here as it was always 0,0. -
e81663b (list) Split up list.rs into smaller modules by
@joshkain #1204 -
e707ff1 (uncategorized) Internally use Position struct by
@EdJoPaToin #1256 -
32a0b26 (uncategorized) Simplify WordWrapper implementation by
@tranzystorekkin #1193
Documentation
-
6ce447c (block) Add docs about style inheritance by
@joshkain #1190 -
55e0880 (block) Update block documentation by
@leohsclin #1206Update block documentation with constructor methods and setter methods in the main doc comment Added an example for using it to surround widgets
-
f2fa1ae (breaking-changes) Add missing code block by
@orhunin #1291 -
f687af7 (breaking-changes) Mention removed lifetime of ToText trait by
@orhunin #1292 -
d468463 (breaking-changes) Fix the PR link by
@orhunin #1294 -
1b9bdd4 (contributing) Fix minor issues by
@EdJoPaToin #1300 -
5f7a7fb (examples) Update barcharts gifs by
@joshkain #1306 -
fe4eeab (examples) Simplify the barchart example by
@joshkain #1079The
barchartexample has been split into two examples:barchartandbarchart-grouped. Thebarchartexample now shows a simple barchart with random data, while thebarchart-groupedexample shows a grouped barchart with fake revenue data.This simplifies the examples a bit so they don't cover too much at once.
- Simplify the rendering functions
- Fix several clippy lints that were marked as allowed
-
6e7b4e4 (examples) Add async example by
@joshkain #1248This example demonstrates how to use Ratatui with widgets that fetch data asynchronously. It uses the
octocrabcrate to fetch a list of pull requests from the GitHub API. You will need an environment variable namedGITHUB_TOKENwith a valid GitHub personal access token. The token does not need any special permissions. -
935a718 (examples) Add missing examples to README by
@kibibyt3in #1225Resolves:#1014
-
50e5674 (examples) Fix: fix typos in tape files by
@kibibyt3in #1224 -
810da72 (examples) Fix hyperlink example tape by
@kibibyt3in #1222 -
5eeb1cc (github) Create CODE_OF_CONDUCT.md by
@joshkain #1279 -
bb71e5f (readme) Remove MSRV by
@EdJoPaToin #1266This notice was useful when the
Cargo.tomlhad no standardized field for this. Now it's easier to look it up in theCargo.tomland it's also a single point of truth. Updating the README was overlooked for quite some time so it's better to just omit it rather than having something wrong that will be forgotten again in the future. -
2fd5ae6 (widgets) Document stability of WidgetRef by
@joshkain #1288Addresses some confusion about when to implement
WidgetRefvsimpl Widget for &W. Notes the stability rationale and links to an issue that helps explain the context of where we're at in working this out. -
716c931 (uncategorized) Document crossterm breaking change by
@joshkain #1281 -
f775030 (uncategorized) Update main lib.rs / README examples by
@joshkain #1280 -
8433d09 (uncategorized) Update demo image by
@joshkain #1276Follow up to https://github.com/ratatui/ratatui/pull/1203
Performance
-
663486f (list) Avoid extra allocations when rendering
Listby@airblast-devin #1244When rendering a
List, eachListItemwould be cloned. Removing the clone, and replacingWidget::renderwithWidgetRef::render_refsaves us allocations caused by the clone of theText<'_>stored inside ofListItem.Based on the results of running the "list" benchmark locally; Performance is improved by %1-3 for all
renderbenchmarks forList. -
4753b72 (reflow) Eliminate most WordWrapper allocations by
@SUPERCILEXin #1239On large paragraphs (~1MB), this saves hundreds of thousands of allocations.
TL;DR:reuse as much memory as possible across
next_linecalls. Instead of allocating new buffers each time, allocate the buffers once and clear them before reuse. -
be3eb75 (table) Avoid extra allocations when rendering
Tableby@airblast-devin #1242When rendering a
TabletheTextstored inside of aCellgets cloned before rendering. This removes the clone and usesWidgetRefinstead, saving us from allocating aVec<Line<'_>>insideText. Also avoids an allocation when rendering the highlight symbol if it contains an owned value. -
f04bf85 (uncategorized) Add buffer benchmarks by
@joshkain #1303 -
e6d2e04 (uncategorized) Move benchmarks into a single benchmark harness by
@joshkain #1302Consolidates the benchmarks into a single executable rather than having to create a new cargo.toml setting per and makes it easier to rearrange these when adding new benchmarks.
Styling
-
a80a8a6 (format) Lint markdown by
@joshkain #1131- chore: Fix line endings for changelog
- chore: cleanup markdown lints
- ci: add Markdown linter
- build: add markdown lint to the makefile
Testing
Miscellaneous Tasks
-
82b70fd (ci) Integrate cargo-semver-checks by
@orhunin #1166cargo-semver-checks: Lint your crate API changes for semver violations. -
c245c13 (ci) Onboard bencher for tracking benchmarks by
@orhunin #1174https://bencher.dev/console/projects/ratatui-org
Closes:#1092
-
efef0d0 (ci) Change label from
breaking changetoType: Breaking Changeby@kdheepakin #1243This PR changes the label that is auto attached to a PR with a breaking change per the conventional commits specification.
-
41a9100 (github) Use the GitHub organization team as codeowners by
@EdJoPaToin #1081Use GitHub organization team in CODEOWNERS and create MAINTAINERS.md
-
3e7458f (github) Add forums and faqs to the issue template by
@joshkain #1201 -
45fcab7 (uncategorized) Add rect::rows benchmark by
@joshkain #1301 -
edc2af9 (uncategorized) Replace big_text with hardcoded logo by
@joshkain #1203big_text.rs was a copy of the code from tui-big-text and was getting gradually out of sync with the original crate. It was also rendering something a bit different than the Ratatui logo. This commit replaces the big_text.rs file with a much smaller string representation of the Ratatui logo.
-
c2d3850 (uncategorized) Use LF line endings for CHANGELOG.md instead of CRLF by
@joshkain #1269 -
a9fe428 (uncategorized) Update cargo-deny config by
@EdJoPaToin #1265Update
cargo-denyconfig (noticed in https://github.com/ratatui/ratatui/pull/1263#pullrequestreview-2215488414) -
ffc4300 (uncategorized) Remove executable flag for rs files by
@EdJoPaToin #1262 -
7bab9f0 (uncategorized) Add more CompactString::const_new instead of new by
@joshkain #1230 -
ccf83e6 (uncategorized) Update labels in issue templates by
@joshkain #1212
Build
Continuous Integration
-
476ac87 (uncategorized) Split up lint job by
@EdJoPaToin #1264This helps with identifying what failed right from the title. Also steps after a failing one are now always executed.
Also shortens the steps a bit by removing obvious names.
New Contributors
-
@SUPERCILEXmade their first contribution in #1239 -
@josueBarretogitmade their first contribution in #1267 -
@airblast-devmade their first contribution in #1242 -
@kibibyt3made their first contribution in #1225 -
@EmiOnGitmade their first contribution in #1217 -
@leohsclmade their first contribution in #1206 -
@robertpsoanemade their first contribution in #1198
Full Changelog: https://github.com/ratatui/ratatui/compare/v0.27.0...0.28.0
-
-
0.28.0-alpha.103 Aug 2024 pre-releaseNothing published for this version
-
0.28.0-alpha.027 Jul 2024 pre-releaseNothing published for this version
-
0.27.1-alpha.320 Jul 2024 pre-releaseNothing published for this version
-
0.27.1-alpha.213 Jul 2024 pre-releaseNothing published for this version
-
0.27.1-alpha.106 Jul 2024 pre-releaseNothing published for this version
-
0.27.1-alpha.029 Jun 2024 pre-releaseNothing published for this version
-
0.27.024 Jun 2024Release notes
Open source →In this version, we have focused on enhancing usability and functionality with new features like background styles for LineGauge, palette colors, and various other improvements including improved performance. Also, we added brand new examples for tracing and creating hyperlinks!
✨ Release highlights: https://ratatui.rs/highlights/v027/
⚠️ List of breaking changes can be found here.
Features
-
eef1afe (linegauge) Allow LineGauge background styles by
@nowNickin #565This PR deprecates `gauge_style` in favor of `filled_style` and `unfilled_style` which can have its foreground and background styled. `cargo run --example=line_gauge --features=crossterm`https://github.com/ratatui/ratatui/assets/5149215/5fb2ce65-8607-478f-8be4-092e08612f5b
-
1365620 (borders) Add FULL and EMPTY border sets by
@joshkain #1182border::FULLuses a full block symbol, whileborder::EMPTYuses an empty space. This is useful for when you need to allocate space for the border and apply the border style to a block without actually drawing a border. This makes it possible to style the entire title area or a block rather than just the title content.
use ratatui::{symbols::border, widgets::Block}; let block = Block::bordered().title("Title").border_set(border::FULL); let block = Block::bordered().title("Title").border_set(border::EMPTY);-
7a48c5b (cell) Add EMPTY and (const) new method by
@EdJoPaToin #1143This simplifies calls to `Buffer::filled` in tests. -
3f2f2cd (docs) Add tracing example by
@joshkain #1192Add an example that demonstrates logging to a file for:https://forum.ratatui.rs/t/how-do-you-println-debug-your-tui-programs/66
cargo run --example tracing RUST_LOG=trace cargo run --example=tracing cat tracing.log-
1520ed9 (layout) Impl Display for Position and Size by
@joshkain #1162 -
46977d8 (list) Add list navigation methods (first, last, previous, next) by
@joshkain #1159 [breaking]Also cleans up the list example significantly (see also <https://github.com/ratatui/ratatui/issues/1157>)Fixes:https://github.com/ratatui/ratatui/pull/1159
BREAKING CHANGE:The
Listwidget now clamps the selected index to the bounds of the list when navigating withfirst,last,previous, andnext, as well as when setting the index directly withselect. -
10d7788 (style) Add conversions from the palette crate colors by
@joshkain #1172This is behind the "palette" feature flag. ```rust use palette::{LinSrgb, Srgb}; use ratatui::style::Color; let color = Color::from(Srgb::new(1.0f32, 0.0, 0.0)); let color = Color::from(LinSrgb::new(1.0f32, 0.0, 0.0)); ``` -
7ef2dae (text) support conversion from Display to Span, Line and Text by
@orhunin #1167Now you can create `Line` and `Text` from numbers like so: ```rust let line = 42.to_line(); let text = 666.to_text(); ``` -
74a32af (uncategorized) Re-export backends from the ratatui crate by
@joshkain #1151`crossterm`, `termion`, and `termwiz` can now be accessed as `ratatui::{crossterm, termion, termwiz}` respectively. This makes it possible to just add the Ratatui crate as a dependency and use the backend of choice without having to add the backend crates as dependencies. To update existing code, replace all instances of `crossterm::` with `ratatui::crossterm::`, `termion::` with `ratatui::termion::`, and `termwiz::` with `ratatui::termwiz::`. -
3594180 (uncategorized) Make Stylize's
.bg(color)generic by@kdheepakin #1103 [breaking] -
0b5fd6b (uncategorized) Add writer() and writer_mut() to termion and crossterm backends by
@enricozbin #991It is sometimes useful to obtain access to the writer if we want to see what has been written so far. For example, when using &mut [u8] as a writer.
Bug Fixes
-
efa965e (line) Remove newlines when converting strings to Lines by
@joshkain #1191Line::from("a\nb")now returns a line with twoSpans instead of 1 -
d370aa7 (span) Ensure that zero-width characters are rendered correctly by
@joshkain #1165 -
127d706 (table) Ensure render offset without selection properly by
@joshkain #1187 -
4bfdc15 (uncategorized) Render of &str and String doesn't respect area.width by
@thscharlerin #1177 -
e6871b9 (uncategorized) Avoid unicode-width breaking change in tests by
@joshkain #1171unicode-width 0.1.13 changed the width of \u{1} from 0 to 1. Our tests assumed that \u{1} had a width of 0, so this change replaces the \u{1} character with \u{200B} (zero width space) in the tests. Upstream issue (closed as won't fix): https://github.com/unicode-rs/unicode-width/issues/55 -
7f3efb0 (uncategorized) Pin unicode-width crate to 0.1.13 by
@joshkain #1170semver breaking change in 0.1.13 <https://github.com/unicode-rs/unicode-width/issues/55> <!-- Please read CONTRIBUTING.md before submitting any pull request. --> -
42cda6d (uncategorized) Prevent panic from string_slice by
@EdJoPaToin #1140https://rust-lang.github.io/rust-clippy/master/index.html#string_slice
Refactor
-
73fd367 (block) Group builder pattern methods by
@EdJoPaToin #1134 -
257db62 (cell) Must_use and simplify style() by
@EdJoPaToin #1124<!-- Please read CONTRIBUTING.md before submitting any pull request. --> -
bf20369 (cell) Reset instead of applying default by
@EdJoPaToin #1127Using reset is clearer to me what actually happens. On the other case a struct is created to override the old one completely which basically does the same in a less clear way. -
cf67ed9 (lint) Use clippy::or_fun_call by
@EdJoPaToin #1138https://rust-lang.github.io/rust-clippy/master/index.html#or_fun_call
-
4770e71 (list) Remove deprecated
start_cornerandCornerby@Valentin271in #759 [breaking]List::start_cornerwas deprecated in v0.25. UseList::directionandListDirectioninstead.
- list.start_corner(Corner::TopLeft); - list.start_corner(Corner::TopRight); // This is not an error, BottomRight rendered top to bottom previously - list.start_corner(Corner::BottomRight); // all becomes + list.direction(ListDirection::TopToBottom);- list.start_corner(Corner::BottomLeft); // becomes + list.direction(ListDirection::BottomToTop);layout::Corneris removed entirely.-
4f77910 (padding) Add Padding::ZERO as a constant by
@EdJoPaToin #1133Deprecate Padding::zero() -
8061813 (uncategorized) Expand glob imports by
@joshkain #1152Consensus is that explicit imports make it easier to understand the example code. This commit removes the prelude import from all examples and replaces it with the necessary imports, and expands other glob imports (widget::*, Constraint::*, KeyCode::*, etc.) everywhere else. Prelude glob imports not in examples are not covered by this PR. See https://github.com/ratatui/ratatui/issues/1150 for more details. -
d929971 (uncategorized) Dont manually impl Default for defaults by
@EdJoPaToin #1142Replace `impl Default` by `#[derive(Default)]` when its implementation equals. -
8a60a56 (uncategorized) Needless_pass_by_ref_mut by
@EdJoPaToin #1137https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut
-
1de9a82 (uncategorized) Simplify if let by
@EdJoPaToin #1135While looking through lints [`clippy::option_if_let_else`](https://rust-lang.github.io/rust-clippy/master/index.html#option_if_let_else) found these. Other findings are more complex so I skipped them.
Documentation
-
1908b06 (borders) Add missing closing code blocks by
@orhunin #1195 -
38bb196 (breaking-changes) Mention
LineGauge::gauge_styleby@orhunin #1194see #565
-
07efde5 (examples) Add hyperlink example by
@joshkain #1063 -
7fdccaf (examples) Add vhs tapes for constraint-explorer and minimal examples by
@joshkain #1164 -
4f307e6 (examples) Simplify paragraph example by
@joshkain #1169 -
f429f68 (examples) Remove lifetimes from the List example by
@mattain #1132Simplify the List example by removing lifetimes not strictly necessary to demonstrate how Ratatui lists work. Instead, the sample strings are copied into each `TodoItem`. To further simplify, I changed the code to use a new TodoItem::new function, rather than an implementation of the `From` trait. -
2f8a936 (uncategorized) Fix links on docs.rs by
@EdJoPaToin #1144This also results in a more readable Cargo.toml as the locations of the things are more obvious now. Includes rewording of the underline-color feature. Logs of the errors: https://docs.rs/crate/ratatui/0.26.3/builds/1224962 Also see #989
Performance
-
4ce67fc (buffer) Filled moves the cell to be filled by
@EdJoPaToin #1148 [breaking] -
8b447ec (rect)
Rect::innertakesMargindirectly instead of reference by@EdJoPaToin #1008 [breaking]BREAKING CHANGE:Margin needs to be passed without reference now.
-let area = area.inner(&Margin { +let area = area.inner(Margin { vertical: 0, horizontal: 2, });Styling
Testing
-
d6587bc (style) Use rstest by
@EdJoPaToin #1136<!-- Please read CONTRIBUTING.md before submitting any pull request. -->
Miscellaneous Tasks
-
7b45f74 (prelude) Add / remove items by
@joshkain #1149 [breaking]his PR removes the items from the prelude that don't form a coherent common vocabulary and adds the missing items that do. Based on a comment at <https://www.reddit.com/r/rust/comments/1cle18j/comment/l2uuuh7/>BREAKING CHANGE:The following items have been removed from the prelude:
-
style::Styled- this trait is useful for widgets that want to support the Stylize trait, but it adds complexity as widgets have twostylemethods and aset_stylemethod. -
symbols::Marker- this item is used by code that needs to draw to theCanvaswidget, but it's not a common item that would be used by most users of the library. -
terminal::{CompletedFrame, TerminalOptions, Viewport}- these items are rarely used by code that needs to interact with the terminal, and they're generally only ever used once in any app.
The following items have been added to the prelude:
-
layout::{Position, Size}- these items are used by code that needs to interact with the layout system. These are newer items that were added in the last few releases, which should be used more liberally. -
cd64367 (symbols) Add tests for line symbols by
@joshkain #1186 -
8cfc316 (uncategorized) Alphabetize examples in Cargo.toml by
@joshkain #1145
Build
-
70df102 (bench) Improve benchmark consistency by
@EdJoPaToin #1126Codegen units are optimized on their own. Per default bench / release have 16 codegen units. What ends up in a codeget unit is rather random and can influence a benchmark result as a code change can move stuff into a different codegen unit → prevent / allow LLVM optimizations unrelated to the actual change. More details: https://doc.rust-lang.org/cargo/reference/profiles.html
New Contributors
@thscharlermade their first contribution in #1177@mattamade their first contribution in #1132@nowNickmade their first contribution in #565@enricozbmade their first contribution in #991
Full Changelog: https://github.com/ratatui/ratatui/compare/v0.26.3...v0.27.0
-
-
0.27.0-alpha.822 Jun 2024 pre-releaseNothing published for this version
-
0.27.0-alpha.717 Jun 2024 pre-releaseNothing published for this version
-
0.27.0-alpha.513 Apr 2024 pre-releaseNothing published for this version
-
0.27.0-alpha.406 Apr 2024 pre-releaseNothing published for this version
-
0.27.0-alpha.330 Mar 2024 pre-releaseNothing published for this version
-
0.27.0-alpha.223 Mar 2024 pre-releaseNothing published for this version
-
0.27.0-alpha.116 Mar 2024 pre-releaseNothing published for this version
-
0.27.0-alpha.009 Mar 2024 pre-releaseNothing published for this version
-
0.26.320 May 2024Release notes
Open source →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/
Features
-
97ee102 (buffer) Track_caller for index_of by
@EdJoPaToin #1046 **The caller put in the wrong x/y -> the caller is the cause. -
bf09234 (table) Make TableState::new const by
@EdJoPaToin #1040 -
eb281df (uncategorized) Use inner Display implementation by
@EdJoPaToin #1097 -
ec763af (uncategorized) Make Stylize's
.bg(color)generic by@kdheepakin #1099This 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
@joshkain #1086
Bug Fixes
-
366cbae (buffer) Fix Debug panic and fix formatting of overridden parts by
@EdJoPaToin #1098Fix 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
@OkieOthin #1069This 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
@psobolikin #1066Add 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
@kxxtin #1074 -
699c2d7 (uncategorized) Unicode truncation bug by
@joshkain #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
@joshkain #1094Fixes code that doesn't compile in the termwiz tests when underline-color feature is enabled. -
5f1e119 (uncategorized) Correct feature flag typo for termwiz by
@joshkain #1088underline-color was incorrectly spelt as underline_color -
0a16496 (uncategorized) Use
to_stringto serialize Color by@SleepySwordsin #934Since 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.
Refactor
-
2cfe82a (buffer) Deprecate assert_buffer_eq! in favor of assert_eq! by
@EdJoPaToin #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
@EdJoPaToin #1083 -
9bd89c2 (clippy) Enable breaking lint checks by
@EdJoPaToin #988We 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
@EdJoPaToin #1038Use `App::default()` directly.
Documentation
-
da1ade7 (github) Update code owners about past maintainers by
@orhunin #1073As per suggestion in https://github.com/ratatui/ratatui/pull/1067#issuecomment-2079766990 It's good for historical purposes! -
3687f78 (github) Update code owners by
@orhunin #1067Removes 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
@kdheepakin #1108 -
f945a0b (test) Fix typo in TestBackend documentation by
@orhunin #1107 -
828d17a (uncategorized) Add minimal example by
@joshkain #1114 -
e95230b (uncategorized) Add note about scrollbar state content length by
@Utagaiin #1077
Performance
-
366c2a0 (block) Use Block::bordered by
@EdJoPaToin #1041Block::bordered()is shorter thanBlock::new().borders(Borders::ALL), requires one less import (Borders) and in caseBlock::default()was used before can even beconst. -
2e71c18 (buffer) Simplify Buffer::filled with macro by
@EdJoPaToin #1036The `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
@EdJoPaToin #1039Also, 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
@EdJoPaToin #1037 -
1706b0a (crossterm) Speed up combined fg and bg color changes by up to 20% by
@joshkain #1072 -
1a4bb1c (layout) Avoid allocating memory when using split ergonomic utils by
@tranzystorekkin #1105Don't create intermediate vec in `Layout::areas` and `Layout::spacers` when there's no need for one.
Styling
-
aa4260f (uncategorized) Use std::fmt instead of importing Debug and Display by
@joshkain #1087This 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)
Testing
Miscellaneous Tasks
-
5fbb77a (readme) Use terminal theme for badges by
@TadoTheMinerin #1026The 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
@joshkain #1080 -
76e5fe5 (uncategorized) Revert "Make Stylize's
.bg(color)generic" by@kdheepakin #1102This reverts commit ec763af8512df731799c8f30c38c37252068a4c4 from #1099 -
64eb391 (uncategorized) Fixup cargo lint for windows targets by
@joshkain #1071Crossterm brings in multiple versions of the same dep -
326a461 (uncategorized) Add package categories field by
@mcskwarein #1035Add 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.
Build
-
4955380 (uncategorized) Remove pre-push hooks by
@joshkain #1115 -
28e81c0 (uncategorized) Add underline-color to all features flag in makefile by
@joshkain #1100 -
c75aa19 (uncategorized) Add clippy::cargo lint by
@joshkain #1053Followup 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.
New Contributors
@Utagaimade their first contribution in #1077@kxxtmade their first contribution in #1074@OkieOthmade their first contribution in #1069@psobolikmade their first contribution in #1066@SleepySwordsmade their first contribution in #934@mcskwaremade their first contribution in #1035
Full Changelog: https://github.com/ratatui/ratatui/compare/v0.26.2...v0.26.3
-
-
0.26.3-alpha.418 May 2024 pre-releaseNothing published for this version
-
0.26.3-alpha.311 May 2024 pre-releaseNothing published for this version
-
0.26.3-alpha.204 May 2024 pre-releaseNothing published for this version
-
0.26.3-alpha.127 Apr 2024 pre-releaseNothing published for this version
-
0.26.3-alpha.020 Apr 2024 pre-releaseNothing published for this version
-
0.26.215 Apr 2024Release notes
Open source →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/
Features
-
11b452d (layout) Mark various functions as const by
@EdJoPaToin #951 -
1cff511 (line) Impl Styled for Line by
@joshkain #968This 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
@CameronBarnesin #958Introduces 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
@joshkain #998Adds 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
FromIteratorimpls forLineandTextby@joshkain #967This 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
&strandStringby@kdheepakin #952Currently, `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()))?; ``` ---------
Bug Fixes
-
0207160 (line) Line truncation respects alignment by
@TadoTheMinerin #987When 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
@mrjackwillsin #949An 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
@EdJoPaToin #964Fixes 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
@joshkain #997Previously 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
@joshkain #992Paragraph was ignoring the new `Text::style` field added in 0.26.0 -
35e971f (uncategorized) Scrollbar thumb not visible on long lists by
@ThomasMizin #959When displaying somewhat-long lists, the `Scrollbar` widget sometimes did not display a thumb character, and only the track will be visible.
Refactor
-
6fd5f63 (lint) Prefer idiomatic for loops by
@EdJoPaTo -
37b957c (lints) Add lints to scrollbar by
@EdJoPaTo -
c12bcfe (non-src) Apply pedantic lints by
@EdJoPaToin #976Fixes 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
@EdJoPaToin #993With 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
@EdJoPaToin #1016Simplifies the code, logic stays exactly the same. -
8e68db9 (uncategorized) Remove pointless default on internal structs by
@EdJoPaToin #980See #978
Also remove other derives. They are unused and just slow down compilation.
-
3be189e (uncategorized) Clippy::thread_local_initializer_can_be_made_const by
@EdJoPaToenabled 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
@EdJoPaToit's not needed and can just be assumedrelated: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
@EdJoPaToenabled by default, only detected by nightly yet -
df5dddf (uncategorized) Unused_imports by
@EdJoPaToenabled by default, only detected on nightly yet -
f1398ae (uncategorized) Clippy::useless_vec by
@EdJoPaToLint 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
Documentation
-
14461c3 (breaking-changes) Typos and markdownlint by
@EdJoPaToin #1009 -
3b002fd (uncategorized) Update incompatible code warning in examples readme by
@joshkain #1013
Performance
-
e02f476 (borders) Allow border!() in const by
@EdJoPaToin #977This allows more compiler optimizations when the macro is used. -
541f0f9 (cell) Use const CompactString::new_inline by
@EdJoPaToin #979Some 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
@EdJoPaToin #963A 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
Miscellaneous Tasks
-
125ee92 (docs) Fix: fix typos in crate documentation by
@orhunin #1002 -
38c17e0 (editorconfig) Set and apply some defaults by
@EdJoPaTo -
07da90a (funding) Add eth address for receiving funds from drips.network by
@BenJamin #994 -
078e97e (github) Add EdJoPaTo as a maintainer by
@orhunin #986 -
b0314c5 (uncategorized) Remove conventional commit check for PR by
@Valentin271in #950This 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.
Build
-
6e6ba27 (lint) Warn on pedantic and allow the rest by
@EdJoPaTo -
c4ce7e8 (uncategorized) Enable more satisfied lints by
@EdJoPaToThese 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.0BREAKING CHANGE:rust 1.74 is required now
New Contributors
@TadoTheMinermade their first contribution in #987@BenJammade their first contribution in #994@CameronBarnesmade their first contribution in #958@ThomasMizmade their first contribution in #959
Full Changelog: https://github.com/ratatui/ratatui/compare/v0.26.1...0.26.2
-
-
0.26.2-alpha.202 Mar 2024 pre-releaseNothing published for this version
-
0.26.2-alpha.124 Feb 2024 pre-releaseNothing published for this version
-
0.26.2-alpha.017 Feb 2024 pre-releaseNothing published for this version
-
0.26.112 Feb 2024Release notes
Open source →This is a patch release that fixes bugs and adds enhancements, including new iterators, title options for blocks, and various rendering improvements. ✨
Features
-
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
Bug Fixes
-
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)
Refactor
Documentation
-
61a8278 (canvas) Add documentation to canvas module (#913)
Document the whole `canvas` module. With this, the whole `widgets` module is documented.
Performance
Miscellaneous Tasks
-
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
Contributors
Thank you so much to everyone that contributed to this release!
Here is the list of contributors who have contributed to
ratatuifor the first time!@mo8it@m4rch3n1ng
-
-
0.26.1-alpha.110 Feb 2024 pre-releaseNothing published for this version
-
0.26.1-alpha.003 Feb 2024 pre-releaseNothing published for this version
-
0.26.002 Feb 2024Release notes
Open source →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!
Features
-
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::ProportionaltoConstraint::Fill(#880)Constraint::Fillis 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 docsBREAKING CHANGE:
Line::styleis now a field ofLineinstead of being stored in eachSpan. -
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
RowintoTable(#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 ofvec![]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
Linein 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 aVec<_>. -
b459228 (termwiz) Add
Fromtermwiz 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:
styleandalignmenttoText- impl
WidgetforText - replace
Textmanual draw to call for Widget impl
All places that use
Texthave 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
ListItemintoList(#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::SpaceAroundandFlex::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
Flexmodes.-
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::DisplayforText,Line, andSpanstructs.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 toLine::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 usenow_utcinstead. -
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)
Refactor
-
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_bottomwas deprecated in v0.22. UseBlock::titleandTitle::positioninstead. -
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_stylechainable (#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. -
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 <[email protected]> -
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 <[email protected]> -
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
Maxconstraints (#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.
-
-
0.26.0-alpha.327 Jan 2024 pre-releaseNothing published for this version
-
0.26.0-alpha.220 Jan 2024 pre-releaseNothing published for this version
-
0.26.0-alpha.113 Jan 2024 pre-releaseNothing published for this version
-
0.26.0-alpha.007 Jan 2024 pre-releaseNothing published for this version
-
0.25.018 Dec 2023Release notes
Open source →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/ratatuiFeatures
-
aef4956 (list)
List::newnow acceptsIntoIterator<Item = Into<ListItem>>(#672) [breaking]This allows to build list like ``` List::new(["Item 1", "Item 2"]) ``` -
8bfd666 (paragraph) Add
line_countandline_widthunstable helper methodsThis is an unstable feature that may be removed in the future -
1229b96 (rect) Add
offsetmethod (#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::symbolfield (#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
Fromtrait for crossterm toStylerelated 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
Fromtrait for termion toStylerelated 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]); ```
Bug Fixes
-
f69d57c (rect) Fix underflow in the
Rect::intersectionmethod (#678) -
56fc410 (block) Make
inneraware 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::symbolfield 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)
Refactor
-
f767ea7 (list)
start_corneris nowdirection(#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
Documentation
-
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
Styling
Miscellaneous Tasks
-
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_useon 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
Continuous Integration
-
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)
Contributors
Thank you so much to everyone that contributed to this release!
Here is the list of contributors who have contributed to
ratatuifor the first time!@rikonaka@danny-burrows@SOF3@jan-ferdinand@rhaskia@asomers@progval@TylerBloom@YeungKC@lyuha
-