typography.rs

  1use gpui::{
  2    div, rems, IntoElement, ParentElement, Rems, RenderOnce, SharedString, Styled, WindowContext,
  3};
  4use settings::Settings;
  5use theme::{ActiveTheme, ThemeSettings};
  6
  7#[derive(Debug, Default, Clone)]
  8pub enum UiTextSize {
  9    /// The default size for UI text.
 10    ///
 11    /// `0.825rem` or `14px` at the default scale of `1rem` = `16px`.
 12    ///
 13    /// Note: The absolute size of this text will change based on a user's `ui_scale` setting.
 14    #[default]
 15    Default,
 16    /// The large size for UI text.
 17    ///
 18    /// `1rem` or `16px` at the default scale of `1rem` = `16px`.
 19    ///
 20    /// Note: The absolute size of this text will change based on a user's `ui_scale` setting.
 21    Large,
 22
 23    /// The small size for UI text.
 24    ///
 25    /// `0.75rem` or `12px` at the default scale of `1rem` = `16px`.
 26    ///
 27    /// Note: The absolute size of this text will change based on a user's `ui_scale` setting.
 28    Small,
 29
 30    /// The extra small size for UI text.
 31    ///
 32    /// `0.625rem` or `10px` at the default scale of `1rem` = `16px`.
 33    ///
 34    /// Note: The absolute size of this text will change based on a user's `ui_scale` setting.
 35    XSmall,
 36}
 37
 38impl UiTextSize {
 39    pub fn rems(self) -> Rems {
 40        match self {
 41            Self::Large => rems(16. / 16.),
 42            Self::Default => rems(14. / 16.),
 43            Self::Small => rems(12. / 16.),
 44            Self::XSmall => rems(10. / 16.),
 45        }
 46    }
 47}
 48
 49/// The size of a [`Headline`] element
 50#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Default)]
 51pub enum HeadlineSize {
 52    XSmall,
 53    Small,
 54    #[default]
 55    Medium,
 56    Large,
 57    XLarge,
 58}
 59
 60impl HeadlineSize {
 61    pub fn size(self) -> Rems {
 62        match self {
 63            // Based on the Major Second scale
 64            Self::XSmall => rems(0.88),
 65            Self::Small => rems(1.0),
 66            Self::Medium => rems(1.125),
 67            Self::Large => rems(1.27),
 68            Self::XLarge => rems(1.43),
 69        }
 70    }
 71
 72    pub fn line_height(self) -> Rems {
 73        match self {
 74            Self::XSmall => rems(1.6),
 75            Self::Small => rems(1.6),
 76            Self::Medium => rems(1.6),
 77            Self::Large => rems(1.6),
 78            Self::XLarge => rems(1.6),
 79        }
 80    }
 81}
 82
 83#[derive(IntoElement)]
 84pub struct Headline {
 85    size: HeadlineSize,
 86    text: SharedString,
 87}
 88
 89impl RenderOnce for Headline {
 90    fn render(self, cx: &mut WindowContext) -> impl IntoElement {
 91        let ui_font = ThemeSettings::get_global(cx).ui_font.family.clone();
 92
 93        div()
 94            .font(ui_font)
 95            .line_height(self.size.line_height())
 96            .text_size(self.size.size())
 97            .text_color(cx.theme().colors().text)
 98            .child(self.text)
 99    }
100}
101
102impl Headline {
103    pub fn new(text: impl Into<SharedString>) -> Self {
104        Self {
105            size: HeadlineSize::default(),
106            text: text.into(),
107        }
108    }
109
110    pub fn size(mut self, size: HeadlineSize) -> Self {
111        self.size = size;
112        self
113    }
114}