Skip to main content

shadow_design/
badge.rs

1use dioxus::prelude::*;
2
3#[derive(Clone, Copy, PartialEq, Debug, Default)]
4pub enum BadgeVariant {
5    #[default]
6    Default,
7    Primary,
8    Success,
9    Warning,
10    Danger,
11    Outline,
12}
13
14impl BadgeVariant {
15    pub fn scss_class(&self) -> &'static str {
16        match self {
17            BadgeVariant::Default => "sd-badge--default",
18            BadgeVariant::Primary => "sd-badge--primary",
19            BadgeVariant::Success => "sd-badge--success",
20            BadgeVariant::Warning => "sd-badge--warning",
21            BadgeVariant::Danger => "sd-badge--danger",
22            BadgeVariant::Outline => "sd-badge--outline",
23        }
24    }
25
26    pub fn dot_color_class(&self) -> &'static str {
27        match self {
28            BadgeVariant::Default => "default",
29            BadgeVariant::Primary => "primary",
30            BadgeVariant::Success => "success",
31            BadgeVariant::Warning => "warning",
32            BadgeVariant::Danger => "danger",
33            BadgeVariant::Outline => "outline",
34        }
35    }
36}
37
38#[component]
39pub fn Badge(
40    label: String,
41    #[props(default)] variant: BadgeVariant,
42    #[props(default)] pill: bool,
43    #[props(default)] dot: bool,
44    #[props(default)] glow: Option<bool>,
45    #[props(default)] class: String,
46) -> Element {
47    let variant_class = variant.scss_class();
48    let pill_class = if pill { "sd-badge--pill" } else { "" };
49
50    #[cfg(feature = "theme")]
51    let theme = crate::theme::use_theme();
52    #[cfg(feature = "theme")]
53    let radius = if pill {
54        ""
55    } else {
56        theme().radius_scale.sm()
57    };
58    #[cfg(feature = "theme")]
59    let glow_class = match glow {
60        Some(true) => "sd-badge--glow",
61        Some(false) => "",
62        None => {
63            if variant == BadgeVariant::Primary && theme().glow_mode != crate::theme::GlowMode::Off
64            {
65                "sd-badge--glow"
66            } else {
67                ""
68            }
69        }
70    };
71
72    #[cfg(not(feature = "theme"))]
73    let radius = "";
74    #[cfg(not(feature = "theme"))]
75    let glow_class = if glow == Some(true) || (glow.is_none() && variant == BadgeVariant::Primary) {
76        "sd-badge--glow"
77    } else {
78        ""
79    };
80
81    let dot_kind = variant.dot_color_class();
82
83    rsx! {
84        span {
85            class: "sd-badge {variant_class} {pill_class} {radius} {glow_class} {class}",
86            if dot {
87                span { class: "sd-badge__dot-container",
88                    span { class: "sd-badge__dot-ping sd-badge__dot-ping--{dot_kind}" }
89                    span { class: "sd-badge__dot sd-badge__dot--{dot_kind}" }
90                }
91            }
92            "{label}"
93        }
94    }
95}