colors.rs

  1#![allow(missing_docs)]
  2
  3use gpui::{Hsla, SharedString, WindowBackgroundAppearance, WindowContext};
  4use refineable::Refineable;
  5use std::sync::Arc;
  6use strum::{AsRefStr, EnumIter, IntoEnumIterator};
  7
  8use crate::{
  9    AccentColors, ActiveTheme, PlayerColors, StatusColors, StatusColorsRefinement, SyntaxTheme,
 10    SystemColors,
 11};
 12
 13#[derive(Refineable, Clone, Debug, PartialEq)]
 14#[refineable(Debug, serde::Deserialize)]
 15pub struct ThemeColors {
 16    /// Border color. Used for most borders, is usually a high contrast color.
 17    pub border: Hsla,
 18    /// Border color. Used for deemphasized borders, like a visual divider between two sections
 19    pub border_variant: Hsla,
 20    /// Border color. Used for focused elements, like keyboard focused list item.
 21    pub border_focused: Hsla,
 22    /// Border color. Used for selected elements, like an active search filter or selected checkbox.
 23    pub border_selected: Hsla,
 24    /// Border color. Used for transparent borders. Used for placeholder borders when an element gains a border on state change.
 25    pub border_transparent: Hsla,
 26    /// Border color. Used for disabled elements, like a disabled input or button.
 27    pub border_disabled: Hsla,
 28    /// Border color. Used for elevated surfaces, like a context menu, popup, or dialog.
 29    pub elevated_surface_background: Hsla,
 30    /// Background Color. Used for grounded surfaces like a panel or tab.
 31    pub surface_background: Hsla,
 32    /// Background Color. Used for the app background and blank panels or windows.
 33    pub background: Hsla,
 34    /// Background Color. Used for the background of an element that should have a different background than the surface it's on.
 35    ///
 36    /// Elements might include: Buttons, Inputs, Checkboxes, Radio Buttons...
 37    ///
 38    /// For an element that should have the same background as the surface it's on, use `ghost_element_background`.
 39    pub element_background: Hsla,
 40    /// Background Color. Used for the hover state of an element that should have a different background than the surface it's on.
 41    ///
 42    /// Hover states are triggered by the mouse entering an element, or a finger touching an element on a touch screen.
 43    pub element_hover: Hsla,
 44    /// Background Color. Used for the active state of an element that should have a different background than the surface it's on.
 45    ///
 46    /// Active states are triggered by the mouse button being pressed down on an element, or the Return button or other activator being pressd.
 47    pub element_active: Hsla,
 48    /// Background Color. Used for the selected state of an element that should have a different background than the surface it's on.
 49    ///
 50    /// Selected states are triggered by the element being selected (or "activated") by the user.
 51    ///
 52    /// This could include a selected checkbox, a toggleable button that is toggled on, etc.
 53    pub element_selected: Hsla,
 54    /// Background Color. Used for the disabled state of an element that should have a different background than the surface it's on.
 55    ///
 56    /// Disabled states are shown when a user cannot interact with an element, like a disabled button or input.
 57    pub element_disabled: Hsla,
 58    /// Background Color. Used for the area that shows where a dragged element will be dropped.
 59    pub drop_target_background: Hsla,
 60    /// Border Color. Used to show the area that shows where a dragged element will be dropped.
 61    // pub drop_target_border: Hsla,
 62    /// Used for the background of a ghost element that should have the same background as the surface it's on.
 63    ///
 64    /// Elements might include: Buttons, Inputs, Checkboxes, Radio Buttons...
 65    ///
 66    /// For an element that should have a different background than the surface it's on, use `element_background`.
 67    pub ghost_element_background: Hsla,
 68    /// Background Color. Used for the hover state of a ghost element that should have the same background as the surface it's on.
 69    ///
 70    /// Hover states are triggered by the mouse entering an element, or a finger touching an element on a touch screen.
 71    pub ghost_element_hover: Hsla,
 72    /// Background Color. Used for the active state of a ghost element that should have the same background as the surface it's on.
 73    ///
 74    /// Active states are triggered by the mouse button being pressed down on an element, or the Return button or other activator being pressd.
 75    pub ghost_element_active: Hsla,
 76    /// Background Color. Used for the selected state of a ghost element that should have the same background as the surface it's on.
 77    ///
 78    /// Selected states are triggered by the element being selected (or "activated") by the user.
 79    ///
 80    /// This could include a selected checkbox, a toggleable button that is toggled on, etc.
 81    pub ghost_element_selected: Hsla,
 82    /// Background Color. Used for the disabled state of a ghost element that should have the same background as the surface it's on.
 83    ///
 84    /// Disabled states are shown when a user cannot interact with an element, like a disabled button or input.
 85    pub ghost_element_disabled: Hsla,
 86    /// Text Color. Default text color used for most text.
 87    pub text: Hsla,
 88    /// Text Color. Color of muted or deemphasized text. It is a subdued version of the standard text color.
 89    pub text_muted: Hsla,
 90    /// Text Color. Color of the placeholder text typically shown in input fields to guide the user to enter valid data.
 91    pub text_placeholder: Hsla,
 92    /// Text Color. Color used for text denoting disabled elements. Typically, the color is faded or grayed out to emphasize the disabled state.
 93    pub text_disabled: Hsla,
 94    /// Text Color. Color used for emphasis or highlighting certain text, like an active filter or a matched character in a search.
 95    pub text_accent: Hsla,
 96    /// Fill Color. Used for the default fill color of an icon.
 97    pub icon: Hsla,
 98    /// Fill Color. Used for the muted or deemphasized fill color of an icon.
 99    ///
100    /// This might be used to show an icon in an inactive pane, or to demphasize a series of icons to give them less visual weight.
101    pub icon_muted: Hsla,
102    /// Fill Color. Used for the disabled fill color of an icon.
103    ///
104    /// Disabled states are shown when a user cannot interact with an element, like a icon button.
105    pub icon_disabled: Hsla,
106    /// Fill Color. Used for the placeholder fill color of an icon.
107    ///
108    /// This might be used to show an icon in an input that disappears when the user enters text.
109    pub icon_placeholder: Hsla,
110    /// Fill Color. Used for the accent fill color of an icon.
111    ///
112    /// This might be used to show when a toggleable icon button is selected.
113    pub icon_accent: Hsla,
114
115    // ===
116    // UI Elements
117    // ===
118    pub status_bar_background: Hsla,
119    pub title_bar_background: Hsla,
120    pub title_bar_inactive_background: Hsla,
121    pub toolbar_background: Hsla,
122    pub tab_bar_background: Hsla,
123    pub tab_inactive_background: Hsla,
124    pub tab_active_background: Hsla,
125    pub search_match_background: Hsla,
126    pub panel_background: Hsla,
127    pub panel_focused_border: Hsla,
128    pub panel_indent_guide: Hsla,
129    pub panel_indent_guide_hover: Hsla,
130    pub panel_indent_guide_active: Hsla,
131    pub pane_focused_border: Hsla,
132    pub pane_group_border: Hsla,
133    /// The color of the scrollbar thumb.
134    pub scrollbar_thumb_background: Hsla,
135    /// The color of the scrollbar thumb when hovered over.
136    pub scrollbar_thumb_hover_background: Hsla,
137    /// The border color of the scrollbar thumb.
138    pub scrollbar_thumb_border: Hsla,
139    /// The background color of the scrollbar track.
140    pub scrollbar_track_background: Hsla,
141    /// The border color of the scrollbar track.
142    pub scrollbar_track_border: Hsla,
143    // /// The opacity of the scrollbar status marks, like diagnostic states and git status.
144    // todo()
145    // pub scrollbar_status_opacity: Hsla,
146
147    // ===
148    // Editor
149    // ===
150    pub editor_foreground: Hsla,
151    pub editor_background: Hsla,
152    // pub editor_inactive_background: Hsla,
153    pub editor_gutter_background: Hsla,
154    pub editor_subheader_background: Hsla,
155    pub editor_active_line_background: Hsla,
156    pub editor_highlighted_line_background: Hsla,
157    /// Text Color. Used for the text of the line number in the editor gutter.
158    pub editor_line_number: Hsla,
159    /// Text Color. Used for the text of the line number in the editor gutter when the line is highlighted.
160    pub editor_active_line_number: Hsla,
161    /// Text Color. Used to mark invisible characters in the editor.
162    ///
163    /// Example: spaces, tabs, carriage returns, etc.
164    pub editor_invisible: Hsla,
165    pub editor_wrap_guide: Hsla,
166    pub editor_active_wrap_guide: Hsla,
167    pub editor_indent_guide: Hsla,
168    pub editor_indent_guide_active: Hsla,
169    /// Read-access of a symbol, like reading a variable.
170    ///
171    /// A document highlight is a range inside a text document which deserves
172    /// special attention. Usually a document highlight is visualized by changing
173    /// the background color of its range.
174    pub editor_document_highlight_read_background: Hsla,
175    /// Read-access of a symbol, like reading a variable.
176    ///
177    /// A document highlight is a range inside a text document which deserves
178    /// special attention. Usually a document highlight is visualized by changing
179    /// the background color of its range.
180    pub editor_document_highlight_write_background: Hsla,
181    /// Highlighted brackets background color.
182    ///
183    /// Matching brackets in the cursor scope are highlighted with this background color.
184    pub editor_document_highlight_bracket_background: Hsla,
185
186    // ===
187    // Terminal
188    // ===
189    /// Terminal layout background color.
190    pub terminal_background: Hsla,
191    /// Terminal foreground color.
192    pub terminal_foreground: Hsla,
193    /// Bright terminal foreground color.
194    pub terminal_bright_foreground: Hsla,
195    /// Dim terminal foreground color.
196    pub terminal_dim_foreground: Hsla,
197    /// Terminal ANSI background color.
198    pub terminal_ansi_background: Hsla,
199    /// Black ANSI terminal color.
200    pub terminal_ansi_black: Hsla,
201    /// Bright black ANSI terminal color.
202    pub terminal_ansi_bright_black: Hsla,
203    /// Dim black ANSI terminal color.
204    pub terminal_ansi_dim_black: Hsla,
205    /// Red ANSI terminal color.
206    pub terminal_ansi_red: Hsla,
207    /// Bright red ANSI terminal color.
208    pub terminal_ansi_bright_red: Hsla,
209    /// Dim red ANSI terminal color.
210    pub terminal_ansi_dim_red: Hsla,
211    /// Green ANSI terminal color.
212    pub terminal_ansi_green: Hsla,
213    /// Bright green ANSI terminal color.
214    pub terminal_ansi_bright_green: Hsla,
215    /// Dim green ANSI terminal color.
216    pub terminal_ansi_dim_green: Hsla,
217    /// Yellow ANSI terminal color.
218    pub terminal_ansi_yellow: Hsla,
219    /// Bright yellow ANSI terminal color.
220    pub terminal_ansi_bright_yellow: Hsla,
221    /// Dim yellow ANSI terminal color.
222    pub terminal_ansi_dim_yellow: Hsla,
223    /// Blue ANSI terminal color.
224    pub terminal_ansi_blue: Hsla,
225    /// Bright blue ANSI terminal color.
226    pub terminal_ansi_bright_blue: Hsla,
227    /// Dim blue ANSI terminal color.
228    pub terminal_ansi_dim_blue: Hsla,
229    /// Magenta ANSI terminal color.
230    pub terminal_ansi_magenta: Hsla,
231    /// Bright magenta ANSI terminal color.
232    pub terminal_ansi_bright_magenta: Hsla,
233    /// Dim magenta ANSI terminal color.
234    pub terminal_ansi_dim_magenta: Hsla,
235    /// Cyan ANSI terminal color.
236    pub terminal_ansi_cyan: Hsla,
237    /// Bright cyan ANSI terminal color.
238    pub terminal_ansi_bright_cyan: Hsla,
239    /// Dim cyan ANSI terminal color.
240    pub terminal_ansi_dim_cyan: Hsla,
241    /// White ANSI terminal color.
242    pub terminal_ansi_white: Hsla,
243    /// Bright white ANSI terminal color.
244    pub terminal_ansi_bright_white: Hsla,
245    /// Dim white ANSI terminal color.
246    pub terminal_ansi_dim_white: Hsla,
247
248    // ===
249    // UI/Rich Text
250    // ===
251    pub link_text_hover: Hsla,
252}
253
254#[derive(EnumIter, Debug, Clone, Copy, AsRefStr)]
255#[strum(serialize_all = "snake_case")]
256pub enum ThemeColorField {
257    Border,
258    BorderVariant,
259    BorderFocused,
260    BorderSelected,
261    BorderTransparent,
262    BorderDisabled,
263    ElevatedSurfaceBackground,
264    SurfaceBackground,
265    Background,
266    ElementBackground,
267    ElementHover,
268    ElementActive,
269    ElementSelected,
270    ElementDisabled,
271    DropTargetBackground,
272    GhostElementBackground,
273    GhostElementHover,
274    GhostElementActive,
275    GhostElementSelected,
276    GhostElementDisabled,
277    Text,
278    TextMuted,
279    TextPlaceholder,
280    TextDisabled,
281    TextAccent,
282    Icon,
283    IconMuted,
284    IconDisabled,
285    IconPlaceholder,
286    IconAccent,
287    StatusBarBackground,
288    TitleBarBackground,
289    TitleBarInactiveBackground,
290    ToolbarBackground,
291    TabBarBackground,
292    TabInactiveBackground,
293    TabActiveBackground,
294    SearchMatchBackground,
295    PanelBackground,
296    PanelFocusedBorder,
297    PanelIndentGuide,
298    PanelIndentGuideHover,
299    PanelIndentGuideActive,
300    PaneFocusedBorder,
301    PaneGroupBorder,
302    ScrollbarThumbBackground,
303    ScrollbarThumbHoverBackground,
304    ScrollbarThumbBorder,
305    ScrollbarTrackBackground,
306    ScrollbarTrackBorder,
307    EditorForeground,
308    EditorBackground,
309    EditorGutterBackground,
310    EditorSubheaderBackground,
311    EditorActiveLineBackground,
312    EditorHighlightedLineBackground,
313    EditorLineNumber,
314    EditorActiveLineNumber,
315    EditorInvisible,
316    EditorWrapGuide,
317    EditorActiveWrapGuide,
318    EditorIndentGuide,
319    EditorIndentGuideActive,
320    EditorDocumentHighlightReadBackground,
321    EditorDocumentHighlightWriteBackground,
322    EditorDocumentHighlightBracketBackground,
323    TerminalBackground,
324    TerminalForeground,
325    TerminalBrightForeground,
326    TerminalDimForeground,
327    TerminalAnsiBackground,
328    TerminalAnsiBlack,
329    TerminalAnsiBrightBlack,
330    TerminalAnsiDimBlack,
331    TerminalAnsiRed,
332    TerminalAnsiBrightRed,
333    TerminalAnsiDimRed,
334    TerminalAnsiGreen,
335    TerminalAnsiBrightGreen,
336    TerminalAnsiDimGreen,
337    TerminalAnsiYellow,
338    TerminalAnsiBrightYellow,
339    TerminalAnsiDimYellow,
340    TerminalAnsiBlue,
341    TerminalAnsiBrightBlue,
342    TerminalAnsiDimBlue,
343    TerminalAnsiMagenta,
344    TerminalAnsiBrightMagenta,
345    TerminalAnsiDimMagenta,
346    TerminalAnsiCyan,
347    TerminalAnsiBrightCyan,
348    TerminalAnsiDimCyan,
349    TerminalAnsiWhite,
350    TerminalAnsiBrightWhite,
351    TerminalAnsiDimWhite,
352    LinkTextHover,
353}
354
355impl ThemeColors {
356    pub fn color(&self, field: ThemeColorField) -> Hsla {
357        match field {
358            ThemeColorField::Border => self.border,
359            ThemeColorField::BorderVariant => self.border_variant,
360            ThemeColorField::BorderFocused => self.border_focused,
361            ThemeColorField::BorderSelected => self.border_selected,
362            ThemeColorField::BorderTransparent => self.border_transparent,
363            ThemeColorField::BorderDisabled => self.border_disabled,
364            ThemeColorField::ElevatedSurfaceBackground => self.elevated_surface_background,
365            ThemeColorField::SurfaceBackground => self.surface_background,
366            ThemeColorField::Background => self.background,
367            ThemeColorField::ElementBackground => self.element_background,
368            ThemeColorField::ElementHover => self.element_hover,
369            ThemeColorField::ElementActive => self.element_active,
370            ThemeColorField::ElementSelected => self.element_selected,
371            ThemeColorField::ElementDisabled => self.element_disabled,
372            ThemeColorField::DropTargetBackground => self.drop_target_background,
373            ThemeColorField::GhostElementBackground => self.ghost_element_background,
374            ThemeColorField::GhostElementHover => self.ghost_element_hover,
375            ThemeColorField::GhostElementActive => self.ghost_element_active,
376            ThemeColorField::GhostElementSelected => self.ghost_element_selected,
377            ThemeColorField::GhostElementDisabled => self.ghost_element_disabled,
378            ThemeColorField::Text => self.text,
379            ThemeColorField::TextMuted => self.text_muted,
380            ThemeColorField::TextPlaceholder => self.text_placeholder,
381            ThemeColorField::TextDisabled => self.text_disabled,
382            ThemeColorField::TextAccent => self.text_accent,
383            ThemeColorField::Icon => self.icon,
384            ThemeColorField::IconMuted => self.icon_muted,
385            ThemeColorField::IconDisabled => self.icon_disabled,
386            ThemeColorField::IconPlaceholder => self.icon_placeholder,
387            ThemeColorField::IconAccent => self.icon_accent,
388            ThemeColorField::StatusBarBackground => self.status_bar_background,
389            ThemeColorField::TitleBarBackground => self.title_bar_background,
390            ThemeColorField::TitleBarInactiveBackground => self.title_bar_inactive_background,
391            ThemeColorField::ToolbarBackground => self.toolbar_background,
392            ThemeColorField::TabBarBackground => self.tab_bar_background,
393            ThemeColorField::TabInactiveBackground => self.tab_inactive_background,
394            ThemeColorField::TabActiveBackground => self.tab_active_background,
395            ThemeColorField::SearchMatchBackground => self.search_match_background,
396            ThemeColorField::PanelBackground => self.panel_background,
397            ThemeColorField::PanelFocusedBorder => self.panel_focused_border,
398            ThemeColorField::PanelIndentGuide => self.panel_indent_guide,
399            ThemeColorField::PanelIndentGuideHover => self.panel_indent_guide_hover,
400            ThemeColorField::PanelIndentGuideActive => self.panel_indent_guide_active,
401            ThemeColorField::PaneFocusedBorder => self.pane_focused_border,
402            ThemeColorField::PaneGroupBorder => self.pane_group_border,
403            ThemeColorField::ScrollbarThumbBackground => self.scrollbar_thumb_background,
404            ThemeColorField::ScrollbarThumbHoverBackground => self.scrollbar_thumb_hover_background,
405            ThemeColorField::ScrollbarThumbBorder => self.scrollbar_thumb_border,
406            ThemeColorField::ScrollbarTrackBackground => self.scrollbar_track_background,
407            ThemeColorField::ScrollbarTrackBorder => self.scrollbar_track_border,
408            ThemeColorField::EditorForeground => self.editor_foreground,
409            ThemeColorField::EditorBackground => self.editor_background,
410            ThemeColorField::EditorGutterBackground => self.editor_gutter_background,
411            ThemeColorField::EditorSubheaderBackground => self.editor_subheader_background,
412            ThemeColorField::EditorActiveLineBackground => self.editor_active_line_background,
413            ThemeColorField::EditorHighlightedLineBackground => {
414                self.editor_highlighted_line_background
415            }
416            ThemeColorField::EditorLineNumber => self.editor_line_number,
417            ThemeColorField::EditorActiveLineNumber => self.editor_active_line_number,
418            ThemeColorField::EditorInvisible => self.editor_invisible,
419            ThemeColorField::EditorWrapGuide => self.editor_wrap_guide,
420            ThemeColorField::EditorActiveWrapGuide => self.editor_active_wrap_guide,
421            ThemeColorField::EditorIndentGuide => self.editor_indent_guide,
422            ThemeColorField::EditorIndentGuideActive => self.editor_indent_guide_active,
423            ThemeColorField::EditorDocumentHighlightReadBackground => {
424                self.editor_document_highlight_read_background
425            }
426            ThemeColorField::EditorDocumentHighlightWriteBackground => {
427                self.editor_document_highlight_write_background
428            }
429            ThemeColorField::EditorDocumentHighlightBracketBackground => {
430                self.editor_document_highlight_bracket_background
431            }
432            ThemeColorField::TerminalBackground => self.terminal_background,
433            ThemeColorField::TerminalForeground => self.terminal_foreground,
434            ThemeColorField::TerminalBrightForeground => self.terminal_bright_foreground,
435            ThemeColorField::TerminalDimForeground => self.terminal_dim_foreground,
436            ThemeColorField::TerminalAnsiBackground => self.terminal_ansi_background,
437            ThemeColorField::TerminalAnsiBlack => self.terminal_ansi_black,
438            ThemeColorField::TerminalAnsiBrightBlack => self.terminal_ansi_bright_black,
439            ThemeColorField::TerminalAnsiDimBlack => self.terminal_ansi_dim_black,
440            ThemeColorField::TerminalAnsiRed => self.terminal_ansi_red,
441            ThemeColorField::TerminalAnsiBrightRed => self.terminal_ansi_bright_red,
442            ThemeColorField::TerminalAnsiDimRed => self.terminal_ansi_dim_red,
443            ThemeColorField::TerminalAnsiGreen => self.terminal_ansi_green,
444            ThemeColorField::TerminalAnsiBrightGreen => self.terminal_ansi_bright_green,
445            ThemeColorField::TerminalAnsiDimGreen => self.terminal_ansi_dim_green,
446            ThemeColorField::TerminalAnsiYellow => self.terminal_ansi_yellow,
447            ThemeColorField::TerminalAnsiBrightYellow => self.terminal_ansi_bright_yellow,
448            ThemeColorField::TerminalAnsiDimYellow => self.terminal_ansi_dim_yellow,
449            ThemeColorField::TerminalAnsiBlue => self.terminal_ansi_blue,
450            ThemeColorField::TerminalAnsiBrightBlue => self.terminal_ansi_bright_blue,
451            ThemeColorField::TerminalAnsiDimBlue => self.terminal_ansi_dim_blue,
452            ThemeColorField::TerminalAnsiMagenta => self.terminal_ansi_magenta,
453            ThemeColorField::TerminalAnsiBrightMagenta => self.terminal_ansi_bright_magenta,
454            ThemeColorField::TerminalAnsiDimMagenta => self.terminal_ansi_dim_magenta,
455            ThemeColorField::TerminalAnsiCyan => self.terminal_ansi_cyan,
456            ThemeColorField::TerminalAnsiBrightCyan => self.terminal_ansi_bright_cyan,
457            ThemeColorField::TerminalAnsiDimCyan => self.terminal_ansi_dim_cyan,
458            ThemeColorField::TerminalAnsiWhite => self.terminal_ansi_white,
459            ThemeColorField::TerminalAnsiBrightWhite => self.terminal_ansi_bright_white,
460            ThemeColorField::TerminalAnsiDimWhite => self.terminal_ansi_dim_white,
461            ThemeColorField::LinkTextHover => self.link_text_hover,
462        }
463    }
464
465    pub fn iter(&self) -> impl Iterator<Item = (ThemeColorField, Hsla)> + '_ {
466        ThemeColorField::iter().map(move |field| (field, self.color(field)))
467    }
468
469    pub fn to_vec(&self) -> Vec<(ThemeColorField, Hsla)> {
470        self.iter().collect()
471    }
472}
473
474pub fn all_theme_colors(cx: &WindowContext) -> Vec<(Hsla, SharedString)> {
475    let theme = cx.theme();
476    ThemeColorField::iter()
477        .map(|field| {
478            let color = theme.colors().color(field);
479            let name = field.as_ref().to_string();
480            (color, SharedString::from(name))
481        })
482        .collect()
483}
484
485#[derive(Refineable, Clone, PartialEq)]
486pub struct ThemeStyles {
487    /// The background appearance of the window.
488    pub window_background_appearance: WindowBackgroundAppearance,
489    pub system: SystemColors,
490    /// An array of colors used for theme elements that iterate through a series of colors.
491    ///
492    /// Example: Player colors, rainbow brackets and indent guides, etc.
493    pub accents: AccentColors,
494
495    #[refineable]
496    pub colors: ThemeColors,
497
498    #[refineable]
499    pub status: StatusColors,
500
501    pub player: PlayerColors,
502
503    pub syntax: Arc<SyntaxTheme>,
504}
505
506#[cfg(test)]
507mod tests {
508    use serde_json::json;
509
510    use super::*;
511
512    #[test]
513    fn override_a_single_theme_color() {
514        let mut colors = ThemeColors::light();
515
516        let magenta: Hsla = gpui::rgb(0xff00ff).into();
517
518        assert_ne!(colors.text, magenta);
519
520        let overrides = ThemeColorsRefinement {
521            text: Some(magenta),
522            ..Default::default()
523        };
524
525        colors.refine(&overrides);
526
527        assert_eq!(colors.text, magenta);
528    }
529
530    #[test]
531    fn override_multiple_theme_colors() {
532        let mut colors = ThemeColors::light();
533
534        let magenta: Hsla = gpui::rgb(0xff00ff).into();
535        let green: Hsla = gpui::rgb(0x00ff00).into();
536
537        assert_ne!(colors.text, magenta);
538        assert_ne!(colors.background, green);
539
540        let overrides = ThemeColorsRefinement {
541            text: Some(magenta),
542            background: Some(green),
543            ..Default::default()
544        };
545
546        colors.refine(&overrides);
547
548        assert_eq!(colors.text, magenta);
549        assert_eq!(colors.background, green);
550    }
551
552    #[test]
553    fn deserialize_theme_colors_refinement_from_json() {
554        let colors: ThemeColorsRefinement = serde_json::from_value(json!({
555            "background": "#ff00ff",
556            "text": "#ff0000"
557        }))
558        .unwrap();
559
560        assert_eq!(colors.background, Some(gpui::rgb(0xff00ff).into()));
561        assert_eq!(colors.text, Some(gpui::rgb(0xff0000).into()));
562    }
563}