use ratatui::style::{Color, Modifier, Style};
#[derive(Clone, Debug)]
pub enum Theme {
Dark,
Light,
}
impl Default for Theme {
fn default() -> Self {
Self::from_env()
}
}
impl Theme {
pub fn from_env() -> Self {
if let Ok(val) = std::env::var("KAGI_THEME") {
match val.to_lowercase().as_str() {
"light" => return Theme::Light,
"dark" => return Theme::Dark,
_ => {}
}
}
if let Ok(val) = std::env::var("COLORFGBG") {
let bg = val.split([';', ':']).nth(1);
if let Some(bg) = bg
&& let Ok(bg_num) = bg.parse::<u8>()
&& ((7..=15).contains(&bg_num) || (230..=255).contains(&bg_num))
{
return Theme::Light;
}
}
Theme::Dark
}
pub fn base(&self) -> Color {
match self {
Theme::Dark => Color::Rgb(26, 27, 38), Theme::Light => Color::Rgb(250, 248, 245), }
}
pub fn surface(&self) -> Color {
match self {
Theme::Dark => Color::Rgb(35, 38, 52), Theme::Light => Color::Rgb(240, 237, 232), }
}
pub fn overlay(&self) -> Color {
match self {
Theme::Dark => Color::Rgb(84, 88, 108), Theme::Light => Color::Rgb(180, 175, 168), }
}
pub fn text(&self) -> Color {
match self {
Theme::Dark => Color::Rgb(211, 213, 225), Theme::Light => Color::Rgb(45, 45, 55), }
}
pub fn muted(&self) -> Color {
match self {
Theme::Dark => Color::Rgb(130, 135, 155), Theme::Light => Color::Rgb(130, 128, 122), }
}
pub fn accent(&self) -> Color {
match self {
Theme::Dark => Color::Rgb(180, 142, 173), Theme::Light => Color::Rgb(140, 90, 120), }
}
pub fn success(&self) -> Color {
match self {
Theme::Dark => Color::Rgb(158, 206, 168), Theme::Light => Color::Rgb(80, 140, 100), }
}
pub fn warning(&self) -> Color {
match self {
Theme::Dark => Color::Rgb(235, 195, 140), Theme::Light => Color::Rgb(180, 130, 60), }
}
pub fn error(&self) -> Color {
match self {
Theme::Dark => Color::Rgb(230, 126, 126), Theme::Light => Color::Rgb(190, 70, 70), }
}
pub fn info(&self) -> Color {
match self {
Theme::Dark => Color::Rgb(140, 170, 210), Theme::Light => Color::Rgb(80, 120, 170), }
}
pub fn highlight_bg(&self) -> Color {
match self {
Theme::Dark => Color::Rgb(45, 48, 65), Theme::Light => Color::Rgb(225, 220, 212), }
}
pub fn border(&self) -> Color {
match self {
Theme::Dark => Color::Rgb(55, 58, 75), Theme::Light => Color::Rgb(200, 195, 188), }
}
pub fn header_style(&self) -> Style {
Style::default()
.fg(self.accent())
.add_modifier(Modifier::BOLD)
}
pub fn title_style(&self) -> Style {
Style::default()
.fg(self.text())
.add_modifier(Modifier::BOLD)
}
pub fn muted_style(&self) -> Style {
Style::default().fg(self.muted())
}
pub fn success_style(&self) -> Style {
Style::default()
.fg(self.success())
.add_modifier(Modifier::BOLD)
}
pub fn warning_style(&self) -> Style {
Style::default()
.fg(self.warning())
.add_modifier(Modifier::BOLD)
}
pub fn error_style(&self) -> Style {
Style::default()
.fg(self.error())
.add_modifier(Modifier::BOLD)
}
pub fn info_style(&self) -> Style {
Style::default()
.fg(self.info())
.add_modifier(Modifier::BOLD)
}
pub fn highlight_style(&self) -> Style {
Style::default().bg(self.highlight_bg()).fg(self.text())
}
pub fn block_style(&self) -> Style {
Style::default().fg(self.border())
}
pub fn logo_style(&self) -> Style {
Style::default()
.fg(self.accent())
.add_modifier(Modifier::BOLD)
}
pub fn key_hint_style(&self) -> Style {
Style::default()
.fg(self.accent())
.add_modifier(Modifier::BOLD)
}
pub fn key_desc_style(&self) -> Style {
Style::default().fg(self.muted())
}
pub fn footer_style(&self) -> Style {
Style::default().bg(self.surface()).fg(self.muted())
}
pub fn bg_style(&self) -> Style {
Style::default().bg(self.base())
}
}