Files
oak-gpui/crates/ui/src/components/label/label.rs
T
9d8a163f5b git_ui: New panel design (#25821)
This PR updates the ui of the git panel. It removes the header from the
panel and unifies the repository, branch and commit controls in the
bottom section.

It also adds a secondary menu to the primary button giving access to a
variety of actions for managing local and remote changes:

![CleanShot 2025-02-28 at 12 18
15@2x](https://github.com/user-attachments/assets/0260c122-405f-46fc-8cc8-d6beac782b9d)

Known issues (will be fixed in a later pr)
- Spinner showing git operation progress was removed, will be re-added
- Clicking expand with the panel editor focused will commit (due to
shared action name. Already tracked)

Before | After

![CleanShot 2025-02-28 at 12 22
18@2x](https://github.com/user-attachments/assets/4c1e4ac9-b975-487f-bf4e-8815a8da4f4f)

(Also adds `component`, `linkme` to cargo-machete ignore as they are
used in the `IntoComponent` proc-macro and will always be incorrectly
flagged as unused)

Release Notes:

- N/A

---------

Co-authored-by: Cole Miller <m@cole-miller.net>
Co-authored-by: Cole Miller <53574922+cole-miller@users.noreply.github.com>
Co-authored-by: Cole Miller <cole@zed.dev>
2025-02-28 20:00:39 +00:00

251 lines
7.6 KiB
Rust

use crate::{prelude::*, LabelLike};
use gpui::StyleRefinement;
/// A struct representing a label element in the UI.
///
/// The `Label` struct stores the label text and common properties for a label element.
/// It provides methods for modifying these properties.
///
/// # Examples
///
/// ```
/// use ui::prelude::*;
///
/// Label::new("Hello, World!");
/// ```
///
/// **A colored label**, for example labeling a dangerous action:
///
/// ```
/// use ui::prelude::*;
///
/// let my_label = Label::new("Delete").color(Color::Error);
/// ```
///
/// **A label with a strikethrough**, for example labeling something that has been deleted:
///
/// ```
/// use ui::prelude::*;
///
/// let my_label = Label::new("Deleted").strikethrough(true);
/// ```
#[derive(IntoElement, IntoComponent)]
pub struct Label {
base: LabelLike,
label: SharedString,
}
impl Label {
/// Creates a new [`Label`] with the given text.
///
/// # Examples
///
/// ```
/// use ui::prelude::*;
///
/// let my_label = Label::new("Hello, World!");
/// ```
pub fn new(label: impl Into<SharedString>) -> Self {
Self {
base: LabelLike::new(),
label: label.into(),
}
}
}
// nate: If we are going to do this, we might as well just
// impl Styled for Label and not constrain styles
// Style methods.
impl Label {
fn style(&mut self) -> &mut StyleRefinement {
self.base.base.style()
}
gpui::margin_style_methods!({
visibility: pub
});
}
impl LabelCommon for Label {
/// Sets the size of the label using a [`LabelSize`].
///
/// # Examples
///
/// ```
/// use ui::prelude::*;
///
/// let my_label = Label::new("Hello, World!").size(LabelSize::Small);
/// ```
fn size(mut self, size: LabelSize) -> Self {
self.base = self.base.size(size);
self
}
/// Sets the weight of the label using a [`FontWeight`].
///
/// # Examples
///
/// ```
/// use ui::prelude::*;
///
/// let my_label = Label::new("Hello, World!").weight(FontWeight::Bold);
/// ```
fn weight(mut self, weight: gpui::FontWeight) -> Self {
self.base = self.base.weight(weight);
self
}
/// Sets the line height style of the label using a [`LineHeightStyle`].
///
/// # Examples
///
/// ```
/// use ui::prelude::*;
///
/// let my_label = Label::new("Hello, World!").line_height_style(LineHeightStyle::UiLabel);
/// ```
fn line_height_style(mut self, line_height_style: LineHeightStyle) -> Self {
self.base = self.base.line_height_style(line_height_style);
self
}
/// Sets the color of the label using a [`Color`].
///
/// # Examples
///
/// ```
/// use ui::prelude::*;
///
/// let my_label = Label::new("Hello, World!").color(Color::Accent);
/// ```
fn color(mut self, color: Color) -> Self {
self.base = self.base.color(color);
self
}
/// Sets the strikethrough property of the label.
///
/// # Examples
///
/// ```
/// use ui::prelude::*;
///
/// let my_label = Label::new("Hello, World!").strikethrough(true);
/// ```
fn strikethrough(mut self) -> Self {
self.base = self.base.strikethrough();
self
}
/// Sets the italic property of the label.
///
/// # Examples
///
/// ```
/// use ui::prelude::*;
///
/// let my_label = Label::new("Hello, World!").italic(true);
/// ```
fn italic(mut self) -> Self {
self.base = self.base.italic();
self
}
/// Sets the alpha property of the color of label.
///
/// # Examples
///
/// ```
/// use ui::prelude::*;
///
/// let my_label = Label::new("Hello, World!").alpha(0.5);
/// ```
fn alpha(mut self, alpha: f32) -> Self {
self.base = self.base.alpha(alpha);
self
}
fn underline(mut self) -> Self {
self.base = self.base.underline();
self
}
fn text_ellipsis(mut self) -> Self {
self.base = self.base.text_ellipsis();
self
}
fn single_line(mut self) -> Self {
self.label = SharedString::from(self.label.replace('\n', "⏎"));
self.base = self.base.single_line();
self
}
fn buffer_font(mut self, cx: &App) -> Self {
self.base = self.base.buffer_font(cx);
self
}
}
impl RenderOnce for Label {
fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
self.base.child(self.label)
}
}
mod label_preview {
use crate::prelude::*;
// View this component preview using `workspace: open component-preview`
impl ComponentPreview for Label {
fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement {
v_flex()
.gap_6()
.children(vec![
example_group_with_title(
"Sizes",
vec![
single_example("Default", Label::new("Project Explorer").into_any_element()),
single_example("Small", Label::new("File: main.rs").size(LabelSize::Small).into_any_element()),
single_example("Large", Label::new("Welcome to Zed").size(LabelSize::Large).into_any_element()),
],
),
example_group_with_title(
"Colors",
vec![
single_example("Default", Label::new("Status: Ready").into_any_element()),
single_example("Accent", Label::new("New Update Available").color(Color::Accent).into_any_element()),
single_example("Error", Label::new("Build Failed").color(Color::Error).into_any_element()),
],
),
example_group_with_title(
"Styles",
vec![
single_example("Default", Label::new("Normal Text").into_any_element()),
single_example("Bold", Label::new("Important Notice").weight(gpui::FontWeight::BOLD).into_any_element()),
single_example("Italic", Label::new("Code Comment").italic().into_any_element()),
single_example("Strikethrough", Label::new("Deprecated Feature").strikethrough().into_any_element()),
single_example("Underline", Label::new("Clickable Link").underline().into_any_element()),
],
),
example_group_with_title(
"Line Height Styles",
vec![
single_example("Default", Label::new("Multi-line\nText\nExample").into_any_element()),
single_example("UI Label", Label::new("Compact\nUI\nLabel").line_height_style(LineHeightStyle::UiLabel).into_any_element()),
],
),
example_group_with_title(
"Special Cases",
vec![
single_example("Single Line", Label::new("Line 1\nLine 2\nLine 3").single_line().into_any_element()),
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()),
],
),
])
.into_any_element()
}
}
}