Skip to main content

guise/
text.rs

1//! `Text` — themed inline text with size, weight, and color controls.
2
3use gpui::prelude::*;
4use gpui::{div, px, App, FontWeight, IntoElement, SharedString, Window};
5
6use crate::devtools::Probed;
7use crate::theme::{theme, Color, Size};
8
9/// Themed body text.
10#[derive(IntoElement)]
11pub struct Text {
12    content: SharedString,
13    size: Size,
14    weight: FontWeight,
15    color: Option<Color>,
16    dimmed: bool,
17}
18
19impl Text {
20    pub fn new(content: impl Into<SharedString>) -> Self {
21        Text {
22            content: content.into(),
23            size: Size::Md,
24            weight: FontWeight::NORMAL,
25            color: None,
26            dimmed: false,
27        }
28    }
29
30    pub fn size(mut self, size: Size) -> Self {
31        self.size = size;
32        self
33    }
34
35    pub fn weight(mut self, weight: FontWeight) -> Self {
36        self.weight = weight;
37        self
38    }
39
40    /// Render at the medium font weight (500).
41    pub fn medium(self) -> Self {
42        self.weight(FontWeight::MEDIUM)
43    }
44
45    /// Render at the bold font weight (700).
46    pub fn bold(self) -> Self {
47        self.weight(FontWeight::BOLD)
48    }
49
50    /// Override the text color.
51    pub fn color(mut self, color: Color) -> Self {
52        self.color = Some(color);
53        self
54    }
55
56    /// Use the muted/secondary text color.
57    pub fn dimmed(mut self) -> Self {
58        self.dimmed = true;
59        self
60    }
61}
62
63impl RenderOnce for Text {
64    fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
65        let t = theme(cx);
66        let color = match (self.color, self.dimmed) {
67            (Some(c), _) => c,
68            (None, true) => t.dimmed(),
69            (None, false) => t.text(),
70        };
71        div()
72            .text_size(px(t.font_size(self.size)))
73            .font_weight(self.weight)
74            .text_color(color.hsla())
75            .child(self.content)
76            .probe("Text")
77            .attr("size", self.size.label())
78            .attr_if("dimmed", self.dimmed)
79    }
80}