use crate::core::px;
use crate::view::prelude::*;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum BadgeVariant {
Default,
Accent,
Danger,
Outline,
}
pub struct Badge {
label: String,
variant: BadgeVariant,
style: Style,
}
impl Badge {
pub fn new(label: impl Into<String>) -> Self {
Self { label: label.into(), variant: BadgeVariant::Default, style: Style::default() }
}
pub fn variant(mut self, variant: BadgeVariant) -> Self {
self.variant = variant;
self
}
}
impl Styled for Badge {
fn style(&mut self) -> &mut Style {
&mut self.style
}
}
impl IntoElement for Badge {
fn into_element(self) -> AnyElement {
let (background, foreground) = match self.variant {
BadgeVariant::Default => (Some(Token::Active), Token::Text),
BadgeVariant::Accent => (Some(Token::Accent), Token::AccentText),
BadgeVariant::Danger => (Some(Token::Danger), Token::DangerText),
BadgeVariant::Outline => (None, Token::TextMuted),
};
div()
.flex_row()
.items_center()
.px_2()
.py(px(2.0))
.rounded_full()
.text_xs()
.text_color(foreground)
.when_some(background, |badge, color| badge.bg(color))
.when(self.variant == BadgeVariant::Outline, |badge| badge.border_1().border_color(Token::Border))
.refine_style(&self.style)
.child(self.label)
.into_element()
}
}
pub fn chip(label: impl Into<String>, selected: bool) -> Div {
div()
.flex_row()
.items_center()
.flex_shrink_0()
.gap_1()
.px_2()
.py(px(3.0))
.rounded_full()
.border_1()
.border_color(if selected { Token::BorderFocused } else { Token::Border })
.bg(if selected { Token::Selection } else { Token::Surface })
.text_xs()
.text_color(if selected { Token::Text } else { Token::TextMuted })
.cursor_pointer()
.hover(|style| style.bg(Token::Hover))
.child(label.into())
}