Keep TUI sidebar selections visible.

This commit is contained in:
2026-08-07 15:32:00 +02:00
parent 358648378e
commit 0417aaf749
3 changed files with 53 additions and 12 deletions

View File

@@ -25,7 +25,9 @@ use ratatui::layout::Size;
use ratatui::layout::{Constraint, Direction, Layout, Rect};
use ratatui::style::{Color, Modifier, Style};
use ratatui::text::{Line, Span, Text};
use ratatui::widgets::{Block, Borders, Clear, Paragraph, Widget, Wrap};
use ratatui::widgets::{
Block, Borders, Clear, List, ListItem, ListState, Paragraph, StatefulWidget, Widget, Wrap,
};
use ratatui_image::picker::Picker;
use ratatui_image::protocol::Protocol;
use ratatui_image::{Image as TerminalImage, Resize};
@@ -3302,14 +3304,8 @@ impl TuiApp {
let rows = self
.items
.iter()
.enumerate()
.map(|(index, item)| {
let style = if index == self.selected_index && self.focus == Focus::Sidebar {
Style::default()
.bg(Color::Rgb(54, 61, 78))
.fg(Color::White)
.add_modifier(Modifier::BOLD)
} else if matches!(item, SidebarItem::Header(_)) {
.map(|item| {
let style = if matches!(item, SidebarItem::Header(_)) {
Style::default()
.fg(Color::Rgb(126, 137, 160))
.add_modifier(Modifier::BOLD)
@@ -3321,10 +3317,27 @@ impl TuiApp {
} else {
" "
};
Line::styled(format!("{prefix}{}", item.label(self.locale)), style)
ListItem::new(Line::styled(
format!("{prefix}{}", item.label(self.locale)),
style,
))
})
.collect::<Vec<_>>();
Paragraph::new(rows).render(inner, buffer);
let highlight = if self.focus == Focus::Sidebar {
Style::default()
.bg(Color::Rgb(54, 61, 78))
.fg(Color::White)
.add_modifier(Modifier::BOLD)
} else {
Style::default()
};
let mut state = ListState::default().with_selected(Some(self.selected_index));
StatefulWidget::render(
List::new(rows).highlight_style(highlight),
inner,
buffer,
&mut state,
);
}
fn render_main(&self, area: Rect, buffer: &mut Buffer) {
@@ -4198,6 +4211,31 @@ mod tests {
assert_eq!(app.view, TuiView::Settings);
}
#[test]
fn sidebar_scroll_follows_j_and_k_selection() {
let fixture = Fixture::new();
let mut app = fixture.app(false);
app.items = (0..20)
.map(|index| SidebarItem::Post(index.to_string(), format!("Post {index:02}")))
.collect();
app.selected_index = 0;
for _ in 0..12 {
app.handle_input(TuiInput::plain(TuiKey::Char('j')))
.unwrap();
}
let scrolled_down = rendered_text(&app, 50, 10);
assert!(scrolled_down.contains("Post 12"));
assert!(!scrolled_down.contains("Post 00"));
for _ in 0..12 {
app.handle_input(TuiInput::plain(TuiKey::Char('k')))
.unwrap();
}
let scrolled_up = rendered_text(&app, 50, 10);
assert!(scrolled_up.contains("Post 00"));
}
#[test]
fn posts_templates_and_scripts_edit_validate_save_and_publish_through_shared_engines() {
let fixture = Fixture::new();