1use gpui::prelude::*;
4use gpui::{div, px, App, FontWeight, IntoElement, SharedString, Window};
5
6use crate::style::{surface, ColorValue, Variant};
7use crate::theme::{theme, Size};
8
9#[derive(IntoElement)]
11pub struct Badge {
12 label: SharedString,
13 variant: Variant,
14 color: ColorValue,
15 size: Size,
16}
17
18impl Badge {
19 pub fn new(label: impl Into<SharedString>) -> Self {
20 Badge {
21 label: label.into(),
22 variant: Variant::Light,
23 color: ColorValue::default(),
24 size: Size::Md,
25 }
26 }
27
28 pub fn variant(mut self, variant: Variant) -> Self {
29 self.variant = variant;
30 self
31 }
32
33 pub fn color(mut self, color: impl Into<ColorValue>) -> Self {
34 self.color = color.into();
35 self
36 }
37
38 pub fn size(mut self, size: Size) -> Self {
39 self.size = size;
40 self
41 }
42
43 fn metrics(&self) -> (f32, f32, f32) {
45 match self.size {
46 Size::Xs => (16.0, 6.0, 9.0),
47 Size::Sm => (18.0, 8.0, 10.0),
48 Size::Md => (20.0, 10.0, 11.0),
49 Size::Lg => (26.0, 12.0, 13.0),
50 Size::Xl => (32.0, 16.0, 16.0),
51 }
52 }
53}
54
55impl RenderOnce for Badge {
56 fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
57 let t = theme(cx);
58 let s = surface(t, self.color, self.variant);
59 let (height, pad_x, font) = self.metrics();
60 let mut el = div()
61 .flex()
62 .items_center()
63 .justify_center()
64 .h(px(height))
65 .px(px(pad_x))
66 .rounded(px(height))
67 .bg(s.bg)
68 .text_color(s.fg)
69 .text_size(px(font))
70 .font_weight(FontWeight::BOLD)
71 .child(self.label);
72 if let Some(border) = s.border {
73 el = el.border_1().border_color(border);
74 }
75 el
76 }
77}