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