chip.rs

  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    border_color: Option<Hsla>,
 20    height: Option<Pixels>,
 21    tooltip: Option<Box<dyn Fn(&mut Window, &mut App) -> AnyView + 'static>>,
 22}
 23
 24impl Chip {
 25    /// Creates a new `Chip` component with the specified label.
 26    pub fn new(label: impl Into<SharedString>) -> Self {
 27        Self {
 28            label: label.into(),
 29            label_color: Color::Default,
 30            label_size: LabelSize::XSmall,
 31            bg_color: None,
 32            border_color: None,
 33            height: None,
 34            tooltip: None,
 35        }
 36    }
 37
 38    /// Sets the color of the label.
 39    pub fn label_color(mut self, color: Color) -> Self {
 40        self.label_color = color;
 41        self
 42    }
 43
 44    /// Sets the size of the label.
 45    pub fn label_size(mut self, size: LabelSize) -> Self {
 46        self.label_size = size;
 47        self
 48    }
 49
 50    /// Sets a custom background color for the callout content.
 51    pub fn bg_color(mut self, color: Hsla) -> Self {
 52        self.bg_color = Some(color);
 53        self
 54    }
 55
 56    /// Sets a custom border color for the chip.
 57    pub fn border_color(mut self, color: Hsla) -> Self {
 58        self.border_color = Some(color);
 59        self
 60    }
 61
 62    /// Sets a custom height for the chip.
 63    pub fn height(mut self, height: Pixels) -> Self {
 64        self.height = Some(height);
 65        self
 66    }
 67
 68    pub fn tooltip(mut self, tooltip: impl Fn(&mut Window, &mut App) -> AnyView + 'static) -> Self {
 69        self.tooltip = Some(Box::new(tooltip));
 70        self
 71    }
 72}
 73
 74impl RenderOnce for Chip {
 75    fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement {
 76        let bg_color = self
 77            .bg_color
 78            .unwrap_or(cx.theme().colors().element_background);
 79
 80        let border_color = self.border_color.unwrap_or(cx.theme().colors().border);
 81
 82        h_flex()
 83            .when_some(self.height, |this, h| this.h(h))
 84            .min_w_0()
 85            .flex_initial()
 86            .px_1()
 87            .border_1()
 88            .rounded_sm()
 89            .border_color(border_color)
 90            .bg(bg_color)
 91            .overflow_hidden()
 92            .child(
 93                Label::new(self.label.clone())
 94                    .size(self.label_size)
 95                    .color(self.label_color)
 96                    .buffer_font(cx)
 97                    .truncate(),
 98            )
 99            .id(self.label.clone())
100            .when_some(self.tooltip, |this, tooltip| this.tooltip(tooltip))
101    }
102}
103
104impl Component for Chip {
105    fn scope() -> ComponentScope {
106        ComponentScope::DataDisplay
107    }
108
109    fn preview(_window: &mut Window, cx: &mut App) -> Option<AnyElement> {
110        let chip_examples = vec![
111            single_example("Default", Chip::new("Chip Example").into_any_element()),
112            single_example(
113                "Customized Label Color",
114                Chip::new("Chip Example")
115                    .label_color(Color::Accent)
116                    .into_any_element(),
117            ),
118            single_example(
119                "Customized Label Size",
120                Chip::new("Chip Example")
121                    .label_size(LabelSize::Large)
122                    .label_color(Color::Accent)
123                    .into_any_element(),
124            ),
125            single_example(
126                "Customized Background Color",
127                Chip::new("Chip Example")
128                    .bg_color(cx.theme().colors().text_accent.opacity(0.1))
129                    .into_any_element(),
130            ),
131        ];
132
133        Some(example_group(chip_examples).vertical().into_any_element())
134    }
135}