1use gpui_kit::{Hsla, SharedString};
2
3use super::color::hex;
4
5#[derive(Clone, Debug, PartialEq)]
11#[non_exhaustive]
12pub struct ThemeConfig {
13 pub surface: Hsla,
15 pub ink: Hsla,
17 pub accent: Hsla,
19 pub contrast: u8,
21 pub fonts: ThemeFonts,
23 pub semantic: SemanticColors,
25}
26
27#[derive(Clone, Debug, PartialEq)]
29#[non_exhaustive]
30pub struct ThemeFonts {
31 pub ui: Option<SharedString>,
33 pub code: Option<SharedString>,
35}
36
37impl Default for ThemeFonts {
38 fn default() -> Self {
41 Self {
42 ui: None,
43 code: super::fonts::default_code_font(),
44 }
45 }
46}
47
48#[derive(Clone, Debug, PartialEq)]
50#[non_exhaustive]
51pub struct SemanticColors {
52 pub success: Hsla,
54 pub destructive: Hsla,
56 pub warning: Hsla,
58 pub skill: Hsla,
60}
61
62impl Default for ThemeConfig {
63 fn default() -> Self {
64 Self::light()
65 }
66}
67
68impl Default for SemanticColors {
69 fn default() -> Self {
70 Self::light()
71 }
72}
73
74impl ThemeConfig {
75 pub fn light() -> Self {
77 Self {
78 surface: hex("#ffffff"),
79 ink: hex("#1a1c1f"),
80 accent: hex("#339cff"),
81 contrast: 45,
82 fonts: ThemeFonts::default(),
83 semantic: SemanticColors::light(),
84 }
85 }
86
87 pub fn dark() -> Self {
89 Self {
90 surface: hex("#181818"),
91 ink: hex("#ffffff"),
92 accent: hex("#539af8"),
95 contrast: 60,
96 fonts: ThemeFonts::default(),
97 semantic: SemanticColors::dark(),
98 }
99 }
100}
101
102impl SemanticColors {
103 pub fn light() -> Self {
105 Self {
106 success: hex("#00a240"),
107 destructive: hex("#ba2623"),
108 warning: hex("#b45309"),
109 skill: hex("#924ff7"),
110 }
111 }
112
113 pub fn dark() -> Self {
115 Self {
116 success: hex("#40c977"),
117 destructive: hex("#fa423e"),
118 warning: hex("#f59e0b"),
119 skill: hex("#ad7bf9"),
120 }
121 }
122}
123
124#[cfg(test)]
125mod tests {
126 use super::*;
127
128 #[test]
129 fn light_and_dark_differ_in_surface_and_accent() {
130 let light = ThemeConfig::light();
131 let dark = ThemeConfig::dark();
132 assert_ne!(light.accent, dark.accent);
133 assert_ne!(light.surface, dark.surface);
134 assert_eq!(light.contrast, 45);
135 assert_eq!(dark.contrast, 60);
136 assert_eq!(ThemeConfig::default(), light);
137 }
138}