From 6d2ec7ad5f0eb2c774ee4a9c8e6d1018fcfc6405 Mon Sep 17 00:00:00 2001 From: David Hagerty Date: Sat, 24 Jan 2026 07:48:14 -0800 Subject: [PATCH] feat(tui): add tab bar widget --- src/tui/widgets/mod.rs | 3 +++ src/tui/widgets/tabs.rs | 46 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 src/tui/widgets/mod.rs create mode 100644 src/tui/widgets/tabs.rs diff --git a/src/tui/widgets/mod.rs b/src/tui/widgets/mod.rs new file mode 100644 index 0000000..b9851e5 --- /dev/null +++ b/src/tui/widgets/mod.rs @@ -0,0 +1,3 @@ +mod tabs; + +pub use tabs::TabBar; diff --git a/src/tui/widgets/tabs.rs b/src/tui/widgets/tabs.rs new file mode 100644 index 0000000..6d06cfe --- /dev/null +++ b/src/tui/widgets/tabs.rs @@ -0,0 +1,46 @@ +use ratatui::{ + buffer::Buffer, + layout::Rect, + style::{Color, Modifier, Style}, + text::{Line, Span}, + widgets::{Tabs as RataTabs, Widget}, +}; + +use crate::tui::ActiveTab; + +pub struct TabBar { + active: ActiveTab, +} + +impl TabBar { + pub fn new(active: ActiveTab) -> Self { + Self { active } + } +} + +impl Widget for TabBar { + fn render(self, area: Rect, buf: &mut Buffer) { + let titles = vec![ + Line::from("[1] Dashboard"), + Line::from("[2] Planning"), + Line::from("[3] Execution"), + ]; + let selected = match self.active { + ActiveTab::Dashboard => 0, + ActiveTab::Planning => 1, + ActiveTab::Execution => 2, + }; + + let tabs = RataTabs::new(titles) + .select(selected) + .style(Style::default().fg(Color::White)) + .highlight_style( + Style::default() + .fg(Color::Yellow) + .add_modifier(Modifier::BOLD), + ) + .divider(Span::raw(" │ ")); + + tabs.render(area, buf); + } +} -- 2.51.2