use gpui_kit::{Hsla, SharedString};
use super::color::hex;
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub struct ThemeConfig {
pub surface: Hsla,
pub ink: Hsla,
pub accent: Hsla,
pub contrast: u8,
pub fonts: ThemeFonts,
pub semantic: SemanticColors,
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub struct ThemeFonts {
pub ui: Option<SharedString>,
pub code: Option<SharedString>,
}
impl Default for ThemeFonts {
fn default() -> Self {
Self {
ui: None,
code: super::fonts::default_code_font(),
}
}
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub struct SemanticColors {
pub success: Hsla,
pub destructive: Hsla,
pub warning: Hsla,
pub info: Hsla,
pub skill: Hsla,
}
impl Default for ThemeConfig {
fn default() -> Self {
Self::light()
}
}
impl Default for SemanticColors {
fn default() -> Self {
Self::light()
}
}
impl ThemeConfig {
pub fn light() -> Self {
Self {
surface: hex("#ffffff"),
ink: hex("#1a1c1f"),
accent: hex("#339cff"),
contrast: 45,
fonts: ThemeFonts::default(),
semantic: SemanticColors::light(),
}
}
pub fn dark() -> Self {
Self {
surface: hex("#181818"),
ink: hex("#ffffff"),
accent: hex("#539af8"),
contrast: 60,
fonts: ThemeFonts::default(),
semantic: SemanticColors::dark(),
}
}
}
impl SemanticColors {
pub fn light() -> Self {
Self {
success: hex("#00a240"),
destructive: hex("#ba2623"),
warning: hex("#b45309"),
info: hex("#2563eb"),
skill: hex("#924ff7"),
}
}
pub fn dark() -> Self {
Self {
success: hex("#40c977"),
destructive: hex("#fa423e"),
warning: hex("#f59e0b"),
info: hex("#60a5fa"),
skill: hex("#ad7bf9"),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn light_and_dark_differ_in_surface_and_accent() {
let light = ThemeConfig::light();
let dark = ThemeConfig::dark();
assert_ne!(light.accent, dark.accent);
assert_ne!(light.surface, dark.surface);
assert_eq!(light.contrast, 45);
assert_eq!(dark.contrast, 60);
assert_eq!(ThemeConfig::default(), light);
}
}