Skip to main content

ui/styles/
color.rs

1use crate::{Label, LabelCommon, component_prelude::*, v_flex};
2use documented::{DocumentedFields, DocumentedVariants};
3use gpui::{App, Hsla, IntoElement, ParentElement, Styled};
4use theme::ActiveTheme;
5
6/// Sets a color that has a consistent meaning across all themes.
7#[derive(
8    Debug,
9    Default,
10    Eq,
11    PartialEq,
12    Copy,
13    Clone,
14    RegisterComponent,
15    Documented,
16    DocumentedFields,
17    DocumentedVariants,
18)]
19pub enum Color {
20    #[default]
21    /// The default text color. Might be known as "foreground" or "primary" in
22    /// some theme systems.
23    ///
24    /// For less emphasis, consider using [`Color::Muted`] or [`Color::Hidden`].
25    Default,
26    /// A text color used for accents, such as links or highlights.
27    Accent,
28    /// A color used to indicate a conflict, such as a version control merge conflict, or a conflict between a file in the editor and the file system.
29    Conflict,
30    /// A color used to indicate a newly created item, such as a new file in
31    /// version control, or a new file on disk.
32    Created,
33    /// It is highly, HIGHLY recommended not to use this! Using this color
34    /// means detaching it from any semantic meaning across themes.
35    ///
36    /// A custom color specified by an HSLA value.
37    Custom(Hsla),
38    /// A color used for all debugger UI elements.
39    Debugger,
40    /// A color used to indicate a deleted item, such as a file removed from version control.
41    Deleted,
42    /// A color used for disabled UI elements or text, like a disabled button or menu item.
43    Disabled,
44    /// A color used to indicate an error condition, or something the user
45    /// cannot do. In very rare cases, it might be used to indicate dangerous or
46    /// destructive action.
47    Error,
48    /// A color used for elements that represent something that is hidden, like
49    /// a hidden file, or an element that should be visually de-emphasized.
50    Hidden,
51    /// A color used for hint or suggestion text, often a blue color. Use this
52    /// color to represent helpful, or semantically neutral information.
53    Hint,
54    /// A color used for items that are intentionally ignored, such as files ignored by version control.
55    Ignored,
56    /// A color used for informational messages or status indicators, often a blue color.
57    Info,
58    /// A color used to indicate a modified item, such as an edited file, or a modified entry in version control.
59    Modified,
60    /// A color used for text or UI elements that should be visually muted or de-emphasized.
61    ///
62    /// For more emphasis, consider using [`Color::Default`].
63    ///
64    /// For less emphasis, consider using [`Color::Hidden`].
65    Muted,
66    /// A color used for placeholder text in input fields.
67    Placeholder,
68    /// A color associated with a specific player number.
69    Player(u32),
70    /// A color used to indicate selected text or UI elements.
71    Selected,
72    /// A color used to indicate a successful operation or status.
73    Success,
74    /// A version control color used to indicate a newly added file or content in version control.
75    VersionControlAdded,
76    /// A version control color used to indicate conflicting changes that need resolution.
77    VersionControlConflict,
78    /// A version control color used to indicate a file or content that has been deleted in version control.
79    VersionControlDeleted,
80    /// A version control color used to indicate files or content that is being ignored by version control.
81    VersionControlIgnored,
82    /// A version control color used to indicate modified files or content in version control.
83    VersionControlModified,
84    /// A color used to indicate a warning condition.
85    Warning,
86}
87
88impl Color {
89    /// Returns the Color's HSLA value.
90    pub fn color(&self, cx: &App) -> Hsla {
91        match self {
92            Color::Default => cx.theme().colors().text,
93            Color::Muted => cx.theme().colors().text_muted,
94            Color::Created => cx.theme().status().created,
95            Color::Modified => cx.theme().status().modified,
96            Color::Conflict => cx.theme().status().conflict,
97            Color::Ignored => cx.theme().status().ignored,
98            Color::Debugger => cx.theme().colors().debugger_accent,
99            Color::Deleted => cx.theme().status().deleted,
100            Color::Disabled => cx.theme().colors().text_disabled,
101            Color::Hidden => cx.theme().status().hidden,
102            Color::Hint => cx.theme().status().hint,
103            Color::Info => cx.theme().status().info,
104            Color::Placeholder => cx.theme().colors().text_placeholder,
105            Color::Accent => cx.theme().colors().text_accent,
106            Color::Player(i) => cx.theme().styles.player.color_for_participant(*i).cursor,
107            Color::Error => cx.theme().status().error,
108            Color::Selected => cx.theme().colors().text_accent,
109            Color::Success => cx.theme().status().success,
110            Color::VersionControlAdded => cx.theme().colors().version_control_added,
111            Color::VersionControlConflict => cx.theme().colors().version_control_conflict,
112            Color::VersionControlDeleted => cx.theme().colors().version_control_deleted,
113            Color::VersionControlIgnored => cx.theme().colors().version_control_ignored,
114            Color::VersionControlModified => cx.theme().colors().version_control_modified,
115            Color::Warning => cx.theme().status().warning,
116            Color::Custom(color) => *color,
117        }
118    }
119}
120
121impl From<Hsla> for Color {
122    fn from(color: Hsla) -> Self {
123        Color::Custom(color)
124    }
125}
126
127impl Component for Color {
128    fn scope() -> ComponentScope {
129        ComponentScope::Utilities
130    }
131
132    fn description() -> Option<&'static str> {
133        Some(Color::DOCS)
134    }
135
136    fn preview(_window: &mut gpui::Window, _cx: &mut App) -> Option<gpui::AnyElement> {
137        Some(
138            v_flex()
139                .gap_6()
140                .children(vec![
141                    example_group_with_title(
142                        "Text Colors",
143                        vec![
144                            single_example(
145                                "Default",
146                                Label::new("Default text color")
147                                    .color(Color::Default)
148                                    .into_any_element(),
149                            )
150                            .description(Color::Default.get_variant_docs()),
151                            single_example(
152                                "Muted",
153                                Label::new("Muted text color")
154                                    .color(Color::Muted)
155                                    .into_any_element(),
156                            )
157                            .description(Color::Muted.get_variant_docs()),
158                            single_example(
159                                "Accent",
160                                Label::new("Accent text color")
161                                    .color(Color::Accent)
162                                    .into_any_element(),
163                            )
164                            .description(Color::Accent.get_variant_docs()),
165                            single_example(
166                                "Disabled",
167                                Label::new("Disabled text color")
168                                    .color(Color::Disabled)
169                                    .into_any_element(),
170                            )
171                            .description(Color::Disabled.get_variant_docs()),
172                        ],
173                    ),
174                    example_group_with_title(
175                        "Status Colors",
176                        vec![
177                            single_example(
178                                "Success",
179                                Label::new("Success status")
180                                    .color(Color::Success)
181                                    .into_any_element(),
182                            )
183                            .description(Color::Success.get_variant_docs()),
184                            single_example(
185                                "Warning",
186                                Label::new("Warning status")
187                                    .color(Color::Warning)
188                                    .into_any_element(),
189                            )
190                            .description(Color::Warning.get_variant_docs()),
191                            single_example(
192                                "Error",
193                                Label::new("Error status")
194                                    .color(Color::Error)
195                                    .into_any_element(),
196                            )
197                            .description(Color::Error.get_variant_docs()),
198                            single_example(
199                                "Info",
200                                Label::new("Info status")
201                                    .color(Color::Info)
202                                    .into_any_element(),
203                            )
204                            .description(Color::Info.get_variant_docs()),
205                        ],
206                    ),
207                    example_group_with_title(
208                        "Version Control Colors",
209                        vec![
210                            single_example(
211                                "Created",
212                                Label::new("Created item")
213                                    .color(Color::Created)
214                                    .into_any_element(),
215                            )
216                            .description(Color::Created.get_variant_docs()),
217                            single_example(
218                                "Modified",
219                                Label::new("Modified item")
220                                    .color(Color::Modified)
221                                    .into_any_element(),
222                            )
223                            .description(Color::Modified.get_variant_docs()),
224                            single_example(
225                                "Deleted",
226                                Label::new("Deleted item")
227                                    .color(Color::Deleted)
228                                    .into_any_element(),
229                            )
230                            .description(Color::Deleted.get_variant_docs()),
231                            single_example(
232                                "Conflict",
233                                Label::new("Conflict item")
234                                    .color(Color::Conflict)
235                                    .into_any_element(),
236                            )
237                            .description(Color::Conflict.get_variant_docs()),
238                        ],
239                    ),
240                ])
241                .into_any_element(),
242        )
243    }
244}