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