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 small size for UI text.
 17    ///
 18    /// `0.75rem` or `12px` 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    Small,
 22
 23    /// The extra small size for UI text.
 24    ///
 25    /// `0.625rem` or `10px` 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    XSmall,
 29}
 30
 31impl UiTextSize {
 32    pub fn rems(self) -> Rems {
 33        match self {
 34            Self::Default => rems(14. / 16.),
 35            Self::Small => rems(12. / 16.),
 36            Self::XSmall => rems(10. / 16.),
 37        }
 38    }
 39}
 40
 41/// The size of a [`Headline`] element
 42#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Default)]
 43pub enum HeadlineSize {
 44    XSmall,
 45    Small,
 46    #[default]
 47    Medium,
 48    Large,
 49    XLarge,
 50}
 51
 52impl HeadlineSize {
 53    pub fn size(self) -> Rems {
 54        match self {
 55            // Based on the Major Second scale
 56            Self::XSmall => rems(0.88),
 57            Self::Small => rems(1.0),
 58            Self::Medium => rems(1.125),
 59            Self::Large => rems(1.27),
 60            Self::XLarge => rems(1.43),
 61        }
 62    }
 63
 64    pub fn line_height(self) -> Rems {
 65        match self {
 66            Self::XSmall => rems(1.6),
 67            Self::Small => rems(1.6),
 68            Self::Medium => rems(1.6),
 69            Self::Large => rems(1.6),
 70            Self::XLarge => rems(1.6),
 71        }
 72    }
 73}
 74
 75#[derive(IntoElement)]
 76pub struct Headline {
 77    size: HeadlineSize,
 78    text: SharedString,
 79}
 80
 81impl RenderOnce for Headline {
 82    fn render(self, cx: &mut WindowContext) -> impl IntoElement {
 83        let ui_font = ThemeSettings::get_global(cx).ui_font.family.clone();
 84
 85        div()
 86            .font(ui_font)
 87            .line_height(self.size.line_height())
 88            .text_size(self.size.size())
 89            .text_color(cx.theme().colors().text)
 90            .child(self.text)
 91    }
 92}
 93
 94impl Headline {
 95    pub fn new(text: impl Into<SharedString>) -> Self {
 96        Self {
 97            size: HeadlineSize::default(),
 98            text: text.into(),
 99        }
100    }
101
102    pub fn size(mut self, size: HeadlineSize) -> Self {
103        self.size = size;
104        self
105    }
106}