fix(scrollbar): check for area.is_empty() before rendering (#1529)

This adds the `area.is_empty()` back into the scrollbar render method.
Without it, the widget panics if the height is 0.

Co-authored-by: Josh McKinney <joshka@users.noreply.github.com>
This commit is contained in:
Raffaele Cataldo
2024-11-30 16:36:49 -08:00
committed by GitHub
parent d201b8e5dd
commit 3b13240728

View File

@@ -504,12 +504,12 @@ impl StatefulWidget for Scrollbar<'_> {
return;
}
let mut bar = self.bar_symbols(area, state);
let area = self.scollbar_area(area);
for x in area.left()..area.right() {
for y in area.top()..area.bottom() {
if let Some(Some((symbol, style))) = bar.next() {
buf.set_string(x, y, symbol, style);
if let Some(area) = self.scrollbar_area(area) {
let areas = area.columns().flat_map(Rect::rows);
let bar_symbols = self.bar_symbols(area, state);
for (area, bar) in areas.zip(bar_symbols) {
if let Some((symbol, style)) = bar {
buf.set_string(area.x, area.y, symbol, style);
}
}
}
@@ -581,14 +581,13 @@ impl Scrollbar<'_> {
(thumb_start, thumb_length, track_end_length)
}
fn scollbar_area(&self, area: Rect) -> Rect {
fn scrollbar_area(&self, area: Rect) -> Option<Rect> {
match self.orientation {
ScrollbarOrientation::VerticalLeft => area.columns().next(),
ScrollbarOrientation::VerticalRight => area.columns().last(),
ScrollbarOrientation::HorizontalTop => area.rows().next(),
ScrollbarOrientation::HorizontalBottom => area.rows().last(),
}
.expect("Scrollbar area is empty") // this should never happen as we check for empty area
}
/// Calculates length of the track excluding the arrow heads
@@ -1065,4 +1064,20 @@ mod tests {
scrollbar_no_arrows.render(buffer.area, &mut buffer, &mut state);
assert_eq!(buffer, Buffer::with_lines([expected]));
}
#[rstest]
#[case::scrollbar_height_0(10, 0)]
#[case::scrollbar_width_0(0, 10)]
fn do_not_render_with_empty_area(#[case] width: u16, #[case] height: u16) {
let scrollbar = Scrollbar::new(ScrollbarOrientation::VerticalRight)
.begin_symbol(Some("<"))
.end_symbol(Some(">"))
.track_symbol(Some("-"))
.thumb_symbol("#");
let zero_width_area = Rect::new(0, 0, width, height);
let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 10));
let mut state = ScrollbarState::new(10);
scrollbar.render(zero_width_area, &mut buffer, &mut state);
}
}