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}