use dioxus::prelude::*;
#[derive(Clone, PartialEq)]
pub enum BadgeType {
Primary,
Success,
Warning,
Info,
Danger,
}
impl BadgeType {
pub fn as_class(&self) -> &'static str {
match self {
BadgeType::Primary => "el-badge__content--primary",
BadgeType::Success => "el-badge__content--success",
BadgeType::Warning => "el-badge__content--warning",
BadgeType::Info => "el-badge__content--info",
BadgeType::Danger => "el-badge__content--danger",
}
}
}
#[derive(Props, Clone, PartialEq)]
pub struct BadgeProps {
#[props(default)]
pub children: Element,
#[props(default)]
pub value: Option<String>,
#[props(default = 99)]
pub max: u32,
#[props(default = false)]
pub is_dot: bool,
#[props(default = false)]
pub hidden: bool,
#[props(default = BadgeType::Danger)]
pub badge_type: BadgeType,
#[props(default = true)]
pub show_zero: bool,
#[props(default)]
pub color: Option<String>,
#[props(default)]
pub class: Option<String>,
#[props(default)]
pub style: Option<String>,
}
#[component]
pub fn Badge(props: BadgeProps) -> Element {
if props.hidden {
return rsx! { {props.children} };
}
let mut class_names = vec!["el-badge".to_string()];
if let Some(ref custom_class) = props.class {
class_names.push(custom_class.clone());
}
let class_string = class_names.join(" ");
let mut content_classes = vec!["el-badge__content".to_string()];
content_classes.push(props.badge_type.as_class().to_string());
if props.is_dot {
content_classes.push("is-dot".to_string());
}
let content_class_string = content_classes.join(" ");
let display_value = if props.is_dot {
String::new()
} else {
match &props.value {
Some(val) => {
if let Ok(num) = val.parse::<u32>() {
if num == 0 && !props.show_zero {
String::new()
} else if num > props.max {
format!("{}+", props.max)
} else {
val.clone()
}
} else {
val.clone()
}
}
None => String::new(),
}
};
let show_content = !display_value.is_empty() || props.is_dot;
let mut content_style = props.style.clone().unwrap_or_default();
if let Some(ref color) = props.color {
content_style = format!("background-color: {}; {}", color, content_style);
}
rsx! {
div {
class: "{class_string}",
{props.children}
if show_content {
sup {
class: "{content_class_string}",
style: "{content_style}",
"{display_value}"
}
}
}
}
}