Skip to main content

oracle_lib/ui/components/
tabs.rs

1//! Tab bar component
2
3use ratatui::{
4    buffer::Buffer,
5    layout::Rect,
6    style::Style,
7    widgets::{Block, Borders, Tabs, Widget},
8};
9
10use crate::ui::theme::Theme;
11
12/// A tab bar widget
13pub struct TabBar<'a> {
14    titles: Vec<&'a str>,
15    selected: usize,
16    theme: &'a Theme,
17    focused: bool,
18}
19
20impl<'a> TabBar<'a> {
21    pub fn new(titles: Vec<&'a str>, theme: &'a Theme) -> Self {
22        Self {
23            titles,
24            selected: 0,
25            theme,
26            focused: false,
27        }
28    }
29
30    pub fn select(mut self, index: usize) -> Self {
31        self.selected = index;
32        self
33    }
34
35    pub fn focused(mut self, focused: bool) -> Self {
36        self.focused = focused;
37        self
38    }
39}
40
41impl Widget for TabBar<'_> {
42    fn render(self, area: Rect, buf: &mut Buffer) {
43        let selected_style = self.theme.style_tab_active();
44        let inactive_style = self.theme.style_dim();
45
46        let border_style = if self.focused {
47            self.theme.style_border_focused()
48        } else {
49            self.theme.style_border()
50        };
51        let block = Block::default()
52            .borders(Borders::ALL)
53            .border_style(border_style)
54            .style(Style::default().bg(self.theme.bg_panel))
55            .title(" Tabs ");
56
57        let tabs = Tabs::new(self.titles)
58            .select(self.selected)
59            .style(inactive_style)
60            .highlight_style(selected_style)
61            .block(block)
62            .divider(" │ ")
63            .padding("    ", "    ");
64
65        tabs.render(area, buf);
66    }
67}