1use gpui::{StyleRefinement, WindowContext};
2
3use crate::{prelude::*, LabelCommon, LabelLike, LabelSize, LineHeightStyle};
4
5/// A struct representing a label element in the UI.
6///
7/// The `Label` struct stores the label text and common properties for a label element.
8/// It provides methods for modifying these properties.
9///
10/// # Examples
11///
12/// ```
13/// use ui::prelude::*;
14///
15/// Label::new("Hello, World!");
16/// ```
17///
18/// **A colored label**, for example labeling a dangerous action:
19///
20/// ```
21/// use ui::prelude::*;
22///
23/// let my_label = Label::new("Delete").color(Color::Error);
24/// ```
25///
26/// **A label with a strikethrough**, for example labeling something that has been deleted:
27///
28/// ```
29/// use ui::prelude::*;
30///
31/// let my_label = Label::new("Deleted").strikethrough(true);
32/// ```
33#[derive(IntoElement)]
34pub struct Label {
35 base: LabelLike,
36 label: SharedString,
37 single_line: bool,
38}
39
40impl Label {
41 /// Creates a new [`Label`] with the given text.
42 ///
43 /// # Examples
44 ///
45 /// ```
46 /// use ui::prelude::*;
47 ///
48 /// let my_label = Label::new("Hello, World!");
49 /// ```
50 pub fn new(label: impl Into<SharedString>) -> Self {
51 Self {
52 base: LabelLike::new(),
53 label: label.into(),
54 single_line: false,
55 }
56 }
57
58 /// Make the label display in a single line mode
59 ///
60 /// # Examples
61 ///
62 /// ```
63 /// use ui::prelude::*;
64 ///
65 /// let my_label = Label::new("Hello, World!").single_line();
66 /// ```
67 pub fn single_line(mut self) -> Self {
68 self.single_line = true;
69 self
70 }
71}
72
73// Style methods.
74impl Label {
75 fn style(&mut self) -> &mut StyleRefinement {
76 self.base.base.style()
77 }
78
79 gpui::margin_style_methods!({
80 visibility: pub
81 });
82}
83
84impl LabelCommon for Label {
85 /// Sets the size of the label using a [`LabelSize`].
86 ///
87 /// # Examples
88 ///
89 /// ```
90 /// use ui::prelude::*;
91 ///
92 /// let my_label = Label::new("Hello, World!").size(LabelSize::Small);
93 /// ```
94 fn size(mut self, size: LabelSize) -> Self {
95 self.base = self.base.size(size);
96 self
97 }
98
99 fn weight(mut self, weight: gpui::FontWeight) -> Self {
100 self.base = self.base.weight(weight);
101 self
102 }
103
104 /// Sets the line height style of the label using a [`LineHeightStyle`].
105 ///
106 /// # Examples
107 ///
108 /// ```
109 /// use ui::prelude::*;
110 ///
111 /// let my_label = Label::new("Hello, World!").line_height_style(LineHeightStyle::UiLabel);
112 /// ```
113 fn line_height_style(mut self, line_height_style: LineHeightStyle) -> Self {
114 self.base = self.base.line_height_style(line_height_style);
115 self
116 }
117
118 /// Sets the color of the label using a [`Color`].
119 ///
120 /// # Examples
121 ///
122 /// ```
123 /// use ui::prelude::*;
124 ///
125 /// let my_label = Label::new("Hello, World!").color(Color::Accent);
126 /// ```
127 fn color(mut self, color: Color) -> Self {
128 self.base = self.base.color(color);
129 self
130 }
131
132 /// Sets the strikethrough property of the label.
133 ///
134 /// # Examples
135 ///
136 /// ```
137 /// use ui::prelude::*;
138 ///
139 /// let my_label = Label::new("Hello, World!").strikethrough(true);
140 /// ```
141 fn strikethrough(mut self, strikethrough: bool) -> Self {
142 self.base = self.base.strikethrough(strikethrough);
143 self
144 }
145
146 /// Sets the italic property of the label.
147 ///
148 /// # Examples
149 ///
150 /// ```
151 /// use ui::prelude::*;
152 ///
153 /// let my_label = Label::new("Hello, World!").italic(true);
154 /// ```
155 fn italic(mut self, italic: bool) -> Self {
156 self.base = self.base.italic(italic);
157 self
158 }
159
160 /// Sets the alpha property of the color of label.
161 ///
162 /// # Examples
163 ///
164 /// ```
165 /// use ui::prelude::*;
166 ///
167 /// let my_label = Label::new("Hello, World!").alpha(0.5);
168 /// ```
169 fn alpha(mut self, alpha: f32) -> Self {
170 self.base = self.base.alpha(alpha);
171 self
172 }
173}
174
175impl RenderOnce for Label {
176 fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
177 let target_label = if self.single_line {
178 SharedString::from(self.label.replace('\n', ""))
179 } else {
180 self.label
181 };
182 self.base.child(target_label)
183 }
184}