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      .min_w(px(0.0))
73      .text_size(px(t.font_size(self.size)))
74      .font_weight(self.weight)
75      .text_color(color.hsla())
76      .child(self.content)
77      .probe("Text")
78      .attr("size", self.size.label())
79      .attr_if("dimmed", self.dimmed)
80  }
81}