use std::ops::{Deref, DerefMut};
use blinc_layout::div::{Div, ElementBuilder, ElementTypeId};
use blinc_layout::prelude::*;
use blinc_theme::ThemeState;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum BadgeVariant {
#[default]
Default,
Secondary,
Success,
Warning,
Destructive,
Outline,
}
pub struct Badge {
inner: Div,
label: String,
variant: BadgeVariant,
}
impl Badge {
pub fn new(label: impl Into<String>) -> Self {
Self::with_variant(label, BadgeVariant::default())
}
fn with_variant(label: impl Into<String>, variant: BadgeVariant) -> Self {
let label = label.into();
let variant_class = match variant {
BadgeVariant::Default => "cn-badge--default",
BadgeVariant::Secondary => "cn-badge--secondary",
BadgeVariant::Success => "cn-badge--success",
BadgeVariant::Warning => "cn-badge--warning",
BadgeVariant::Destructive => "cn-badge--destructive",
BadgeVariant::Outline => "cn-badge--outline",
};
let badge = div()
.class("cn-badge")
.class(variant_class)
.items_center()
.justify_center()
.child(text(&label).medium());
Self {
inner: badge,
label,
variant,
}
}
pub fn variant(self, variant: BadgeVariant) -> Self {
Self::with_variant(self.label, variant)
}
pub fn class(mut self, name: impl Into<String>) -> Self {
self.inner = self.inner.class(name);
self
}
pub fn id(mut self, id: &str) -> Self {
self.inner = self.inner.id(id);
self
}
}
impl Deref for Badge {
type Target = Div;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl DerefMut for Badge {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
impl ElementBuilder for Badge {
fn build(&self, tree: &mut blinc_layout::tree::LayoutTree) -> blinc_layout::tree::LayoutNodeId {
self.inner.build(tree)
}
fn render_props(&self) -> blinc_layout::element::RenderProps {
self.inner.render_props()
}
fn children_builders(&self) -> &[Box<dyn ElementBuilder>] {
self.inner.children_builders()
}
fn event_handlers(&self) -> Option<&blinc_layout::event_handler::EventHandlers> {
ElementBuilder::event_handlers(&self.inner)
}
fn layout_style(&self) -> Option<&taffy::Style> {
ElementBuilder::layout_style(&self.inner)
}
fn element_type_id(&self) -> ElementTypeId {
ElementBuilder::element_type_id(&self.inner)
}
fn element_classes(&self) -> &[String] {
self.inner.element_classes()
}
}
pub fn badge(label: impl Into<String>) -> Badge {
Badge::new(label)
}
#[cfg(test)]
mod tests {
use super::*;
fn init_theme() {
let _ = ThemeState::try_get().unwrap_or_else(|| {
ThemeState::init_default();
ThemeState::get()
});
}
#[test]
fn test_badge_default() {
init_theme();
let _ = badge("Test");
}
#[test]
fn test_badge_variants() {
init_theme();
let _ = badge("Default").variant(BadgeVariant::Default);
let _ = badge("Secondary").variant(BadgeVariant::Secondary);
let _ = badge("Success").variant(BadgeVariant::Success);
let _ = badge("Warning").variant(BadgeVariant::Warning);
let _ = badge("Error").variant(BadgeVariant::Destructive);
let _ = badge("Outline").variant(BadgeVariant::Outline);
}
}