NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
crates.io · #1226 most downloaded on crates.io
A library that's all about cooking up terminal user interfaces
Last release 3 months ago
19 Jun 2026
Release timing varies
gaps range from 2 weeks to 5 months
Nearly every release is documented
notes for 18 of 19 stable releases
Nothing withdrawn
no release was ever pulled
4 years old
87 releases · first in 2023
One column per quarter.
⚠️ List of breaking changes can be found here .
We are excited to announce the new version of ratatui - a Rust library that's all about cooking up TUIs 👨🍳🐀
✨ Release highlights: https://ratatui.rs/highlights/v0302/
⚠️ List of breaking changes can be found here.
90639c1 (uncategorized) Add Termina backend by @joshka in #2561
Summary
- 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 docsRefs #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
fce3c80 (widgets) Require thread-safe shadow effects by @joshka in #2584
Summary
- 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-exportsFixes #2583
e306ce6 (buffer) Create updates for "uncovered" cells by @benjajaja in #2587
When 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 @satyakwok in #2594
Closes #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.
c75d778 (ci) Add cargo-udeps dependency check by @joshka in #2599
Adds 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 @KikiKian in #2598
Audit 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
36854ef (uncategorized) Add auto-merge required gate by @joshka in #2596
Summary
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
checksValidation
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
Full Changelog: ratatui-v0.30.1...ratatui-v0.30.2
⚠️ List of breaking changes can be found here .
"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.
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
4d30420 (buffer) Add CellDiffOption::AlwaysUpdate to force cell updates by sxyazi in #2480
When 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.
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 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]);
0a87882 (uncategorized) Add impl From<u16> for Padding and Margin by 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
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.
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
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).
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.
⚠️ List of breaking changes can be found here.
"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 ratatui so 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.
90a77aa (direction) Add Direction::perpendicular(self) by @b-guild in #2197
56d5e05 (bar) Update label and text_value to accept Into<> by @Emivvvvv in #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 @Emivvvvv in #1476
Related:https://github.com/ratatui/ratatui/issues/683
e15fefa (barchar) Add BarChart::grouped constructor by @joshka in #1513
Add 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 @Emivvvvv in #1453
Adds constructor methods for BarChart, BarGroup, and Bar
1dc18bf (calendar) Add width and height functions by @joshka in #2198
Fixes https://github.com/ratatui/ratatui/issues/2016
f18bcbf (canvas) Add quadrant, sextant and octant markers by @sbarral in #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-g00da in #2165
This 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 to Style by @sxyazi in #2267
Resolves https://github.com/ratatui/ratatui/issues/2264
2d713d7 (crossterm) Allow multiple crossterm versions by @joshka in #1841
This 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::SpaceEvenly by @kdheepak in #1952 [breaking]
Resolves https://github.com/ratatui/ratatui/issues/1951
BREAKING CHANGE:Old
Flex::SpaceAroundbehavior is available by using
Flex::SpaceEvenlyand new
Flex::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 @joshka in #1547
7ad9c29 (linegauge) Customized symbols by @sectore in #1601
With 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-dev in #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-g00da in #2076
Improves 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-atomicenabledTurning on
portable-atomictogether withstdwill fall back tostdatomic.
1399d95 (no_std) Make palette and serde features depends on std by @j-g00da in #1919
b32f781 (no_std) Make ratatui-macros no-std by @j-g00da in #1865
3e1c72f (no_std) Make ratatui compatible with #![no_std] by @j-g00da in #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_std compatibility by @j-g00da in #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::Error Infallible by @j-g00da in #1823 [breaking]
BREAKING CHANGE:
TestBackendnow usescore::convert::Infalliblefor error handling instead ofstd::io::Error
007713e (no_std) Replace Backend's io::Error usages with associated Error type by @j-g00da in #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-widgets no_std by @j-g00da in #1779
Resolves #1776
5a232a3 (no_std) Remove redundant std usages in ratatui-widgets by @j-g00da in #1762
ebe10cd (no_std) Remove redundant std usages in ratatui-core by @j-g00da in #1753
Resolves https://github.com/ratatui/ratatui/issues/1751
08b08cc (rect) Centering by @janTatesa in #1814
Resolves #617
ff729b7 (scrollbar) Support retrieving the current position of state by @orhun in #1552
As 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 @joshka in #2172
Allow
Style'sadd_modifierandsub_modifierfields to deserialize fromnull
b9da192 (serde) Derive Serialize/Deserialize for alignment enums by @j-g00da in #1957
Resolves #1954
89b7421 (serde) Derive Serialize/Deserialize for additional structs/enums by @aurreland in #1883
This PR adds
#[derive(Serialize, Deserialize)]to the following structs:
ConstraintDirectionSpacingLayoutAccentedPaletteNonAccentedPalettePalettePaddingBordersBorderTypeListDirectionScrollbarOrientationScrollDirectionRenderDirectionHighlightSpacingFixes #1877
03f3f6d (style) Allow add/sub modifiers to be omitted in Style serialization. by @rcorre in #2057
It'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 Marker non-exhaustive by @j-g00da in #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 @theotchlx in #1573
Adds 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 AddAssign for Text by @acuteenvy in #1956
This 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 @orhun in #1538
Allows constructing
Rectangle,PointsandCircleusing thenewmethod instead of initializing with the public fields directly.
22610b0 (uncategorized) Support adding an Offset to Position by @joshka in #2239
Adds 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 @joshka in #2240
Fixes:https://github.com/ratatui/ratatui/issues/1440
96d097e (uncategorized) Implement Rect ops for moving by @joshka in #1596
feat: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 @joshka in #2226
Add 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 @0xb002f0 in #2223
75b78be (uncategorized) Add width() impl for tabs by @joshka in #2049
The 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 @joshka in #2030
You 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 @joshka in #2028
Rect::from(size)returns a new Rect at the origin (0, 0) with the specifiedSize
017af11 (uncategorized) Preserve block titles when merging borders by @j-g00da in #1977
Resolves #1939
6dcd53b (uncategorized) Add ergonomic methods for layouting Rects by @joshka in #1909
This 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 @joshka in #1929
Fixes:https://github.com/ratatui/ratatui/issues/211
7bc78bc (uncategorized) Add ratatui::run() method by @joshka in #1707
This 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 @joshka in #1935
This 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 importing Borders by @j-g00da in #1918
Currently using
border!macro requires explicit import ofBorderswhich is unnecessary.
671c2b4 (uncategorized) Support merging the borders of blocks by @j-g00da
When 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 @joshka in #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 @joshka in #1852
Removes the CalendarEventStore::today() function in no-std environments
53cdbbc (uncategorized) Enable serde propagation to backend crates (crossterm, termion) by @ArjunKrish7356 in #1812
This 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 @aschey in #1684
fcb47d6 (uncategorized) Rename Alignment to HorizontalAlignment and add VerticalAlignment by @joshka in #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 @joshka in #1703
Other 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-Nans in #1584
Move 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 @joshka in #1581
https://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.
a89d3d6 (buffer) Clear behavior with VS16 wide emojis by @nornagon in #2063
This 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 @joshka in #1507
Previously 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 @renesat in #1501
Previously 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 @marcoieni in #2119
https://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 @MarSik in #1541
The 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 @orhun in #2164
fixes #1721
dca331c (demo) Support tab key in demo2 example by @orhun in #1726
see #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 @orhun in #1679
fixes #1678
39479e2 (examples) Ensure that example projects are not published by @orhun in #1672
9314312 (layout) Feature flag cache related types by @joshka in #1842
2dd1977 (layout-cache) Import NonZeroUsize only when layout-cache is enabled by @j-g00da in #1839
This silences unused import warning, when
layout-cacheis disabled.
564a9d7 (line-gauge) Pad default label to display 3 numbers by @martinetd in #2053
Display 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 @joshka in #1612
The 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-dev in #1832
79d5165 (no_std) Propagate std feature flag to dependencies by @j-g00da in #1838
Disables
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 f64 polyfills for no_std compatibility by @j-g00da in #1840
Related:https://github.com/rust-lang/rust/issues/137578
3b13240 (scrollbar) Check for area.is_empty() before rendering by @farmeroy in #1529
This 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 @EdJoPaTo in #1312
2ce958e (table) Allow display of additional table row, if row height > 1 by @Lunderberg in #1452
0a25bc1 (tests) Update the stderr snapshot for ratatui-macros by @orhun in #2161
New 🦀 broke the CI
5fa342c (widgets) Fix centered block title truncation by @ognis1205 in #1973
Previously 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 @joshka in #2173
1fe64de (uncategorized) Include underline color in anstyle conversion by @aschey in #2004
Underline color wasn't included in the style conversion logic.
c1b8528 (uncategorized) Panic when rendering widgets on too small buffer by @j-g00da in #1996
Fixes panic on overflow on horizontal
BarchartandRatatuiMascotand adds proper tests to all widgets.
08b21fa (uncategorized) Fix panic when rendering a Paragraph out of bounds by @jwodder in #1670
Fixes #1667.
80bc818 (uncategorized) Fix truncation of left aligned block titles by @joshka in #1931
truncate 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 @joshka in #1934
The 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 @janTatesa in #1921
12cb5a2 (uncategorized) Allow canvas area to exceed u16::MAX by @Daksh14 in #1891
This 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 @joshka in #1857
c238aca (uncategorized) padding_right() should set right padding instead of left by @sxyazi in #1837
Fixes https://github.com/ratatui/ratatui/issues/1836
c90ba97 (uncategorized) Avoid unnecessary imports in minimal build by @cgzones in #1787
core::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-g00da in #1755
New version of rust (1.86.0) caused CI to fail.
4eac5b2 (uncategorized) Make deprecation notes more helpful by @joshka in #1702
AI 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 @jwodder in #1669
Fixes #1666.
f5fc819 (uncategorized) Avoid extra line break on whitespace only lines when wrapping paragraphs by @dotdash in #1636
Currently 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 @joshka in #1527
https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
36e2d1b (uncategorized) Add feature(doc_cfg) when generating docs by @joshka in #1506
4d7704f (uncategorized) Make StatefulWidget and Ref work with unsized State by @thscharler in #1505
StatefulWidget::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.
8d60e96 (examples) Use crossterm event methods by @joshka in #1792
Crossterm 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-2100 in #1782
This 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.
f132fa1 (table) Small readability improvements by @joshka in #1510
c7c3498 (uncategorized) Use saturating_add in Rect::new by @pharrison31415 in #2216
02e53de (uncategorized) Make use of iter::repeat_n() by @cgzones in #1788
Applied via clippy --fix. Available since 1.82.0.
a195d59 (uncategorized) Move xtask commands to small modules by @joshka in #1620
904b0aa (uncategorized) Move symbols to modules by @joshka in #1594
7c8573f (uncategorized) Rearrange selection_spacing code by @raylu in #1540
217c57c (uncategorized) Modularize backends by @orhun in #1508
Backend 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 @joshka in #1479
This is a preparatory refactoring for modularization. No user visible changes.
40e96a2 (block) Add collapsed border example by @joshka in #1899
d291042 (block) Revise the block example by @orhun in #1520
- Moves the block example from
ratatuitoratatui-widgets- Simplifies the example (bordered, styled, custom borders)
see #1512
0951da5 (breaking-changes) Improve migration guide for Backend::Error by @j-g00da in #1908
Related:https://github.com/fujiapple852/trippy/pull/1588
bbe1cf9 (breaking-changes) Change MSRV to 1.85 by @j-g00da in #1896
The minimum supported Rust version is now for
ratatuiv0.30 is 1.85
c7912f3 (breaking-changes) Fix header level by @j-g00da in #1825
73488ab (contributing) Fix link to widgets_block_renders test by @ognis1205 in #2101
The
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 @joshka in #1816
3ae6bf1 (contributing) Use cargo-xtask for instructions by @orhun in #1509
- Updates
CONTRIBUTING.mdabout the usage ofxtask- Removes
Makefile.toml
22e3e84 (core) Remove link to Paragraph widget by @orhun in #1683
b65788c (examples) Remove duplicated link by @matthiasbeyer in #2212
200b217 (examples) Add VHS tapes and docs for widget examples by @orhun in #2114
fixes #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-g00da in #1890
Makes CI typos check pass again
882cc3c (examples) Update app examples with tapes by @orhun in #1673
4393fae (examples) Move scrollbar example to examples folder by @orhun in #1665
9ea70e2 (examples) Move widget-impl example to examples folder by @orhun in #1663
774ab78 (examples) Move widget-ref-container example to examples folder by @orhun in #1664
see #1512
910d16e (examples) Move user-input example to examples folder by @orhun in #1659
dbfb7da (examples) Move table example to examples folder by @orhun in #1657
cb2a58a (examples) Move tracing example to examples folder by @orhun in #1658
7e00b64 (examples) Move panic example to examples folder by @orhun in #1655
8127590 (examples) Move modifiers example to examples folder by @orhun in #1654
7c40c0b (examples) Move popup example to examples folder by @orhun in #1656
see #1512
d87354f (examples) Move list example to examples folder by @orhun in #1653
see #1512
also renames it to todo-list
621226f (examples) Move inline example to examples folder by @orhun in #1651
9ba7d25 (examples) Move hyperlink example to examples folder by @orhun in #1650
bb94d1c (examples) Move minimal example to examples folder by @orhun in #1649
9f399ac (examples) Move gauge example to examples folder by @orhun in #1646
104d6a6 (examples) Move custom-widget example to examples folder by @orhun in #1644
fa8ca01 (examples) Move flex example to examples folder by @orhun in #1642
f5fde0e (examples) Move constraints example to examples folder by @orhun in #1641
fc70288 (examples) Move constraint-explorer example to examples folder by @orhun in #1640
325f961 (examples) Move hello-world example to examples folder by @orhun in #1647
867c4bc (examples) Move colors-rgb example to examples folder by @joshka in #1582
- docs: move colors-rgb example to examples folder
- docs: update main examples README
72334ed (layout) Update documentation to point to kasuari solver by @a-kenji in #2003
2be9ccb (layout) Remove unnecessary path prefix by @j-g00da in #1766
b669ceb (layout) Change cassowary to kasuari crate reference by @j-g00da in #1765
f907c74 (license) Update copyright years by @LVivona in #1639
Update MIT Licence to copyright year 2025
68b9f67 (readme) Add Built with Ratatui badge for downstream projects by @harilvfs in #1905
6e43672 (readme) Reimagine README.md by @orhun in #1569
This 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 @HoKim98 in #1484
260af68 (readme) Include iocraft as an alternative by @kdheepak in #1483
8e5151f (rect) Fix typo in the Rect::outer function comments by @orhun in #2123
40f13c6 (rect) Update the outdated comment for Rect::area() by @isgin01 in #2100
The 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 @Blaeriz in #2071
Closes : https://github.com/ratatui/ratatui/issues/1200
b08b4cb (terminal) Add disclaimer
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
⚠️ List of breaking changes can be found here.
"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.
4c4851c (example) Add drawing feature to the canvas example by @orhun in #1429
fun fact: I had to do 35 pushups for this...
e5a7609 (line) Impl From<Cow<str>> for Line by @joshka in #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 @joshka in #1307
This 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 @nfachan in #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-dev in #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 @joshka in #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 @joshka in #1410
Improves 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 Sparkline by @fujiapple852 in #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 @kdheepak in #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.
7bdccce (uncategorized) Add an impl of DoubleEndedIterator for Columns and Rows by @fujiapple852 [breaking]
BREAKING-CHANGE:The
pubmodifier has been removed from fields on the
layout::rect::Columnsandlayout::rect::Rowsiterators. These fields were not intended to be public and should not have been accessed directly.Fixes:#1357
4f5503d (color) Hsl and hsluv are now clamped before conversion by @joshka in #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 @joshka in #1421
3df685e (rect) Rect::area now returns u32 and Rect::new() no longer clamps area to u16::MAX by @joshka in #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 @roberth in #1427
0f48239 (terminal) Resize() now resizes fixed viewports by @Patryk27 in #1353
Terminal::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 @Lunderberg in #1432
This 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 @joshka in #1437
b9653ba (uncategorized) Prevent calender render panic when terminal height is small by @adrodgers in #1380
Fixes:#1379
da821b4 (uncategorized) Clippy lints from rust 1.81.0 by @fujiapple852 in #1356
68886d1 (uncategorized) Add unstable-backend-writer feature by @Patryk27 in #1352
https://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.
6db16d6 (color) Use palette types for Hsl/Hsluv conversions by @orhun in #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 @kdheepak in #1397
This 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 @farmeroy in #1406
Fixes #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 @mo8it in #1345
b13e2f9 (backend) Added link to stdio FAQ by @Valentin271 in #1349
b88717b (constraint) Add note about percentages by @joshka in #1368
381ec75 (readme) Reduce the length by @joshka in #1431
Motivation 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 @joshka in #1419
4069aa8 (uncategorized) Fix missing breaking changes link by @joshka in #1416
870bc6a (uncategorized) Use Frame::area() instead of size() in examples by @hosseinnedaee in #1361
Frame::size()is deprecated
@joshka in #1372
ratatui::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 @joshka in #1434
When 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 @orhun in #1350
See:https://github.com/orhun/git-cliff-action/releases/tag/v4.0.0
69e0cd2 (deny) Allow Zlib license in cargo-deny configuration by @orhun in #1411
bc10af5 (style) Make Debug output for Text/Line/Span/Style more concise by @joshka in #1383
Given:```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 @joshka in #1430
9fd1bee (uncategorized) Make Positions iterator fields private by @joshka in #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 Table by @airblast-dev in #1408
5ad623c (uncategorized) Remove usage of prelude by @joshka in #1390
This 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 @orhun in #1403 [breaking]
We pin unicode-width to avoid breaking applications when there are breaking changes in the library.
Discussion in #1271
@Veetaha in #1362
https://github.com/bnjbvr/cargo-machete
@roberth made their first contribution in #1427@du-ob made their first contribution in #1333@farmeroy made their first contribution in #1406@adrodgers made their first contribution in #1380@Veetaha made their first contribution in #1362@hosseinnedaee made their first contribution in #1361@Patryk27 made their first contribution in #1352Full Changelog: https://github.com/ratatui/ratatui/compare/v0.28.1...v0.29.0
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
> is not deprecated by this approach. This just provides a simple one
ed51c4b (terminal) Add ratatui::init() and restore() methods by @joshka in #1289
These 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.
aed60b9 (terminal) Terminal::insert_before would crash when called while the viewport filled the screen by @nfachan in #1329
Reimplement 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
fdd5d8c (text) Remove trailing newline from single-line Display trait impl by @LucasPickering in #1320
2fb0b8a (uncategorized) Fix u16 overflow in Terminal::insert_before. by @nfachan in #1323
If 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
3631b34 (examples) Add widget implementation example by @joshka in #1147
This 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 @joshka in #1315
730dfd4 (examples) Show line gauge in demo example by @montmorill in #1309
9ed85fd (table) Fix incorrect backticks in TableState docs by @airblast-dev in #1342
6d1bd99 (uncategorized) Minor grammar fixes by @matta in #1330
097ee86 (uncategorized) Remove superfluous doc(inline) by @EdJoPaTo in #1310
It's no longer needed since #1260
3fdb5e8 (uncategorized) Fix typo in terminal.rs by @mrjackwills in #1313
0d5f3c0 (uncategorized) Avoid unneeded allocations in assertions by @mo8it in #1335
A vector can be compared to an array.
65da535 (ci) Update release strategy by @orhun in #1337
closes #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 @joshka in #1318
23516bc (uncategorized) Rename ratatui-org to ratatui by @joshka in #1334
All 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
0256269 (uncategorized) Simplify Windows build by @joshka in #1317
Termion 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.
@nfachan made their first contribution in #1329@LucasPickering made their first contribution in #1320@montmorill made their first contribution in #1309Full Changelog: https://github.com/ratatui/ratatui/compare/v0.28.0...v0.28.1
Nothing published for this version
Nothing published for this version
Nothing published for this version
⚠️ List of breaking changes can be found here.
"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.
8d4a102 (barchart) Allow axes to accept Lines by @joshka in #1273 [breaking]
a23ecd9 (buffer) Add Buffer::cell, cell_mut and index implementations by @joshka in #1084
Code 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 IntoIterator for axis labels by @EdJoPaTo in #1283 [breaking]
BREAKING CHANGES: #1273 is already breaking and this only advances the already breaking part
5b51018 (chart) Add GraphType::Bar by @joshka in #1205
f97e07c (frame) Replace Frame::size() with Frame::area() by @EdJoPaTo in #1293
Area 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 @EdJoPaTo in #1253
b2aa843 (layout) Enable serde for Margin, Position, Rect, Size by @EdJoPaTo in #1255
36d49e5 (table) Select first, last, etc to table state by @robertpsoane in #1198
Add select_previous, select_next, select_first & select_last to TableState
Used equivalent API as in ListState
3bb374d (terminal) Add Terminal::try_draw() method by @joshka in #1209
This 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 Add and AddAssign implementations for Line, Span, and Text by @joshka in #1236
This 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 @joshka in #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 @EdJoPaTo in #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 @josueBarretogit in #1267
Implement new methods
scroll_down_by(u16)andscroll_up_by(u16)for bothListstateandTablestate.Closes:#1207
864cd9f (testbackend) Prevent area mismatch by @EdJoPaTo in #1252
Removes 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 @EdJoPaTo in #1226
c08b522 (chart) Allow removing all the axis labels by @EdJoPaTo in #1282
axis.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-dev in #1235
The
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 @EdJoPaTo in #1257
84cb164 (terminal) Make terminal module private by @joshka in #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 @SUPERCILEX in #1270
cd93547 (uncategorized) Remove unnecessary synchronization in layout cache by @SUPERCILEX in #1245
Layout::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 Line by @joshka in #1247
A
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 @SUPERCILEX in #1237
84f3341 (uncategorized) Clippy lints from rust 1.80.0 by @joshka in #1238
bb68bc6 (backend) Return Size from Backend::size instead of Rect by @EdJoPaTo in #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 @joshka in #1204
e707ff1 (uncategorized) Internally use Position struct by @EdJoPaTo in #1256
32a0b26 (uncategorized) Simplify WordWrapper implementation by @tranzystorekk in #1193
6ce447c (block) Add docs about style inheritance by @joshka in #1190
55e0880 (block) Update block documentation by @leohscl in #1206
Update 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 @orhun in #1291
f687af7 (breaking-changes) Mention removed lifetime of ToText trait by @orhun in #1292
d468463 (breaking-changes) Fix the PR link by @orhun in #1294
1b9bdd4 (contributing) Fix minor issues by @EdJoPaTo in #1300
5f7a7fb (examples) Update barcharts gifs by @joshka in #1306
fe4eeab (examples) Simplify the barchart example by @joshka in #1079
The
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 @joshka in #1248
This 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 @kibibyt3 in #1225
Resolves:#1014
50e5674 (examples) Fix: fix typos in tape files by @kibibyt3 in #1224
810da72 (examples) Fix hyperlink example tape by @kibibyt3 in #1222
5eeb1cc (github) Create CODE_OF_CONDUCT.md by @joshka in #1279
bb71e5f (readme) Remove MSRV by @EdJoPaTo in #1266
This 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 @joshka in #1288
Addresses 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 @joshka in #1281
f775030 (uncategorized) Update main lib.rs / README examples by @joshka in #1280
8433d09 (uncategorized) Update demo image by @joshka in #1276
Follow up to https://github.com/ratatui/ratatui/pull/1203
663486f (list) Avoid extra allocations when rendering List by @airblast-dev in #1244
When 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 @SUPERCILEX in #1239
On 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 Table by @airblast-dev in #1242
When 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 @joshka in #1303
e6d2e04 (uncategorized) Move benchmarks into a single benchmark harness by @joshka in #1302
Consolidates 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.
a80a8a6 (format) Lint markdown by @joshka in #1131
- chore: Fix line endings for changelog
- chore: cleanup markdown lints
- ci: add Markdown linter
- build: add markdown lint to the makefile
82b70fd (ci) Integrate cargo-semver-checks by @orhun in #1166
cargo-semver-checks: Lint your crate API changes for semver violations.
c245c13 (ci) Onboard bencher for tracking benchmarks by @orhun in #1174
https://bencher.dev/console/projects/ratatui-org
Closes:#1092
efef0d0 (ci) Change label from breaking change to Type: Breaking Change by @kdheepak in #1243
This 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 @EdJoPaTo in #1081
Use GitHub organization team in CODEOWNERS and create MAINTAINERS.md
3e7458f (github) Add forums and faqs to the issue template by @joshka in #1201
45fcab7 (uncategorized) Add rect::rows benchmark by @joshka in #1301
edc2af9 (uncategorized) Replace big_text with hardcoded logo by @joshka in #1203
big_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 @joshka in #1269
a9fe428 (uncategorized) Update cargo-deny config by @EdJoPaTo in #1265
Update
cargo-denyconfig (noticed in https://github.com/ratatui/ratatui/pull/1263#pullrequestreview-2215488414)
ffc4300 (uncategorized) Remove executable flag for rs files by @EdJoPaTo in #1262
7bab9f0 (uncategorized) Add more CompactString::const_new instead of new by @joshka in #1230
ccf83e6 (uncategorized) Update labels in issue templates by @joshka in #1212
476ac87 (uncategorized) Split up lint job by @EdJoPaTo in #1264
This 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.
@SUPERCILEX made their first contribution in #1239
@josueBarretogit made their first contribution in #1267
@airblast-dev made their first contribution in #1242
@kibibyt3 made their first contribution in #1225
@EmiOnGit made their first contribution in #1217
@leohscl made their first contribution in #1206
@robertpsoane made their first contribution in #1198
Full Changelog: https://github.com/ratatui/ratatui/compare/v0.27.0...0.28.0
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
⚠️ List of breaking changes can be found here.
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.
eef1afe (linegauge) Allow LineGauge background styles by @nowNick in #565
This 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 @joshka in #1182
border::FULL uses a full block symbol, while border::EMPTY uses 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 @EdJoPaTo in #1143
This simplifies calls to `Buffer::filled` in tests.
3f2f2cd (docs) Add tracing example by @joshka in #1192
Add 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 @joshka in #1162
46977d8 (list) Add list navigation methods (first, last, previous, next) by @joshka in #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 List widget now clamps the selected index to the
bounds of the list when navigating with first, last, previous, and
next, as well as when setting the index directly with select.
10d7788 (style) Add conversions from the palette crate colors by @joshka in #1172
This 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 @orhun in #1167
Now 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 @joshka in #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 @kdheepak in #1103 [breaking]
0b5fd6b (uncategorized) Add writer() and writer_mut() to termion and crossterm backends by @enricozb in #991
It 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.
efa965e (line) Remove newlines when converting strings to Lines by @joshka in #1191
Line::from("a\nb") now returns a line with two Spans instead of 1
d370aa7 (span) Ensure that zero-width characters are rendered correctly by @joshka in #1165
127d706 (table) Ensure render offset without selection properly by @joshka in #1187
4bfdc15 (uncategorized) Render of &str and String doesn't respect area.width by @thscharler in #1177
e6871b9 (uncategorized) Avoid unicode-width breaking change in tests by @joshka in #1171
unicode-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 @joshka in #1170
semver 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 @EdJoPaTo in #1140
https://rust-lang.github.io/rust-clippy/master/index.html#string_slice
73fd367 (block) Group builder pattern methods by @EdJoPaTo in #1134
257db62 (cell) Must_use and simplify style() by @EdJoPaTo in #1124
<!-- Please read CONTRIBUTING.md before submitting any pull request. -->
bf20369 (cell) Reset instead of applying default by @EdJoPaTo in #1127
Using 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 @EdJoPaTo in #1138
https://rust-lang.github.io/rust-clippy/master/index.html#or_fun_call
4770e71 (list) Remove deprecated start_corner and Corner by @Valentin271 in #759 [breaking]
List::start_corner was deprecated in v0.25. Use List::direction and
ListDirection instead.
- 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::Corner is removed entirely.
4f77910 (padding) Add Padding::ZERO as a constant by @EdJoPaTo in #1133
Deprecate Padding::zero()
8061813 (uncategorized) Expand glob imports by @joshka in #1152
Consensus 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 @EdJoPaTo in #1142
Replace `impl Default` by `#[derive(Default)]` when its implementation
equals.
8a60a56 (uncategorized) Needless_pass_by_ref_mut by @EdJoPaTo in #1137
https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut
1de9a82 (uncategorized) Simplify if let by @EdJoPaTo in #1135
While 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.
1908b06 (borders) Add missing closing code blocks by @orhun in #1195
38bb196 (breaking-changes) Mention LineGauge::gauge_style by @orhun in #1194
see #565
07efde5 (examples) Add hyperlink example by @joshka in #1063
7fdccaf (examples) Add vhs tapes for constraint-explorer and minimal examples by @joshka in #1164
4f307e6 (examples) Simplify paragraph example by @joshka in #1169
f429f68 (examples) Remove lifetimes from the List example by @matta in #1132
Simplify 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 @EdJoPaTo in #1144
This 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
4ce67fc (buffer) Filled moves the cell to be filled by @EdJoPaTo in #1148 [breaking]
8b447ec (rect) Rect::inner takes Margin directly instead of reference by @EdJoPaTo in #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,
});
d6587bc (style) Use rstest by @EdJoPaTo in #1136
<!-- Please read CONTRIBUTING.md before submitting any pull request. -->
7b45f74 (prelude) Add / remove items by @joshka in #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 two
style methods and a set_style method.
symbols::Marker - this item is used by code that needs to draw to
the Canvas widget, 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 @joshka in #1186
8cfc316 (uncategorized) Alphabetize examples in Cargo.toml by @joshka in #1145
70df102 (bench) Improve benchmark consistency by @EdJoPaTo in #1126
Codegen 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
@thscharler made their first contribution in #1177@matta made their first contribution in #1132@nowNick made their first contribution in #565@enricozb made their first contribution in #991Full Changelog: https://github.com/ratatui/ratatui/compare/v0.26.3...v0.27.0
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →