1#![warn(missing_docs)]
24#![forbid(unsafe_code)]
25
26pub mod colors;
27pub mod config;
28pub mod derive;
29pub mod icons;
30
31use gpui_component::theme::{Theme, ThemeMode};
32use native_theme::{NativeTheme, ThemeVariant};
33
34#[deprecated(since = "0.3.2", note = "Use NativeTheme::pick_variant() instead")]
39#[allow(deprecated)]
40pub fn pick_variant(theme: &NativeTheme, is_dark: bool) -> Option<&ThemeVariant> {
41 theme.pick_variant(is_dark)
42}
43
44pub fn to_theme(variant: &ThemeVariant, name: &str, is_dark: bool) -> Theme {
51 let theme_color = colors::to_theme_color(variant);
52 let mode = if is_dark {
53 ThemeMode::Dark
54 } else {
55 ThemeMode::Light
56 };
57 let theme_config = config::to_theme_config(variant, name, mode);
58
59 let mut theme = Theme::from(&theme_color);
66 theme.apply_config(&theme_config.into());
67 theme.colors = theme_color;
68 theme
69}
70
71#[cfg(test)]
72#[allow(deprecated)]
73mod tests {
74 use super::*;
75 use native_theme::Rgba;
76
77 #[test]
78 fn pick_variant_light_first() {
79 let mut theme = NativeTheme::new("Test");
80 let mut light = ThemeVariant::default();
81 light.colors.background = Some(Rgba::rgb(255, 255, 255));
82 theme.light = Some(light);
83
84 let picked = pick_variant(&theme, false);
85 assert!(picked.is_some());
86 assert_eq!(
87 picked.unwrap().colors.background,
88 Some(Rgba::rgb(255, 255, 255))
89 );
90 }
91
92 #[test]
93 fn pick_variant_dark_first() {
94 let mut theme = NativeTheme::new("Test");
95 let mut dark = ThemeVariant::default();
96 dark.colors.background = Some(Rgba::rgb(30, 30, 30));
97 theme.dark = Some(dark);
98
99 let picked = pick_variant(&theme, true);
100 assert!(picked.is_some());
101 assert_eq!(
102 picked.unwrap().colors.background,
103 Some(Rgba::rgb(30, 30, 30))
104 );
105 }
106
107 #[test]
108 fn pick_variant_fallback() {
109 let mut theme = NativeTheme::new("Test");
110 let mut light = ThemeVariant::default();
111 light.colors.background = Some(Rgba::rgb(255, 255, 255));
112 theme.light = Some(light);
113 let picked = pick_variant(&theme, true);
115 assert!(picked.is_some());
116 }
117
118 #[test]
119 fn pick_variant_empty_returns_none() {
120 let theme = NativeTheme::new("Empty");
121 assert!(pick_variant(&theme, false).is_none());
122 assert!(pick_variant(&theme, true).is_none());
123 }
124
125 #[test]
126 fn to_theme_produces_valid_theme() {
127 let mut variant = ThemeVariant::default();
128 variant.colors.background = Some(Rgba::rgb(255, 255, 255));
129 variant.colors.foreground = Some(Rgba::rgb(0, 0, 0));
130 variant.colors.accent = Some(Rgba::rgb(0, 120, 215));
131 variant.fonts.family = Some("Inter".into());
132 variant.fonts.size = Some(14.0);
133 variant.geometry.radius = Some(4.0);
134
135 let theme = to_theme(&variant, "Test", false);
136
137 assert!(!theme.is_dark());
139 }
140}