label.rs

  1#![allow(missing_docs)]
  2
  3use gpui::{AnyElement, App, StyleRefinement, Window};
  4
  5use crate::{prelude::*, LabelCommon, LabelLike, LabelSize, LineHeightStyle};
  6
  7/// A struct representing a label element in the UI.
  8///
  9/// The `Label` struct stores the label text and common properties for a label element.
 10/// It provides methods for modifying these properties.
 11///
 12/// # Examples
 13///
 14/// ```
 15/// use ui::prelude::*;
 16///
 17/// Label::new("Hello, World!");
 18/// ```
 19///
 20/// **A colored label**, for example labeling a dangerous action:
 21///
 22/// ```
 23/// use ui::prelude::*;
 24///
 25/// let my_label = Label::new("Delete").color(Color::Error);
 26/// ```
 27///
 28/// **A label with a strikethrough**, for example labeling something that has been deleted:
 29///
 30/// ```
 31/// use ui::prelude::*;
 32///
 33/// let my_label = Label::new("Deleted").strikethrough(true);
 34/// ```
 35#[derive(IntoElement, IntoComponent)]
 36pub struct Label {
 37    base: LabelLike,
 38    label: SharedString,
 39}
 40
 41impl Label {
 42    /// Creates a new [`Label`] with the given text.
 43    ///
 44    /// # Examples
 45    ///
 46    /// ```
 47    /// use ui::prelude::*;
 48    ///
 49    /// let my_label = Label::new("Hello, World!");
 50    /// ```
 51    pub fn new(label: impl Into<SharedString>) -> Self {
 52        Self {
 53            base: LabelLike::new(),
 54            label: label.into(),
 55        }
 56    }
 57}
 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    fn weight(mut self, weight: gpui::FontWeight) -> Self {
 86        self.base = self.base.weight(weight);
 87        self
 88    }
 89
 90    /// Sets the line height style of the label using a [`LineHeightStyle`].
 91    ///
 92    /// # Examples
 93    ///
 94    /// ```
 95    /// use ui::prelude::*;
 96    ///
 97    /// let my_label = Label::new("Hello, World!").line_height_style(LineHeightStyle::UiLabel);
 98    /// ```
 99    fn line_height_style(mut self, line_height_style: LineHeightStyle) -> Self {
100        self.base = self.base.line_height_style(line_height_style);
101        self
102    }
103
104    /// Sets the color of the label using a [`Color`].
105    ///
106    /// # Examples
107    ///
108    /// ```
109    /// use ui::prelude::*;
110    ///
111    /// let my_label = Label::new("Hello, World!").color(Color::Accent);
112    /// ```
113    fn color(mut self, color: Color) -> Self {
114        self.base = self.base.color(color);
115        self
116    }
117
118    /// Sets the strikethrough property of the label.
119    ///
120    /// # Examples
121    ///
122    /// ```
123    /// use ui::prelude::*;
124    ///
125    /// let my_label = Label::new("Hello, World!").strikethrough(true);
126    /// ```
127    fn strikethrough(mut self, strikethrough: bool) -> Self {
128        self.base = self.base.strikethrough(strikethrough);
129        self
130    }
131
132    /// Sets the italic property of the label.
133    ///
134    /// # Examples
135    ///
136    /// ```
137    /// use ui::prelude::*;
138    ///
139    /// let my_label = Label::new("Hello, World!").italic(true);
140    /// ```
141    fn italic(mut self, italic: bool) -> Self {
142        self.base = self.base.italic(italic);
143        self
144    }
145
146    /// Sets the alpha property of the color of label.
147    ///
148    /// # Examples
149    ///
150    /// ```
151    /// use ui::prelude::*;
152    ///
153    /// let my_label = Label::new("Hello, World!").alpha(0.5);
154    /// ```
155    fn alpha(mut self, alpha: f32) -> Self {
156        self.base = self.base.alpha(alpha);
157        self
158    }
159
160    fn underline(mut self, underline: bool) -> Self {
161        self.base = self.base.underline(underline);
162        self
163    }
164
165    fn text_ellipsis(mut self) -> Self {
166        self.base = self.base.text_ellipsis();
167        self
168    }
169
170    fn single_line(mut self) -> Self {
171        self.label = SharedString::from(self.label.replace('\n', ""));
172        self.base = self.base.single_line();
173        self
174    }
175
176    fn buffer_font(mut self, cx: &App) -> Self {
177        self.base = self.base.buffer_font(cx);
178        self
179    }
180}
181
182impl RenderOnce for Label {
183    fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
184        self.base.child(self.label)
185    }
186}
187
188impl ComponentPreview for Label {
189    fn preview(_window: &mut Window, _cx: &App) -> AnyElement {
190        v_flex()
191            .gap_6()
192            .children(vec![
193                example_group_with_title(
194                    "Sizes",
195                    vec![
196                        single_example("Default", Label::new("Default Label").into_any_element()),
197                        single_example("Small", Label::new("Small Label").size(LabelSize::Small).into_any_element()),
198                        single_example("Large", Label::new("Large Label").size(LabelSize::Large).into_any_element()),
199                    ],
200                ),
201                example_group_with_title(
202                    "Colors",
203                    vec![
204                        single_example("Default", Label::new("Default Color").into_any_element()),
205                        single_example("Accent", Label::new("Accent Color").color(Color::Accent).into_any_element()),
206                        single_example("Error", Label::new("Error Color").color(Color::Error).into_any_element()),
207                    ],
208                ),
209                example_group_with_title(
210                    "Styles",
211                    vec![
212                        single_example("Default", Label::new("Default Style").into_any_element()),
213                        single_example("Bold", Label::new("Bold Style").weight(gpui::FontWeight::BOLD).into_any_element()),
214                        single_example("Italic", Label::new("Italic Style").italic(true).into_any_element()),
215                        single_example("Strikethrough", Label::new("Strikethrough Style").strikethrough(true).into_any_element()),
216                        single_example("Underline", Label::new("Underline Style").underline(true).into_any_element()),
217                    ],
218                ),
219                example_group_with_title(
220                    "Line Height Styles",
221                    vec![
222                        single_example("Default", Label::new("Default Line Height").into_any_element()),
223                        single_example("UI Label", Label::new("UI Label Line Height").line_height_style(LineHeightStyle::UiLabel).into_any_element()),
224                    ],
225                ),
226                example_group_with_title(
227                    "Special Cases",
228                    vec![
229                        single_example("Single Line", Label::new("Single\nLine\nText").single_line().into_any_element()),
230                        single_example("Text Ellipsis", Label::new("This is a very long text that should be truncated with an ellipsis").text_ellipsis().into_any_element()),
231                    ],
232                ),
233            ])
234            .into_any_element()
235    }
236}