1use crate::Divider;
2use crate::DividerColor;
3use crate::component_prelude::*;
4use crate::prelude::*;
5use gpui::{AnyElement, IntoElement, SharedString, Window};
6
7#[derive(IntoElement, RegisterComponent)]
8pub struct Badge {
9 label: SharedString,
10 icon: IconName,
11}
12
13impl Badge {
14 pub fn new(label: impl Into<SharedString>) -> Self {
15 Self {
16 label: label.into(),
17 icon: IconName::Check,
18 }
19 }
20
21 pub fn icon(mut self, icon: IconName) -> Self {
22 self.icon = icon;
23 self
24 }
25}
26
27impl RenderOnce for Badge {
28 fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
29 h_flex()
30 .h_full()
31 .gap_1()
32 .pl_1()
33 .pr_2()
34 .border_1()
35 .border_color(cx.theme().colors().border)
36 .bg(cx.theme().colors().element_background)
37 .rounded_sm()
38 .overflow_hidden()
39 .child(
40 Icon::new(self.icon)
41 .size(IconSize::XSmall)
42 .color(Color::Muted),
43 )
44 .child(Divider::vertical().color(DividerColor::Border))
45 .child(
46 Label::new(self.label.clone())
47 .size(LabelSize::XSmall)
48 .buffer_font(cx)
49 .ml_1(),
50 )
51 }
52}
53
54impl Component for Badge {
55 fn scope() -> ComponentScope {
56 ComponentScope::DataDisplay
57 }
58
59 fn description() -> Option<&'static str> {
60 Some(
61 "A compact, labeled component with optional icon for displaying status, categories, or metadata.",
62 )
63 }
64
65 fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
66 Some(
67 single_example("Basic Badge", Badge::new("Default").into_any_element())
68 .into_any_element(),
69 )
70 }
71}