styled_ext.rs

  1use gpui::{hsla, px, Styled, WindowContext};
  2use settings::Settings;
  3use theme::ThemeSettings;
  4
  5use crate::prelude::*;
  6use crate::{ElevationIndex, UiTextSize};
  7
  8fn elevated<E: Styled>(this: E, cx: &mut WindowContext, index: ElevationIndex) -> E {
  9    this.bg(cx.theme().colors().elevated_surface_background)
 10        .z_index(index.z_index())
 11        .rounded(px(8.))
 12        .border()
 13        .border_color(cx.theme().colors().border_variant)
 14        .shadow(index.shadow())
 15}
 16
 17/// Extends [`Styled`](gpui::Styled) with Zed specific styling methods.
 18pub trait StyledExt: Styled + Sized {
 19    /// Sets the width of the element as a percentage of the viewport's width.
 20    ///
 21    /// `percent` should be a value between `0.0` and `1.0`.
 22    fn w_vw(self, percent: f32, cx: &mut WindowContext) -> Self {
 23        self.w(cx.viewport_size().width * percent)
 24    }
 25
 26    /// Sets the height of the element as a percentage of the viewport's height.
 27    ///
 28    /// `percent` should be a value between `0.0` and `1.0`.
 29    fn h_vh(self, percent: f32, cx: &mut WindowContext) -> Self {
 30        self.h(cx.viewport_size().height * percent)
 31    }
 32
 33    /// Horizontally stacks elements.
 34    ///
 35    /// Sets `flex()`, `flex_row()`, `items_center()`
 36    fn h_flex(self) -> Self {
 37        self.flex().flex_row().items_center()
 38    }
 39
 40    /// Vertically stacks elements.
 41    ///
 42    /// Sets `flex()`, `flex_col()`
 43    fn v_flex(self) -> Self {
 44        self.flex().flex_col()
 45    }
 46
 47    fn text_ui_size(self, size: UiTextSize) -> Self {
 48        self.text_size(size.rems())
 49    }
 50
 51    /// The default size for UI text.
 52    ///
 53    /// `0.825rem` or `14px` at the default scale of `1rem` = `16px`.
 54    ///
 55    /// Note: The absolute size of this text will change based on a user's `ui_scale` setting.
 56    ///
 57    /// Use [`text_ui_sm`] for regular-sized text.
 58    fn text_ui(self) -> Self {
 59        self.text_size(UiTextSize::default().rems())
 60    }
 61
 62    /// The small size for UI text.
 63    ///
 64    /// `0.75rem` or `12px` at the default scale of `1rem` = `16px`.
 65    ///
 66    /// Note: The absolute size of this text will change based on a user's `ui_scale` setting.
 67    ///
 68    /// Use [`text_ui`] for regular-sized text.
 69    fn text_ui_sm(self) -> Self {
 70        self.text_size(UiTextSize::Small.rems())
 71    }
 72
 73    /// The extra small size for UI text.
 74    ///
 75    /// `0.625rem` or `10px` at the default scale of `1rem` = `16px`.
 76    ///
 77    /// Note: The absolute size of this text will change based on a user's `ui_scale` setting.
 78    ///
 79    /// Use [`text_ui`] for regular-sized text.
 80    fn text_ui_xs(self) -> Self {
 81        self.text_size(UiTextSize::XSmall.rems())
 82    }
 83
 84    /// The font size for buffer text.
 85    ///
 86    /// Retrieves the default font size, or the user's custom font size if set.
 87    ///
 88    /// This should only be used for text that is displayed in a buffer,
 89    /// or other places that text needs to match the user's buffer font size.
 90    fn text_buffer(self, cx: &mut WindowContext) -> Self {
 91        let settings = ThemeSettings::get_global(cx);
 92        self.text_size(settings.buffer_font_size(cx))
 93    }
 94
 95    /// The [`Surface`](ui2::ElevationIndex::Surface) elevation level, located above the app background, is the standard level for all elements
 96    ///
 97    /// Sets `bg()`, `rounded_lg()`, `border()`, `border_color()`, `shadow()`
 98    ///
 99    /// Example Elements: Title Bar, Panel, Tab Bar, Editor
100    fn elevation_1(self, cx: &mut WindowContext) -> Self {
101        elevated(self, cx, ElevationIndex::Surface)
102    }
103
104    /// Non-Modal Elevated Surfaces appear above the [`Surface`](ui2::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.
105    ///
106    /// Sets `bg()`, `rounded_lg()`, `border()`, `border_color()`, `shadow()`
107    ///
108    /// Examples: Notifications, Palettes, Detached/Floating Windows, Detached/Floating Panels
109    fn elevation_2(self, cx: &mut WindowContext) -> Self {
110        elevated(self, cx, ElevationIndex::ElevatedSurface)
111    }
112
113    /// 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.
114    ///
115    /// 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.
116    ///
117    /// If the element does not have this behavior, it should be rendered at the [`Elevated Surface`](ui2::ElevationIndex::ElevatedSurface) layer.
118    ///
119    /// Sets `bg()`, `rounded_lg()`, `border()`, `border_color()`, `shadow()`
120    ///
121    /// Examples: Settings Modal, Channel Management, Wizards/Setup UI, Dialogs
122    fn elevation_3(self, cx: &mut WindowContext) -> Self {
123        elevated(self, cx, ElevationIndex::ModalSurface)
124    }
125
126    /// The theme's primary border color.
127    fn border_primary(self, cx: &mut WindowContext) -> Self {
128        self.border_color(cx.theme().colors().border)
129    }
130
131    /// The theme's secondary or muted border color.
132    fn border_muted(self, cx: &mut WindowContext) -> Self {
133        self.border_color(cx.theme().colors().border_variant)
134    }
135
136    fn debug_bg_red(self) -> Self {
137        self.bg(hsla(0. / 360., 1., 0.5, 1.))
138    }
139
140    fn debug_bg_green(self) -> Self {
141        self.bg(hsla(120. / 360., 1., 0.5, 1.))
142    }
143
144    fn debug_bg_blue(self) -> Self {
145        self.bg(hsla(240. / 360., 1., 0.5, 1.))
146    }
147
148    fn debug_bg_yellow(self) -> Self {
149        self.bg(hsla(60. / 360., 1., 0.5, 1.))
150    }
151
152    fn debug_bg_cyan(self) -> Self {
153        self.bg(hsla(160. / 360., 1., 0.5, 1.))
154    }
155
156    fn debug_bg_magenta(self) -> Self {
157        self.bg(hsla(300. / 360., 1., 0.5, 1.))
158    }
159}
160
161impl<E: Styled> StyledExt for E {}