diff --git a/demo/src/app.rs b/demo/src/app.rs index f7dfc26..788af32 100644 --- a/demo/src/app.rs +++ b/demo/src/app.rs @@ -28,6 +28,7 @@ pub fn App() -> impl IntoView { + diff --git a/demo/src/pages/badge/mod.rs b/demo/src/pages/badge/mod.rs new file mode 100644 index 0000000..f4ba53c --- /dev/null +++ b/demo/src/pages/badge/mod.rs @@ -0,0 +1,73 @@ +use crate::components::{Demo, DemoCode}; +use leptos::*; +use melt_ui::*; +use prisms::highlight_str; + +#[component] +pub fn BadgePage() -> impl IntoView { + let value = create_rw_signal(0); + view! { +
+

"Badge"

+ + + + + + + + + + + + + + + + + "value:" + {move || value.get()} + + + + + + + + + + + + + + + + + "value:" + {move || value.get()} + + } + "#, + "rust" + ) + > + + "" + + +
+ } +} diff --git a/demo/src/pages/components.rs b/demo/src/pages/components.rs index d4f3346..ee2c327 100644 --- a/demo/src/pages/components.rs +++ b/demo/src/pages/components.rs @@ -152,6 +152,10 @@ fn gen_menu_data() -> Vec { value: "alert".into(), label: "Alert".into(), }, + MenuItemOption { + value: "badge".into(), + label: "Badge".into(), + }, MenuItemOption { value: "modal".into(), label: "Modal".into(), diff --git a/demo/src/pages/mod.rs b/demo/src/pages/mod.rs index 55dbe64..b807a52 100644 --- a/demo/src/pages/mod.rs +++ b/demo/src/pages/mod.rs @@ -1,6 +1,7 @@ mod alert; mod auto_complete; mod avatar; +mod badge; mod button; mod checkbox; mod color_picker; @@ -24,6 +25,7 @@ mod toast; pub use alert::*; pub use auto_complete::*; pub use avatar::*; +pub use badge::*; pub use button::*; pub use checkbox::*; pub use color_picker::*; diff --git a/src/badge/badge.css b/src/badge/badge.css new file mode 100644 index 0000000..cd8bca5 --- /dev/null +++ b/src/badge/badge.css @@ -0,0 +1,27 @@ +.melt-badge { + position: relative; + display: inline-block; +} +.melt-badge__sup { + position: absolute; + color: var(--font-color); + background-color: var(--background-color); +} +.melt-badge__sup--value { + top: -9px; + right: -9px; + font-size: 12px; + height: 18px; + line-height: 18px; + border-radius: 9px; + padding: 0 6px; + text-align: center; +} + +.melt-badge__sup--dot { + top: -5px; + right: -5px; + height: 10px; + width: 10px; + border-radius: 50%; +} diff --git a/src/badge/mod.rs b/src/badge/mod.rs new file mode 100644 index 0000000..f33ad8a --- /dev/null +++ b/src/badge/mod.rs @@ -0,0 +1,66 @@ +use crate::{mount_style, theme::use_theme, Theme}; +use leptos::*; + +#[derive(Default, Clone)] +pub enum BadgeColor { + Success, + Warning, + #[default] + Error, +} + +impl BadgeColor { + pub fn theme_color(&self, theme: &Theme) -> String { + match self { + BadgeColor::Success => theme.common.color_success.clone(), + BadgeColor::Warning => theme.common.color_warning.clone(), + BadgeColor::Error => theme.common.color_error.clone(), + } + } +} + +#[component] +pub fn Badge( + #[prop(optional, into)] value: MaybeSignal, + #[prop(default = MaybeSignal::Static(u32::MAX), into)] max_value: MaybeSignal, + #[prop(optional, into)] color: MaybeSignal, + #[prop(optional, into)] dot: MaybeSignal, + 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(&format!("--font-color: #fff;")); + theme.with(|theme| { + css_vars.push_str(&format!( + "--background-color: {};", + color.get().theme_color(theme) + )); + }); + css_vars + }); + let value = create_memo(move |_| { + let value = value.get(); + let max_value = max_value.get(); + if value == 0 { + String::new() + } else if max_value < value { + format!("{max_value}+") + } else { + value.to_string() + } + }); + view! { +
+
+ {move || value.get()} +
+ {children()} +
+ } +} diff --git a/src/lib.rs b/src/lib.rs index 9ad7bfb..713a235 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,7 @@ mod alert; mod auto_complete; mod avatar; +mod badge; mod button; mod card; mod checkbox; @@ -29,6 +30,7 @@ mod wave; pub use alert::*; pub use auto_complete::*; pub use avatar::*; +pub use badge::*; pub use button::*; pub use card::*; pub use checkbox::*;