ui: Color cleanup (#26673)

This PR cleans up some color & elevation misc.

### Don't allow deriving Color from Hsla

The point of the [ui::Color] enum is to encourage consistent color
usage, and the the Color::Custom case is really only meant for cases
where we have no other choice.

`impl From<Hsla> for Color` encourages blindly passing colors into
`Color::Custom` – with this in place we might as well remove the entire
`Color` enum.

The usages that were updated due to this removal were for colors that
already exist in the Color enum, making it even more clear that it
didn't make sense to have this.

### `ElevationIndex` -> `Elevation`

This name would make more sense if we had an `Elevation` in the first
place. The new name is more clear.

#### `Button::elevation`

As part of this change I also updated button's `layer` method to
`elevation`, since it takes an elevation. This method still has the
following issue:

You want to use `Button::elevation` when it's default colors are
invisible on the layer you are rendering the button on. However, current
this method uses the elevation's `bg` color, rather than it's
`on_elevation_bg`.

Ideally when you use `Button::elevation` you want to pass the elevation
you are _on_, not choosing one that will show up the elevation you are
on.

This change will be in a separate PR, as it likely will have widespread
visual impact across the app.

Release Notes:

- N/A
This commit is contained in:
Nate Butler 2025-03-13 11:18:40 -04:00 committed by GitHub
parent 8cf5af1a84
commit 6767e98e00
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 139 additions and 161 deletions

View file

@ -1,9 +1,9 @@
use gpui::{hsla, App, Styled};
use crate::prelude::*;
use crate::ElevationIndex;
use crate::Elevation;
fn elevated<E: Styled>(this: E, cx: &App, index: ElevationIndex) -> E {
fn elevated<E: Styled>(this: E, cx: &App, index: Elevation) -> E {
this.bg(cx.theme().colors().elevated_surface_background)
.rounded_lg()
.border_1()
@ -11,7 +11,7 @@ fn elevated<E: Styled>(this: E, cx: &App, index: ElevationIndex) -> E {
.shadow(index.shadow(cx))
}
fn elevated_borderless<E: Styled>(this: E, cx: &mut App, index: ElevationIndex) -> E {
fn elevated_borderless<E: Styled>(this: E, cx: &mut App, index: Elevation) -> E {
this.bg(cx.theme().colors().elevated_surface_background)
.rounded_lg()
.shadow(index.shadow(cx))
@ -33,56 +33,56 @@ pub trait StyledExt: Styled + Sized {
self.flex().flex_col()
}
/// The [`Surface`](ElevationIndex::Surface) elevation level, located above the app background, is the standard level for all elements
/// The [`Surface`](Elevation::Surface) elevation level, located above the app background, is the standard level for all elements
///
/// Sets `bg()`, `rounded_lg()`, `border()`, `border_color()`, `shadow()`
///
/// Example Elements: Title Bar, Panel, Tab Bar, Editor
fn elevation_1(self, cx: &mut App) -> Self {
elevated(self, cx, ElevationIndex::Surface)
elevated(self, cx, Elevation::Surface)
}
/// See [`elevation_1`](Self::elevation_1).
///
/// Renders a borderless version [`elevation_1`](Self::elevation_1).
fn elevation_1_borderless(self, cx: &mut App) -> Self {
elevated_borderless(self, cx, ElevationIndex::Surface)
elevated_borderless(self, cx, Elevation::Surface)
}
/// Non-Modal Elevated Surfaces appear above the [`Surface`](ElevationIndex::Surface) layer and is used for things that should appear above most UI elements like an editor or panel, but not elements like popovers, context menus, modals, etc.
/// Non-Modal Elevated Surfaces appear above the [`Surface`](Elevation::Surface) layer and is used for things that should appear above most UI elements like an editor or panel, but not elements like popovers, context menus, modals, etc.
///
/// Sets `bg()`, `rounded_lg()`, `border()`, `border_color()`, `shadow()`
///
/// Examples: Notifications, Palettes, Detached/Floating Windows, Detached/Floating Panels
fn elevation_2(self, cx: &App) -> Self {
elevated(self, cx, ElevationIndex::ElevatedSurface)
elevated(self, cx, Elevation::ElevatedSurface)
}
/// See [`elevation_2`](Self::elevation_2).
///
/// Renders a borderless version [`elevation_2`](Self::elevation_2).
fn elevation_2_borderless(self, cx: &mut App) -> Self {
elevated_borderless(self, cx, ElevationIndex::ElevatedSurface)
elevated_borderless(self, cx, Elevation::ElevatedSurface)
}
/// Modal Surfaces are used for elements that should appear above all other UI elements and are located above the wash layer. This is the maximum elevation at which UI elements can be rendered in their default state.
///
/// Elements rendered at this layer should have an enforced behavior: Any interaction outside of the modal will either dismiss the modal or prompt an action (Save your progress, etc) then dismiss the modal.
///
/// If the element does not have this behavior, it should be rendered at the [`Elevated Surface`](ElevationIndex::ElevatedSurface) layer.
/// If the element does not have this behavior, it should be rendered at the [`Elevated Surface`](Elevation::ElevatedSurface) layer.
///
/// Sets `bg()`, `rounded_lg()`, `border()`, `border_color()`, `shadow()`
///
/// Examples: Settings Modal, Channel Management, Wizards/Setup UI, Dialogs
fn elevation_3(self, cx: &mut App) -> Self {
elevated(self, cx, ElevationIndex::ModalSurface)
elevated(self, cx, Elevation::ModalSurface)
}
/// See [`elevation_3`](Self::elevation_3).
///
/// Renders a borderless version [`elevation_3`](Self::elevation_3).
fn elevation_3_borderless(self, cx: &mut App) -> Self {
elevated_borderless(self, cx, ElevationIndex::ModalSurface)
elevated_borderless(self, cx, Elevation::ModalSurface)
}
/// The theme's primary border color.