1use gpui::{relative, AnyElement, Styled};
2use smallvec::SmallVec;
3
4use crate::prelude::*;
5
6#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Default)]
7pub enum LabelSize {
8 #[default]
9 Default,
10 Small,
11 XSmall,
12}
13
14#[derive(Default, PartialEq, Copy, Clone)]
15pub enum LineHeightStyle {
16 #[default]
17 TextLabel,
18 /// Sets the line height to 1.
19 UiLabel,
20}
21
22/// A common set of traits all labels must implement.
23pub trait LabelCommon {
24 fn size(self, size: LabelSize) -> Self;
25 fn line_height_style(self, line_height_style: LineHeightStyle) -> Self;
26 fn color(self, color: Color) -> Self;
27 fn strikethrough(self, strikethrough: bool) -> Self;
28}
29
30#[derive(IntoElement)]
31pub struct LabelLike {
32 size: LabelSize,
33 line_height_style: LineHeightStyle,
34 pub(crate) color: Color,
35 strikethrough: bool,
36 children: SmallVec<[AnyElement; 2]>,
37}
38
39impl LabelLike {
40 pub fn new() -> Self {
41 Self {
42 size: LabelSize::Default,
43 line_height_style: LineHeightStyle::default(),
44 color: Color::Default,
45 strikethrough: false,
46 children: SmallVec::new(),
47 }
48 }
49}
50
51impl LabelCommon for LabelLike {
52 fn size(mut self, size: LabelSize) -> Self {
53 self.size = size;
54 self
55 }
56
57 fn line_height_style(mut self, line_height_style: LineHeightStyle) -> Self {
58 self.line_height_style = line_height_style;
59 self
60 }
61
62 fn color(mut self, color: Color) -> Self {
63 self.color = color;
64 self
65 }
66
67 fn strikethrough(mut self, strikethrough: bool) -> Self {
68 self.strikethrough = strikethrough;
69 self
70 }
71}
72
73impl ParentElement for LabelLike {
74 fn children_mut(&mut self) -> &mut SmallVec<[AnyElement; 2]> {
75 &mut self.children
76 }
77}
78
79impl RenderOnce for LabelLike {
80 fn render(self, cx: &mut WindowContext) -> impl IntoElement {
81 div()
82 .when(self.strikethrough, |this| {
83 this.relative().child(
84 div()
85 .absolute()
86 .top_1_2()
87 .w_full()
88 .h_px()
89 .bg(Color::Hidden.color(cx)),
90 )
91 })
92 .map(|this| match self.size {
93 LabelSize::Default => this.text_ui(),
94 LabelSize::Small => this.text_ui_sm(),
95 LabelSize::XSmall => this.text_ui_xs(),
96 })
97 .when(self.line_height_style == LineHeightStyle::UiLabel, |this| {
98 this.line_height(relative(1.))
99 })
100 .text_color(self.color.color(cx))
101 .children(self.children)
102 }
103}