1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
use crate::{theme::use_theme, Theme};
use leptos::*;
use thaw_utils::{class_list, mount_style, OptionalProp};

#[derive(Default, Clone)]
pub enum BadgeVariant {
    Success,
    Warning,
    #[default]
    Error,
}

impl BadgeVariant {
    fn theme_color(&self, theme: &Theme) -> String {
        match self {
            BadgeVariant::Success => theme.common.color_success.clone(),
            BadgeVariant::Warning => theme.common.color_warning.clone(),
            BadgeVariant::Error => theme.common.color_error.clone(),
        }
    }
}

#[component]
pub fn Badge(
    #[prop(optional, into)] value: MaybeSignal<u32>,
    #[prop(default = MaybeSignal::Static(u32::MAX), into)] max: MaybeSignal<u32>,
    #[prop(optional, into)] variant: MaybeSignal<BadgeVariant>,
    #[prop(optional, into)] dot: MaybeSignal<bool>,
    #[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>,
    children: Children,
) -> impl IntoView {
    let theme = use_theme(Theme::light);
    mount_style("badge", include_str!("./badge.css"));
    let css_vars = create_memo(move |_| {
        let mut css_vars = String::new();
        css_vars.push_str("--thaw-font-color: #fff;");
        theme.with(|theme| {
            css_vars.push_str(&format!(
                "--thaw-background-color: {};",
                variant.get().theme_color(theme)
            ));
        });
        css_vars
    });
    let value = create_memo(move |_| {
        let value = value.get();
        let max_value = max.get();
        if value == 0 {
            String::new()
        } else if max_value < value {
            format!("{max_value}+")
        } else {
            value.to_string()
        }
    });

    view! {
        <div class="thaw-badge" style=move || css_vars.get()>
            <div class=class_list![
                "thaw-badge__sup", ("thaw-badge__sup--value", move || ! dot.get() && ! value.get()
                .is_empty()), ("thaw-badge__sup--dot", move || dot.get()), class.map(| c | move || c
                .get())
            ]>{move || value.get()}</div>
            {children()}
        </div>
    }
}