Skip to main content

gpui_component/theme/
theme_color.rs

1use std::{ops::Deref, sync::Arc};
2
3use crate::{ThemeMode, theme::DEFAULT_THEME_COLORS};
4
5use gpui::{Background, Fill, Hsla};
6use schemars::JsonSchema;
7use serde::{Deserialize, Serialize};
8
9/// A theme token that keeps a solid representative color and its renderable background.
10#[derive(Debug, Default, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema)]
11pub struct ThemeToken {
12    pub color: Hsla,
13    pub background: Background,
14}
15
16impl ThemeToken {
17    pub fn new(color: Hsla, background: Background) -> Self {
18        Self { color, background }
19    }
20}
21
22impl Deref for ThemeToken {
23    type Target = Hsla;
24
25    fn deref(&self) -> &Self::Target {
26        &self.color
27    }
28}
29
30impl From<Hsla> for ThemeToken {
31    fn from(color: Hsla) -> Self {
32        Self {
33            color,
34            background: color.into(),
35        }
36    }
37}
38
39impl From<ThemeToken> for Hsla {
40    fn from(token: ThemeToken) -> Self {
41        token.color
42    }
43}
44
45impl From<ThemeToken> for Background {
46    fn from(token: ThemeToken) -> Self {
47        token.background
48    }
49}
50
51impl From<ThemeToken> for Fill {
52    fn from(token: ThemeToken) -> Self {
53        Fill::Color(token.background)
54    }
55}
56
57/// Theme colors used throughout the UI components.
58#[derive(Debug, Default, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema)]
59pub struct ThemeColor {
60    /// Used for accents such as hover background on MenuItem, ListItem, etc.
61    pub accent: Hsla,
62    /// Used for accent text color.
63    pub accent_foreground: Hsla,
64    /// Accordion background color.
65    pub accordion: Hsla,
66    /// Default background color.
67    pub background: Hsla,
68    /// Default border color
69    pub border: Hsla,
70    /// Default Button background color.
71    pub button: Hsla,
72    /// Default Button active background color.
73    pub button_active: Hsla,
74    /// Default Button text color.
75    pub button_foreground: Hsla,
76    /// Default Button hover background color.
77    pub button_hover: Hsla,
78    /// Button danger background color, fallback to `danger`.
79    pub button_danger: Hsla,
80    /// Button danger active background color, fallback to `danger_active`.
81    pub button_danger_active: Hsla,
82    /// Button danger text color, fallback to `danger_foreground`.
83    pub button_danger_foreground: Hsla,
84    /// Button danger hover background color, fallback to `danger_hover`.
85    pub button_danger_hover: Hsla,
86    /// Button info background color, fallback to `info`.
87    pub button_info: Hsla,
88    /// Button info active background color, fallback to `info_active`.
89    pub button_info_active: Hsla,
90    /// Button info text color, fallback to `info_foreground`.
91    pub button_info_foreground: Hsla,
92    /// Button info hover background color, fallback to `info_hover`.
93    pub button_info_hover: Hsla,
94    /// Button primary background color, fallback to `primary`.
95    pub button_primary: Hsla,
96    /// Button primary active background color, fallback to `primary_active`.
97    pub button_primary_active: Hsla,
98    /// Button primary text color, fallback to `primary_foreground`.
99    pub button_primary_foreground: Hsla,
100    /// Button primary hover background color, fallback to `primary_hover`.
101    pub button_primary_hover: Hsla,
102    /// Button secondary background color, fallback to `secondary`.
103    pub button_secondary: Hsla,
104    /// Button secondary active background color, fallback to `secondary_active`.
105    pub button_secondary_active: Hsla,
106    /// Button secondary text color, fallback to `secondary_foreground`.
107    pub button_secondary_foreground: Hsla,
108    /// Button secondary hover background color, fallback to `secondary_hover`.
109    pub button_secondary_hover: Hsla,
110    /// Button success background color, fallback to `success`.
111    pub button_success: Hsla,
112    /// Button success active background color, fallback to `success_active`.
113    pub button_success_active: Hsla,
114    /// Button success text color, fallback to `success_foreground`.
115    pub button_success_foreground: Hsla,
116    /// Button success hover background color, fallback to `success_hover`.
117    pub button_success_hover: Hsla,
118    /// Button warning background color, fallback to `warning`.
119    pub button_warning: Hsla,
120    /// Button warning active background color, fallback to `warning_active`.
121    pub button_warning_active: Hsla,
122    /// Button warning text color, fallback to `warning_foreground`.
123    pub button_warning_foreground: Hsla,
124    /// Button warning hover background color, fallback to `warning_hover`.
125    pub button_warning_hover: Hsla,
126    /// Background color for GroupBox.
127    pub group_box: Hsla,
128    /// Text color for GroupBox.
129    pub group_box_foreground: Hsla,
130    /// Input caret color (Blinking cursor).
131    pub caret: Hsla,
132    /// Chart 1 color (`chart.1` in the theme file).
133    pub chart_1: Hsla,
134    /// Chart 2 color (`chart.2` in the theme file).
135    pub chart_2: Hsla,
136    /// Chart 3 color (`chart.3` in the theme file).
137    pub chart_3: Hsla,
138    /// Chart 4 color (`chart.4` in the theme file).
139    pub chart_4: Hsla,
140    /// Chart 5 color (`chart.5` in the theme file).
141    pub chart_5: Hsla,
142    /// Bullish color for candlestick charts (upward price movement).
143    pub chart_bullish: Hsla,
144    /// Bearish color for candlestick charts (downward price movement).
145    pub chart_bearish: Hsla,
146    /// Danger background color.
147    pub danger: Hsla,
148    /// Danger active background color.
149    pub danger_active: Hsla,
150    /// Danger text color.
151    pub danger_foreground: Hsla,
152    /// Danger hover background color.
153    pub danger_hover: Hsla,
154    /// Description List label background color.
155    pub description_list_label: Hsla,
156    /// Description List label foreground color.
157    pub description_list_label_foreground: Hsla,
158    /// Drag border color.
159    pub drag_border: Hsla,
160    /// Drop target background color.
161    pub drop_target: Hsla,
162    /// Default text color.
163    pub foreground: Hsla,
164    /// Info background color.
165    pub info: Hsla,
166    /// Info active background color.
167    pub info_active: Hsla,
168    /// Info text color.
169    pub info_foreground: Hsla,
170    /// Info hover background color.
171    pub info_hover: Hsla,
172    /// Border color for inputs such as Input, Select, etc.
173    pub input: Hsla,
174    /// Link text color.
175    pub link: Hsla,
176    /// Active link text color.
177    pub link_active: Hsla,
178    /// Hover link text color.
179    pub link_hover: Hsla,
180    /// Background color for List and ListItem.
181    pub list: Hsla,
182    /// Background color for active ListItem.
183    pub list_active: Hsla,
184    /// Border color for active ListItem.
185    pub list_active_border: Hsla,
186    /// Stripe background color for even ListItem.
187    pub list_even: Hsla,
188    /// Background color for List header.
189    pub list_head: Hsla,
190    /// Hover background color for ListItem.
191    pub list_hover: Hsla,
192    /// Muted backgrounds such as Skeleton and Switch.
193    pub muted: Hsla,
194    /// Muted text color, as used in disabled text.
195    pub muted_foreground: Hsla,
196    /// Background color for Popover.
197    pub popover: Hsla,
198    /// Text color for Popover.
199    pub popover_foreground: Hsla,
200    /// Primary background color.
201    pub primary: Hsla,
202    /// Active primary background color.
203    pub primary_active: Hsla,
204    /// Primary text color.
205    pub primary_foreground: Hsla,
206    /// Hover primary background color.
207    pub primary_hover: Hsla,
208    /// Progress bar background color.
209    pub progress_bar: Hsla,
210    /// Used for focus ring.
211    pub ring: Hsla,
212    /// Scrollbar background color.
213    pub scrollbar: Hsla,
214    /// Scrollbar thumb background color.
215    pub scrollbar_thumb: Hsla,
216    /// Scrollbar thumb hover background color.
217    pub scrollbar_thumb_hover: Hsla,
218    /// Secondary background color.
219    pub secondary: Hsla,
220    /// Active secondary background color.
221    pub secondary_active: Hsla,
222    /// Secondary text color, used for secondary Button text color or secondary text.
223    pub secondary_foreground: Hsla,
224    /// Hover secondary background color.
225    pub secondary_hover: Hsla,
226    /// Input selection background color.
227    pub selection: Hsla,
228    /// Sidebar background color.
229    pub sidebar: Hsla,
230    /// Sidebar accent background color.
231    pub sidebar_accent: Hsla,
232    /// Sidebar accent text color.
233    pub sidebar_accent_foreground: Hsla,
234    /// Sidebar border color.
235    pub sidebar_border: Hsla,
236    /// Sidebar text color.
237    pub sidebar_foreground: Hsla,
238    /// Sidebar primary background color.
239    pub sidebar_primary: Hsla,
240    /// Sidebar primary text color.
241    pub sidebar_primary_foreground: Hsla,
242    /// Skeleton background color.
243    pub skeleton: Hsla,
244    /// Slider bar background color.
245    pub slider_bar: Hsla,
246    /// Slider thumb background color.
247    pub slider_thumb: Hsla,
248    /// Success background color.
249    pub success: Hsla,
250    /// Success text color.
251    pub success_foreground: Hsla,
252    /// Success hover background color.
253    pub success_hover: Hsla,
254    /// Success active background color.
255    pub success_active: Hsla,
256    /// Switch background color.
257    pub switch: Hsla,
258    /// Switch thumb background color.
259    pub switch_thumb: Hsla,
260    /// Tab background color.
261    pub tab: Hsla,
262    /// Tab active background color.
263    pub tab_active: Hsla,
264    /// Tab active text color.
265    pub tab_active_foreground: Hsla,
266    /// TabBar background color.
267    pub tab_bar: Hsla,
268    /// TabBar segmented background color.
269    pub tab_bar_segmented: Hsla,
270    /// Tab text color.
271    pub tab_foreground: Hsla,
272    /// Table background color.
273    pub table: Hsla,
274    /// Table active item background color.
275    pub table_active: Hsla,
276    /// Table active item border color.
277    pub table_active_border: Hsla,
278    /// Stripe background color for even TableRow.
279    pub table_even: Hsla,
280    /// Table head background color.
281    pub table_head: Hsla,
282    /// Table head text color.
283    pub table_head_foreground: Hsla,
284    /// Table footer background color.
285    pub table_foot: Hsla,
286    /// Table footer text color.
287    pub table_foot_foreground: Hsla,
288    /// Table item hover background color.
289    pub table_hover: Hsla,
290    /// Table row border color.
291    pub table_row_border: Hsla,
292    /// TitleBar background color, use for Window title bar.
293    pub title_bar: Hsla,
294    /// TitleBar border color.
295    pub title_bar_border: Hsla,
296    /// StatusBar background color, use for the bottom status bar.
297    pub status_bar: Hsla,
298    /// StatusBar border color.
299    pub status_bar_border: Hsla,
300    /// Warning background color.
301    pub warning: Hsla,
302    /// Warning active background color.
303    pub warning_active: Hsla,
304    /// Warning hover background color.
305    pub warning_hover: Hsla,
306    /// Warning foreground color.
307    pub warning_foreground: Hsla,
308    /// Overlay background color.
309    pub overlay: Hsla,
310    /// Window border color.
311    ///
312    /// # Platform specific:
313    ///
314    /// This is only works on Linux, other platforms we can't change the window border color.
315    pub window_border: Hsla,
316
317    /// The base red color.
318    pub red: Hsla,
319    /// The base red light color.
320    pub red_light: Hsla,
321    /// The base green color.
322    pub green: Hsla,
323    /// The base green light color.
324    pub green_light: Hsla,
325    /// The base blue color.
326    pub blue: Hsla,
327    /// The base blue light color.
328    pub blue_light: Hsla,
329    /// The base yellow color.
330    pub yellow: Hsla,
331    /// The base yellow light color.
332    pub yellow_light: Hsla,
333    /// The base magenta color.
334    pub magenta: Hsla,
335    /// The base magenta light color.
336    pub magenta_light: Hsla,
337    /// The base cyan color.
338    pub cyan: Hsla,
339    /// The base cyan light color.
340    pub cyan_light: Hsla,
341}
342
343macro_rules! define_theme_tokens {
344    ($($field:ident),+ $(,)?) => {
345        /// Legacy resolved tokens retained for compatibility with existing
346        /// `gpui-component` themes and components.
347        ///
348        /// This type intentionally includes component-specific fields such as
349        /// `button_primary`, `tab_active`, and `table_hover`. New application-owned
350        /// components should use [`gpui_base::SemanticThemeTokens`] instead. The
351        /// legacy fields remain public so existing theme files and direct field
352        /// access continue to work unchanged.
353        #[derive(Debug, Default, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema)]
354        pub struct ThemeTokens {
355            $(pub $field: ThemeToken,)+
356        }
357
358        impl ThemeTokens {
359            /// Brings the tokens and `colors` back to one value per field after
360            /// an edit, given the two as they were before it.
361            ///
362            /// A field edited on `colors` wins: when its token no longer names
363            /// that color, the token becomes that solid color, dropping any
364            /// gradient it carried — the caller asked for the solid color. A
365            /// field edited only on the tokens writes its solid color back to
366            /// `colors`. A field the edit set on both sides to one color, as
367            /// applying a theme config does, keeps its token, so a gradient
368            /// from a theme file survives; so does an untouched field.
369            pub(crate) fn reconcile(
370                &mut self,
371                colors: &mut ThemeColor,
372                colors_before: &ThemeColor,
373                tokens_before: &ThemeTokens,
374            ) {
375                $(
376                    if colors.$field != colors_before.$field {
377                        if self.$field.color != colors.$field {
378                            self.$field = colors.$field.into();
379                        }
380                    } else if self.$field != tokens_before.$field {
381                        colors.$field = self.$field.color;
382                    }
383                )+
384            }
385        }
386
387        impl From<ThemeColor> for ThemeTokens {
388            fn from(colors: ThemeColor) -> Self {
389                Self {
390                    $($field: colors.$field.into(),)+
391                }
392            }
393        }
394
395        impl From<&ThemeColor> for ThemeTokens {
396            fn from(colors: &ThemeColor) -> Self {
397                Self::from(*colors)
398            }
399        }
400    };
401}
402
403define_theme_tokens! {
404    accent,
405    accent_foreground,
406    accordion,
407    background,
408    border,
409    button,
410    button_active,
411    button_foreground,
412    button_hover,
413    button_danger,
414    button_danger_active,
415    button_danger_foreground,
416    button_danger_hover,
417    button_info,
418    button_info_active,
419    button_info_foreground,
420    button_info_hover,
421    button_primary,
422    button_primary_active,
423    button_primary_foreground,
424    button_primary_hover,
425    button_secondary,
426    button_secondary_active,
427    button_secondary_foreground,
428    button_secondary_hover,
429    button_success,
430    button_success_active,
431    button_success_foreground,
432    button_success_hover,
433    button_warning,
434    button_warning_active,
435    button_warning_foreground,
436    button_warning_hover,
437    group_box,
438    group_box_foreground,
439    caret,
440    chart_1,
441    chart_2,
442    chart_3,
443    chart_4,
444    chart_5,
445    chart_bullish,
446    chart_bearish,
447    danger,
448    danger_active,
449    danger_foreground,
450    danger_hover,
451    description_list_label,
452    description_list_label_foreground,
453    drag_border,
454    drop_target,
455    foreground,
456    info,
457    info_active,
458    info_foreground,
459    info_hover,
460    input,
461    link,
462    link_active,
463    link_hover,
464    list,
465    list_active,
466    list_active_border,
467    list_even,
468    list_head,
469    list_hover,
470    muted,
471    muted_foreground,
472    popover,
473    popover_foreground,
474    primary,
475    primary_active,
476    primary_foreground,
477    primary_hover,
478    progress_bar,
479    ring,
480    scrollbar,
481    scrollbar_thumb,
482    scrollbar_thumb_hover,
483    secondary,
484    secondary_active,
485    secondary_foreground,
486    secondary_hover,
487    selection,
488    sidebar,
489    sidebar_accent,
490    sidebar_accent_foreground,
491    sidebar_border,
492    sidebar_foreground,
493    sidebar_primary,
494    sidebar_primary_foreground,
495    skeleton,
496    slider_bar,
497    slider_thumb,
498    success,
499    success_foreground,
500    success_hover,
501    success_active,
502    switch,
503    switch_thumb,
504    tab,
505    tab_active,
506    tab_active_foreground,
507    tab_bar,
508    tab_bar_segmented,
509    tab_foreground,
510    table,
511    table_active,
512    table_active_border,
513    table_even,
514    table_head,
515    table_head_foreground,
516    table_foot,
517    table_foot_foreground,
518    table_hover,
519    table_row_border,
520    title_bar,
521    title_bar_border,
522    status_bar,
523    status_bar_border,
524    warning,
525    warning_active,
526    warning_hover,
527    warning_foreground,
528    overlay,
529    window_border,
530    red,
531    red_light,
532    green,
533    green_light,
534    blue,
535    blue_light,
536    yellow,
537    yellow_light,
538    magenta,
539    magenta_light,
540    cyan,
541    cyan_light,
542}
543
544impl ThemeColor {
545    /// Get the default light theme colors.
546    pub fn light() -> Arc<Self> {
547        DEFAULT_THEME_COLORS[&ThemeMode::Light].0.clone()
548    }
549
550    /// Get the default dark theme colors.
551    pub fn dark() -> Arc<Self> {
552        DEFAULT_THEME_COLORS[&ThemeMode::Dark].0.clone()
553    }
554}