label.rs

  1use crate::{prelude::*, LabelLike};
  2use gpui::StyleRefinement;
  3
  4/// A struct representing a label element in the UI.
  5///
  6/// The `Label` struct stores the label text and common properties for a label element.
  7/// It provides methods for modifying these properties.
  8///
  9/// # Examples
 10///
 11/// ```
 12/// use ui::prelude::*;
 13///
 14/// Label::new("Hello, World!");
 15/// ```
 16///
 17/// **A colored label**, for example labeling a dangerous action:
 18///
 19/// ```
 20/// use ui::prelude::*;
 21///
 22/// let my_label = Label::new("Delete").color(Color::Error);
 23/// ```
 24///
 25/// **A label with a strikethrough**, for example labeling something that has been deleted:
 26///
 27/// ```
 28/// use ui::prelude::*;
 29///
 30/// let my_label = Label::new("Deleted").strikethrough(true);
 31/// ```
 32#[derive(IntoElement, IntoComponent)]
 33pub struct Label {
 34    base: LabelLike,
 35    label: SharedString,
 36}
 37
 38impl Label {
 39    /// Creates a new [`Label`] with the given text.
 40    ///
 41    /// # Examples
 42    ///
 43    /// ```
 44    /// use ui::prelude::*;
 45    ///
 46    /// let my_label = Label::new("Hello, World!");
 47    /// ```
 48    pub fn new(label: impl Into<SharedString>) -> Self {
 49        Self {
 50            base: LabelLike::new(),
 51            label: label.into(),
 52        }
 53    }
 54}
 55
 56// nate: If we are going to do this, we might as well just
 57// impl Styled for Label and not constrain styles
 58
 59// Style methods.
 60impl Label {
 61    fn style(&mut self) -> &mut StyleRefinement {
 62        self.base.base.style()
 63    }
 64
 65    gpui::margin_style_methods!({
 66        visibility: pub
 67    });
 68}
 69
 70impl LabelCommon for Label {
 71    /// Sets the size of the label using a [`LabelSize`].
 72    ///
 73    /// # Examples
 74    ///
 75    /// ```
 76    /// use ui::prelude::*;
 77    ///
 78    /// let my_label = Label::new("Hello, World!").size(LabelSize::Small);
 79    /// ```
 80    fn size(mut self, size: LabelSize) -> Self {
 81        self.base = self.base.size(size);
 82        self
 83    }
 84
 85    /// Sets the weight of the label using a [`FontWeight`].
 86    ///
 87    /// # Examples
 88    ///
 89    /// ```
 90    /// use ui::prelude::*;
 91    ///
 92    /// let my_label = Label::new("Hello, World!").weight(FontWeight::Bold);
 93    /// ```
 94    fn weight(mut self, weight: gpui::FontWeight) -> Self {
 95        self.base = self.base.weight(weight);
 96        self
 97    }
 98
 99    /// Sets the line height style of the label using a [`LineHeightStyle`].
100    ///
101    /// # Examples
102    ///
103    /// ```
104    /// use ui::prelude::*;
105    ///
106    /// let my_label = Label::new("Hello, World!").line_height_style(LineHeightStyle::UiLabel);
107    /// ```
108    fn line_height_style(mut self, line_height_style: LineHeightStyle) -> Self {
109        self.base = self.base.line_height_style(line_height_style);
110        self
111    }
112
113    /// Sets the color of the label using a [`Color`].
114    ///
115    /// # Examples
116    ///
117    /// ```
118    /// use ui::prelude::*;
119    ///
120    /// let my_label = Label::new("Hello, World!").color(Color::Accent);
121    /// ```
122    fn color(mut self, color: Color) -> Self {
123        self.base = self.base.color(color);
124        self
125    }
126
127    /// Sets the strikethrough property of the label.
128    ///
129    /// # Examples
130    ///
131    /// ```
132    /// use ui::prelude::*;
133    ///
134    /// let my_label = Label::new("Hello, World!").strikethrough(true);
135    /// ```
136    fn strikethrough(mut self) -> Self {
137        self.base = self.base.strikethrough();
138        self
139    }
140
141    /// Sets the italic property of the label.
142    ///
143    /// # Examples
144    ///
145    /// ```
146    /// use ui::prelude::*;
147    ///
148    /// let my_label = Label::new("Hello, World!").italic(true);
149    /// ```
150    fn italic(mut self) -> Self {
151        self.base = self.base.italic();
152        self
153    }
154
155    /// Sets the alpha property of the color of label.
156    ///
157    /// # Examples
158    ///
159    /// ```
160    /// use ui::prelude::*;
161    ///
162    /// let my_label = Label::new("Hello, World!").alpha(0.5);
163    /// ```
164    fn alpha(mut self, alpha: f32) -> Self {
165        self.base = self.base.alpha(alpha);
166        self
167    }
168
169    fn underline(mut self) -> Self {
170        self.base = self.base.underline();
171        self
172    }
173
174    fn text_ellipsis(mut self) -> Self {
175        self.base = self.base.text_ellipsis();
176        self
177    }
178
179    fn single_line(mut self) -> Self {
180        self.label = SharedString::from(self.label.replace('\n', ""));
181        self.base = self.base.single_line();
182        self
183    }
184
185    fn buffer_font(mut self, cx: &App) -> Self {
186        self.base = self.base.buffer_font(cx);
187        self
188    }
189}
190
191impl RenderOnce for Label {
192    fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
193        self.base.child(self.label)
194    }
195}
196
197mod label_preview {
198    use crate::prelude::*;
199
200    // View this component preview using `workspace: open component-preview`
201    impl ComponentPreview for Label {
202        fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement {
203            v_flex()
204                .gap_6()
205                .children(vec![
206                    example_group_with_title(
207                        "Sizes",
208                        vec![
209                            single_example("Default", Label::new("Project Explorer").into_any_element()),
210                            single_example("Small", Label::new("File: main.rs").size(LabelSize::Small).into_any_element()),
211                            single_example("Large", Label::new("Welcome to Zed").size(LabelSize::Large).into_any_element()),
212                        ],
213                    ),
214                    example_group_with_title(
215                        "Colors",
216                        vec![
217                            single_example("Default", Label::new("Status: Ready").into_any_element()),
218                            single_example("Accent", Label::new("New Update Available").color(Color::Accent).into_any_element()),
219                            single_example("Error", Label::new("Build Failed").color(Color::Error).into_any_element()),
220                        ],
221                    ),
222                    example_group_with_title(
223                        "Styles",
224                        vec![
225                            single_example("Default", Label::new("Normal Text").into_any_element()),
226                            single_example("Bold", Label::new("Important Notice").weight(gpui::FontWeight::BOLD).into_any_element()),
227                            single_example("Italic", Label::new("Code Comment").italic().into_any_element()),
228                            single_example("Strikethrough", Label::new("Deprecated Feature").strikethrough().into_any_element()),
229                            single_example("Underline", Label::new("Clickable Link").underline().into_any_element()),
230                        ],
231                    ),
232                    example_group_with_title(
233                        "Line Height Styles",
234                        vec![
235                            single_example("Default", Label::new("Multi-line\nText\nExample").into_any_element()),
236                            single_example("UI Label", Label::new("Compact\nUI\nLabel").line_height_style(LineHeightStyle::UiLabel).into_any_element()),
237                        ],
238                    ),
239                    example_group_with_title(
240                        "Special Cases",
241                        vec![
242                            single_example("Single Line", Label::new("Line 1\nLine 2\nLine 3").single_line().into_any_element()),
243                            single_example("Text Ellipsis", div().max_w_24().child(Label::new("This is a very long file name that should be truncated: very_long_file_name_with_many_words.rs").text_ellipsis()).into_any_element()),
244                        ],
245                    ),
246                ])
247                .into_any_element()
248        }
249    }
250}