1use crate::prelude::*;
2use gpui::{AnyElement, AnyView, Hsla, IntoElement, ParentElement, Styled};
3
4/// Chips provide a container for an informative label.
5///
6/// # Usage Example
7///
8/// ```
9/// use ui::Chip;
10///
11/// let chip = Chip::new("This Chip");
12/// ```
13#[derive(IntoElement, RegisterComponent)]
14pub struct Chip {
15 label: SharedString,
16 label_color: Color,
17 label_size: LabelSize,
18 bg_color: Option<Hsla>,
19 tooltip: Option<Box<dyn Fn(&mut Window, &mut App) -> AnyView + 'static>>,
20}
21
22impl Chip {
23 /// Creates a new `Chip` component with the specified label.
24 pub fn new(label: impl Into<SharedString>) -> Self {
25 Self {
26 label: label.into(),
27 label_color: Color::Default,
28 label_size: LabelSize::XSmall,
29 bg_color: None,
30 tooltip: None,
31 }
32 }
33
34 /// Sets the color of the label.
35 pub fn label_color(mut self, color: Color) -> Self {
36 self.label_color = color;
37 self
38 }
39
40 /// Sets the size of the label.
41 pub fn label_size(mut self, size: LabelSize) -> Self {
42 self.label_size = size;
43 self
44 }
45
46 /// Sets a custom background color for the callout content.
47 pub fn bg_color(mut self, color: Hsla) -> Self {
48 self.bg_color = Some(color);
49 self
50 }
51
52 pub fn tooltip(mut self, tooltip: impl Fn(&mut Window, &mut App) -> AnyView + 'static) -> Self {
53 self.tooltip = Some(Box::new(tooltip));
54 self
55 }
56}
57
58impl RenderOnce for Chip {
59 fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement {
60 let bg_color = self
61 .bg_color
62 .unwrap_or(cx.theme().colors().element_background);
63
64 h_flex()
65 .min_w_0()
66 .flex_initial()
67 .px_1()
68 .border_1()
69 .rounded_sm()
70 .border_color(cx.theme().colors().border)
71 .bg(bg_color)
72 .overflow_hidden()
73 .child(
74 Label::new(self.label.clone())
75 .size(self.label_size)
76 .color(self.label_color)
77 .buffer_font(cx),
78 )
79 .id(self.label.clone())
80 .when_some(self.tooltip, |this, tooltip| this.tooltip(tooltip))
81 }
82}
83
84impl Component for Chip {
85 fn scope() -> ComponentScope {
86 ComponentScope::DataDisplay
87 }
88
89 fn preview(_window: &mut Window, cx: &mut App) -> Option<AnyElement> {
90 let chip_examples = vec![
91 single_example("Default", Chip::new("Chip Example").into_any_element()),
92 single_example(
93 "Customized Label Color",
94 Chip::new("Chip Example")
95 .label_color(Color::Accent)
96 .into_any_element(),
97 ),
98 single_example(
99 "Customized Label Size",
100 Chip::new("Chip Example")
101 .label_size(LabelSize::Large)
102 .label_color(Color::Accent)
103 .into_any_element(),
104 ),
105 single_example(
106 "Customized Background Color",
107 Chip::new("Chip Example")
108 .bg_color(cx.theme().colors().text_accent.opacity(0.1))
109 .into_any_element(),
110 ),
111 ];
112
113 Some(example_group(chip_examples).vertical().into_any_element())
114 }
115}