use ratatui::style::{Color, Modifier, Style};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Theme {
#[default]
Default,
Dracula,
SolarizedDark,
SolarizedLight,
GruvboxDark,
GruvboxLight,
}
impl Theme {
pub const ALL: [Theme; 6] = [
Theme::Default,
Theme::Dracula,
Theme::SolarizedDark,
Theme::SolarizedLight,
Theme::GruvboxDark,
Theme::GruvboxLight,
];
pub fn label(self) -> &'static str {
match self {
Theme::Default => "Default",
Theme::Dracula => "Dracula",
Theme::SolarizedDark => "Solarized Dark",
Theme::SolarizedLight => "Solarized Light",
Theme::GruvboxDark => "Gruvbox Dark",
Theme::GruvboxLight => "Gruvbox Light",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum GraphStyle {
#[default]
Dots,
Bars,
}
impl GraphStyle {
pub const ALL: [GraphStyle; 2] = [GraphStyle::Dots, GraphStyle::Bars];
pub fn label(self) -> &'static str {
match self {
GraphStyle::Dots => "Dots",
GraphStyle::Bars => "Bars",
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct Palette {
pub background: Color,
pub foreground: Color,
pub claude: Color,
pub codex: Color,
pub child: Color,
pub border: Color,
pub title: Color,
pub header: Color,
pub selected_bg: Color,
pub label: Color,
pub dim: Color,
}
impl Palette {
pub fn from_theme(theme: Theme) -> Self {
match theme {
Theme::Default => Self {
background: Color::Rgb(20, 20, 35),
foreground: Color::Rgb(220, 220, 220),
claude: Color::Rgb(204, 120, 50),
codex: Color::Rgb(100, 200, 100),
child: Color::Rgb(160, 160, 160),
border: Color::Rgb(90, 90, 90),
title: Color::Rgb(240, 240, 240),
header: Color::Rgb(235, 206, 50),
selected_bg: Color::Rgb(60, 60, 60),
label: Color::Rgb(235, 206, 50),
dim: Color::Rgb(100, 100, 100),
},
Theme::Dracula => Self {
background: Color::Rgb(40, 42, 54), foreground: Color::Rgb(248, 248, 242), claude: Color::Rgb(255, 121, 198), codex: Color::Rgb(80, 250, 123), child: Color::Rgb(98, 114, 164), border: Color::Rgb(68, 71, 90), title: Color::Rgb(248, 248, 242), header: Color::Rgb(241, 250, 140), selected_bg: Color::Rgb(68, 71, 90),
label: Color::Rgb(189, 147, 249), dim: Color::Rgb(98, 114, 164), },
Theme::SolarizedDark => Self {
background: Color::Rgb(0, 43, 54), foreground: Color::Rgb(131, 148, 150), claude: Color::Rgb(203, 75, 22), codex: Color::Rgb(133, 153, 0), child: Color::Rgb(131, 148, 150), border: Color::Rgb(88, 110, 117), title: Color::Rgb(147, 161, 161), header: Color::Rgb(181, 137, 0), selected_bg: Color::Rgb(7, 54, 66), label: Color::Rgb(181, 137, 0), dim: Color::Rgb(88, 110, 117), },
Theme::SolarizedLight => Self {
background: Color::Rgb(253, 246, 227), foreground: Color::Rgb(101, 123, 131), claude: Color::Rgb(203, 75, 22), codex: Color::Rgb(133, 153, 0), child: Color::Rgb(101, 123, 131), border: Color::Rgb(147, 161, 161), title: Color::Rgb(88, 110, 117), header: Color::Rgb(181, 137, 0), selected_bg: Color::Rgb(238, 232, 213), label: Color::Rgb(38, 139, 210), dim: Color::Rgb(147, 161, 161), },
Theme::GruvboxDark => Self {
background: Color::Rgb(40, 40, 40), foreground: Color::Rgb(235, 219, 178), claude: Color::Rgb(254, 128, 25), codex: Color::Rgb(184, 187, 38), child: Color::Rgb(168, 153, 132), border: Color::Rgb(80, 73, 69), title: Color::Rgb(235, 219, 178), header: Color::Rgb(250, 189, 47), selected_bg: Color::Rgb(80, 73, 69), label: Color::Rgb(250, 189, 47), dim: Color::Rgb(146, 131, 116), },
Theme::GruvboxLight => Self {
background: Color::Rgb(251, 241, 199), foreground: Color::Rgb(60, 56, 54), claude: Color::Rgb(175, 58, 3), codex: Color::Rgb(121, 116, 14), child: Color::Rgb(102, 92, 84), border: Color::Rgb(213, 196, 161), title: Color::Rgb(60, 56, 54), header: Color::Rgb(181, 118, 20), selected_bg: Color::Rgb(213, 196, 161), label: Color::Rgb(7, 102, 120), dim: Color::Rgb(146, 131, 116), },
}
}
pub fn base_style(&self) -> Style {
Style::new().bg(self.background).fg(self.foreground)
}
pub fn claude_style(&self) -> Style {
Style::new().fg(self.claude)
}
pub fn codex_style(&self) -> Style {
Style::new().fg(self.codex)
}
pub fn child_style(&self) -> Style {
Style::new().fg(self.child)
}
pub fn border_style(&self) -> Style {
Style::new().fg(self.border)
}
pub fn title_style(&self) -> Style {
Style::new().fg(self.title).add_modifier(Modifier::BOLD)
}
pub fn header_style(&self) -> Style {
Style::new().fg(self.header).add_modifier(Modifier::BOLD)
}
pub fn selected_style(&self) -> Style {
Style::new().bg(self.selected_bg).add_modifier(Modifier::BOLD)
}
pub fn label_style(&self) -> Style {
Style::new().fg(self.label)
}
pub fn dim_style(&self) -> Style {
Style::new().fg(self.dim)
}
}
impl Default for Palette {
fn default() -> Self {
Self::from_theme(Theme::Default)
}
}