fix: fix truncation of left aligned block titles (#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
This commit is contained in:
Josh McKinney
2025-06-25 21:56:40 -07:00
committed by GitHub
parent 0c3872f1c5
commit 80bc818723
2 changed files with 77 additions and 10 deletions

View File

@@ -780,9 +780,9 @@ impl Block<'_> {
fn render_title_position(&self, position: TitlePosition, area: Rect, buf: &mut Buffer) {
// NOTE: the order in which these functions are called defines the overlapping behavior
self.render_right_titles(position, area, buf);
self.render_center_titles(position, area, buf);
self.render_left_titles(position, area, buf);
self.render_center_titles(position, area, buf);
self.render_right_titles(position, area, buf);
}
/// Render titles aligned to the right of the block
@@ -1824,4 +1824,70 @@ mod tests {
}
pretty_assertions::assert_eq!(Buffer::with_lines(expected.lines()), buffer);
}
#[test]
fn left_titles_truncated() {
let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 1));
Block::new()
.title("L12345")
.title("L67890")
.render(buffer.area, &mut buffer);
assert_eq!(buffer, Buffer::with_lines(["L12345 L67"]));
}
/// Note: this test is probably not what you'd expect, but it is how it works in the current
/// implementation. Update this if the behavior changes.
///
/// This probably should render the titles centered as a whole and then truncate both titles
/// to fit, but instead it renders each title and truncates them individually. This causes the
/// left title to be displayed in full, while the right title is truncated.
#[test]
fn center_titles_truncated() {
let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 1));
Block::new()
.title(Line::from("C12345").centered())
.title(Line::from("C67890").centered())
.render(buffer.area, &mut buffer);
assert_eq!(buffer, Buffer::with_lines(["C12345 678"]));
}
#[test]
fn right_titles_truncated() {
let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 1));
Block::new()
.title(Line::from("R12345").right_aligned())
.title(Line::from("R67890").right_aligned())
.render(buffer.area, &mut buffer);
assert_eq!(buffer, Buffer::with_lines(["345 R67890"]));
}
#[test]
fn center_title_truncates_left_title() {
let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 1));
Block::new()
.title("L1234")
.title(Line::from("C5678").centered())
.render(buffer.area, &mut buffer);
assert_eq!(buffer, Buffer::with_lines(["L1C5678 "]));
}
#[test]
fn right_title_truncates_left_title() {
let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 1));
Block::new()
.title("L12345")
.title(Line::from("R67890").right_aligned())
.render(buffer.area, &mut buffer);
assert_eq!(buffer, Buffer::with_lines(["L123R67890"]));
}
#[test]
fn right_title_truncates_center_title() {
let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 1));
Block::new()
.title(Line::from("C12345").centered())
.title(Line::from("R67890").right_aligned())
.render(buffer.area, &mut buffer);
assert_eq!(buffer, Buffer::with_lines([" C1R67890"]));
}
}

View File

@@ -50,27 +50,28 @@ fn widgets_block_titles_overlap() {
terminal.backend().assert_buffer_lines(expected);
}
// Left overrides the center
// Center overrides left titles
test_case(
Block::new()
.title(Line::from("aaaaa").left_aligned())
.title(Line::from("bbb").centered())
.title(Line::from("ccc").right_aligned()),
Rect::new(0, 0, 10, 1),
["aaaaab ccc"],
["aaabbb ccc"],
);
// Left alignment overrides the center alignment which overrides the right alignment
// Right alignment overrides the center alignment which overrides the left alignment
test_case(
Block::new()
.title(Line::from("aaaaa").left_aligned())
.title(Line::from("bbbbb").centered())
.title(Line::from("ccccc").right_aligned()),
Rect::new(0, 0, 11, 1),
["aaaaabbbccc"],
["aaabbbccccc"],
);
// Multiple left alignment overrides the center alignment and the right alignment
// Center alignment overwrites multiple left alignment, right alignment overwrites center
// alignment
test_case(
Block::new()
.title(Line::from("aaaaa").left_aligned())
@@ -78,16 +79,16 @@ fn widgets_block_titles_overlap() {
.title(Line::from("bbbbb").centered())
.title(Line::from("ccccc").right_aligned()),
Rect::new(0, 0, 11, 1),
["aaaaabaaaaa"],
["aaabbbccccc"],
);
// The right alignment doesn't override the center alignment, but pierces through it
// Right alignment overrides the center alignment
test_case(
Block::new()
.title(Line::from("bbbbb").centered())
.title(Line::from("ccccccccccc").right_aligned()),
Rect::new(0, 0, 11, 1),
["cccbbbbbccc"],
["ccccccccccc"],
);
}