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    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}