Skip to main content

ai_usagebar/tui/
style.rs

1//! Shared TUI styling adapters.
2
3use ratatui::style::Color;
4use ratatui_bubbletea_theme::{BubbleTheme, Palette, Symbols};
5
6use crate::pacing::PaceSeverity;
7use crate::theme::Theme;
8
9/// Build a Charm/Bubble Tea-style theme while preserving this app's configured
10/// foreground, dim, and health colors where possible.
11pub fn bubble_theme(theme: &Theme) -> BubbleTheme {
12    let charm = Palette::CHARM;
13    let palette = Palette {
14        foreground: color(&theme.fg).unwrap_or(charm.foreground),
15        muted: color(&theme.dim).unwrap_or(charm.muted),
16        accent: charm.accent,
17        success: color(&theme.green).unwrap_or(charm.success),
18        warning: color(&theme.yellow).unwrap_or(charm.warning),
19        error: color(&theme.red).unwrap_or(charm.error),
20        border: color(&theme.dim).unwrap_or(charm.border),
21        focused_border: color(&theme.blue).unwrap_or(charm.focused_border),
22        selected_background: color(&theme.bar_empty).unwrap_or(charm.selected_background),
23    };
24    BubbleTheme::new(palette, Symbols::default())
25}
26
27pub fn color(hex: &str) -> Option<Color> {
28    let (r, g, b) = crate::theme::parse_hex_rgb(hex)?;
29    Some(Color::Rgb(r, g, b))
30}
31
32pub fn severity_color(theme: &Theme, bubble: &BubbleTheme, severity: PaceSeverity) -> Color {
33    match severity {
34        PaceSeverity::Low => bubble.palette.success,
35        PaceSeverity::Mid => bubble.palette.warning,
36        PaceSeverity::High => color(&theme.orange).unwrap_or(bubble.palette.warning),
37        PaceSeverity::Critical => bubble.palette.error,
38    }
39}
40
41pub fn progress_theme(base: BubbleTheme, filled: Color, empty: Color) -> BubbleTheme {
42    let mut palette = base.palette;
43    palette.accent = filled;
44    palette.muted = empty;
45    BubbleTheme::new(palette, base.symbols)
46}