mirror of
https://github.com/adoyle0/thaw.git
synced 2025-01-23 06:19:22 -05:00
refactor: badge
This commit is contained in:
parent
bd9a419002
commit
b17f1400a5
6 changed files with 496 additions and 115 deletions
|
@ -143,6 +143,10 @@ pub(crate) fn gen_menu_data() -> Vec<MenuGroupOption> {
|
||||||
value: "/components/avatar".into(),
|
value: "/components/avatar".into(),
|
||||||
label: "Avatar".into(),
|
label: "Avatar".into(),
|
||||||
},
|
},
|
||||||
|
MenuItemOption {
|
||||||
|
value: "/components/badge".into(),
|
||||||
|
label: "Badge".into(),
|
||||||
|
},
|
||||||
MenuItemOption {
|
MenuItemOption {
|
||||||
value: "/components/breadcrumb".into(),
|
value: "/components/breadcrumb".into(),
|
||||||
label: "Breadcrumb".into(),
|
label: "Breadcrumb".into(),
|
||||||
|
@ -259,10 +263,6 @@ pub(crate) fn gen_menu_data() -> Vec<MenuGroupOption> {
|
||||||
value: "/components/alert".into(),
|
value: "/components/alert".into(),
|
||||||
label: "Alert".into(),
|
label: "Alert".into(),
|
||||||
},
|
},
|
||||||
MenuItemOption {
|
|
||||||
value: "/components/badge".into(),
|
|
||||||
label: "Badge".into(),
|
|
||||||
},
|
|
||||||
MenuItemOption {
|
MenuItemOption {
|
||||||
value: "/components/drawer".into(),
|
value: "/components/drawer".into(),
|
||||||
label: "Drawer".into(),
|
label: "Drawer".into(),
|
||||||
|
|
|
@ -1,33 +1,92 @@
|
||||||
# Badge
|
# Badge
|
||||||
|
|
||||||
```rust demo
|
```rust demo
|
||||||
let value = create_rw_signal(0);
|
view! {
|
||||||
|
<Badge />
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Appearance
|
||||||
|
|
||||||
|
```rust demo
|
||||||
view! {
|
view! {
|
||||||
<Space>
|
<Space>
|
||||||
<Badge value max=10>
|
<Badge appearance=BadgeAppearance::Filled>"999+"</Badge>
|
||||||
<Avatar/>
|
<Badge appearance=BadgeAppearance::Ghost>"999+"</Badge>
|
||||||
</Badge>
|
<Badge appearance=BadgeAppearance::Outline>"999+"</Badge>
|
||||||
<Badge variant=BadgeVariant::Success value max=10>
|
<Badge appearance=BadgeAppearance::Tint>"999+"</Badge>
|
||||||
<Avatar/>
|
</Space>
|
||||||
</Badge>
|
|
||||||
<Badge variant=BadgeVariant::Warning value max=10>
|
|
||||||
<Avatar/>
|
|
||||||
</Badge>
|
|
||||||
<Badge variant=BadgeVariant::Warning dot=true>
|
|
||||||
<Avatar/>
|
|
||||||
</Badge>
|
|
||||||
<Button on_click=move |_| value.update(|v| *v += 1)>"+1"</Button>
|
|
||||||
<Button on_click=move |_| {
|
|
||||||
value
|
|
||||||
.update(|v| {
|
|
||||||
if *v != 0 {
|
|
||||||
*v -= 1;
|
|
||||||
}
|
}
|
||||||
})
|
```
|
||||||
}>"-1"</Button>
|
|
||||||
"value:"
|
### Sizes
|
||||||
{move || value.get()}
|
|
||||||
|
```rust demo
|
||||||
|
view! {
|
||||||
|
<Space>
|
||||||
|
<Badge size=BadgeSize::Tiny/>
|
||||||
|
<Badge size=BadgeSize::ExtraSmall/>
|
||||||
|
<Badge size=BadgeSize::Small/>
|
||||||
|
<Badge size=BadgeSize::Medium/>
|
||||||
|
<Badge size=BadgeSize::Large/>
|
||||||
|
<Badge size=BadgeSize::ExtraLarge/>
|
||||||
|
</Space>
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Color
|
||||||
|
|
||||||
|
```rust demo
|
||||||
|
view! {
|
||||||
|
<Space vertical=true>
|
||||||
|
<Space>
|
||||||
|
<Badge appearance=BadgeAppearance::Filled color=BadgeColor::Brand>"999+"</Badge>
|
||||||
|
<Badge appearance=BadgeAppearance::Ghost color=BadgeColor::Brand>"999+"</Badge>
|
||||||
|
<Badge appearance=BadgeAppearance::Outline color=BadgeColor::Brand>"999+"</Badge>
|
||||||
|
<Badge appearance=BadgeAppearance::Tint color=BadgeColor::Brand>"999+"</Badge>
|
||||||
|
</Space>
|
||||||
|
<Space>
|
||||||
|
<Badge appearance=BadgeAppearance::Filled color=BadgeColor::Danger>"999+"</Badge>
|
||||||
|
<Badge appearance=BadgeAppearance::Ghost color=BadgeColor::Danger>"999+"</Badge>
|
||||||
|
<Badge appearance=BadgeAppearance::Outline color=BadgeColor::Danger>"999+"</Badge>
|
||||||
|
<Badge appearance=BadgeAppearance::Tint color=BadgeColor::Danger>"999+"</Badge>
|
||||||
|
</Space>
|
||||||
|
<Space>
|
||||||
|
<Badge appearance=BadgeAppearance::Filled color=BadgeColor::Important>"999+"</Badge>
|
||||||
|
<Badge appearance=BadgeAppearance::Ghost color=BadgeColor::Important>"999+"</Badge>
|
||||||
|
<Badge appearance=BadgeAppearance::Outline color=BadgeColor::Important>"999+"</Badge>
|
||||||
|
<Badge appearance=BadgeAppearance::Tint color=BadgeColor::Important>"999+"</Badge>
|
||||||
|
</Space>
|
||||||
|
<Space>
|
||||||
|
<Badge appearance=BadgeAppearance::Filled color=BadgeColor::Informative>"999+"</Badge>
|
||||||
|
<Badge appearance=BadgeAppearance::Ghost color=BadgeColor::Informative>"999+"</Badge>
|
||||||
|
<Badge appearance=BadgeAppearance::Outline color=BadgeColor::Informative>"999+"</Badge>
|
||||||
|
<Badge appearance=BadgeAppearance::Tint color=BadgeColor::Informative>"999+"</Badge>
|
||||||
|
</Space>
|
||||||
|
<Space>
|
||||||
|
<Badge appearance=BadgeAppearance::Filled color=BadgeColor::Severe>"999+"</Badge>
|
||||||
|
<Badge appearance=BadgeAppearance::Ghost color=BadgeColor::Severe>"999+"</Badge>
|
||||||
|
<Badge appearance=BadgeAppearance::Outline color=BadgeColor::Severe>"999+"</Badge>
|
||||||
|
<Badge appearance=BadgeAppearance::Tint color=BadgeColor::Severe>"999+"</Badge>
|
||||||
|
</Space>
|
||||||
|
<Space>
|
||||||
|
<Badge appearance=BadgeAppearance::Filled color=BadgeColor::Subtle>"999+"</Badge>
|
||||||
|
<Badge appearance=BadgeAppearance::Ghost color=BadgeColor::Subtle>"999+"</Badge>
|
||||||
|
<Badge appearance=BadgeAppearance::Outline color=BadgeColor::Subtle>"999+"</Badge>
|
||||||
|
<Badge appearance=BadgeAppearance::Tint color=BadgeColor::Subtle>"999+"</Badge>
|
||||||
|
</Space>
|
||||||
|
<Space>
|
||||||
|
<Badge appearance=BadgeAppearance::Filled color=BadgeColor::Success>"999+"</Badge>
|
||||||
|
<Badge appearance=BadgeAppearance::Ghost color=BadgeColor::Success>"999+"</Badge>
|
||||||
|
<Badge appearance=BadgeAppearance::Outline color=BadgeColor::Success>"999+"</Badge>
|
||||||
|
<Badge appearance=BadgeAppearance::Tint color=BadgeColor::Success>"999+"</Badge>
|
||||||
|
</Space>
|
||||||
|
<Space>
|
||||||
|
<Badge appearance=BadgeAppearance::Filled color=BadgeColor::Warning>"999+"</Badge>
|
||||||
|
<Badge appearance=BadgeAppearance::Ghost color=BadgeColor::Warning>"999+"</Badge>
|
||||||
|
<Badge appearance=BadgeAppearance::Outline color=BadgeColor::Warning>"999+"</Badge>
|
||||||
|
<Badge appearance=BadgeAppearance::Tint color=BadgeColor::Warning>"999+"</Badge>
|
||||||
|
</Space>
|
||||||
</Space>
|
</Space>
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,28 +1,220 @@
|
||||||
.thaw-badge {
|
.thaw-badge {
|
||||||
|
display: inline-flex;
|
||||||
|
box-sizing: border-box;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline-block;
|
font-family: var(--fontFamilyBase);
|
||||||
}
|
font-size: var(--fontSizeBase200);
|
||||||
.thaw-badge__sup {
|
font-weight: var(--fontWeightSemibold);
|
||||||
position: absolute;
|
line-height: var(--lineHeightBase200);
|
||||||
color: var(--thaw-font-color);
|
height: 20px;
|
||||||
background-color: var(--thaw-background-color);
|
width: 20px;
|
||||||
z-index: 10;
|
min-width: max-content;
|
||||||
}
|
padding: 0 calc(var(--spacingHorizontalXS) + var(--spacingHorizontalXXS));
|
||||||
.thaw-badge__sup--value {
|
border-radius: var(--borderRadiusCircular);
|
||||||
top: -9px;
|
border-color: var(--colorTransparentStroke);
|
||||||
right: -9px;
|
|
||||||
font-size: 12px;
|
|
||||||
height: 18px;
|
|
||||||
line-height: 18px;
|
|
||||||
border-radius: 9px;
|
|
||||||
padding: 0 6px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.thaw-badge__sup--dot {
|
.thaw-badge--filled {
|
||||||
top: -5px;
|
color: var(--colorNeutralForegroundOnBrand);
|
||||||
right: -5px;
|
background-color: var(--colorBrandBackground);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--filled.thaw-badge--danger {
|
||||||
|
background-color: var(--colorPaletteRedBackground3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--filled.thaw-badge--important {
|
||||||
|
color: var(--colorNeutralBackground1);
|
||||||
|
background-color: var(--colorNeutralForeground1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--filled.thaw-badge--informative {
|
||||||
|
color: var(--colorNeutralForeground3);
|
||||||
|
background-color: var(--colorNeutralBackground5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--filled.thaw-badge--severe {
|
||||||
|
background-color: var(--colorPaletteDarkOrangeBackground3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--filled.thaw-badge--subtle {
|
||||||
|
color: var(--colorNeutralForeground1);
|
||||||
|
background-color: var(--colorNeutralBackground1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--filled.thaw-badge--success {
|
||||||
|
background-color: var(--colorPaletteGreenBackground3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--filled.thaw-badge--warning {
|
||||||
|
color: var(--colorNeutralForeground1Static);
|
||||||
|
background-color: var(--colorPaletteYellowBackground3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--ghost {
|
||||||
|
color: var(--colorBrandForeground1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--ghost.thaw-badge--danger {
|
||||||
|
color: var(--colorPaletteRedForeground3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--ghost.thaw-badge--important {
|
||||||
|
color: var(--colorNeutralForeground1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--ghost.thaw-badge--informative {
|
||||||
|
color: var(--colorNeutralForeground3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--ghost.thaw-badge--severe {
|
||||||
|
color: var(--colorPaletteDarkOrangeForeground3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--ghost.thaw-badge--subtle {
|
||||||
|
color: var(--colorNeutralForegroundStaticInverted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--ghost.thaw-badge--success {
|
||||||
|
color: var(--colorPaletteGreenForeground3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--ghost.thaw-badge--warning {
|
||||||
|
color: var(--colorPaletteYellowForeground2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--outline {
|
||||||
|
color: var(--colorBrandForeground1);
|
||||||
|
border-color: currentcolor;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--outline.thaw-badge--danger {
|
||||||
|
color: var(--colorPaletteRedForeground3);
|
||||||
|
border-color: var(--colorPaletteRedBorder2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--outline.thaw-badge--important {
|
||||||
|
color: var(--colorNeutralForeground3);
|
||||||
|
border-color: var(--colorNeutralStrokeAccessible);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--outline.thaw-badge--informative {
|
||||||
|
color: var(--colorNeutralForeground3);
|
||||||
|
border-color: var(--colorNeutralStroke2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--outline.thaw-badge--severe {
|
||||||
|
color: var(--colorPaletteDarkOrangeForeground3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--outline.thaw-badge--subtle {
|
||||||
|
color: var(--colorNeutralForegroundStaticInverted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--outline.thaw-badge--success {
|
||||||
|
color: var(--colorPaletteGreenForeground3);
|
||||||
|
border-color: var(--colorPaletteGreenBorder2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--outline.thaw-badge--warning {
|
||||||
|
color: var(--colorPaletteYellowForeground2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--tint {
|
||||||
|
color: var(--colorBrandForeground2);
|
||||||
|
background-color: var(--colorBrandBackground2);
|
||||||
|
border-color: var(--colorBrandStroke2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--tint.thaw-badge--danger {
|
||||||
|
background-color: var(--colorPaletteRedBackground1);
|
||||||
|
color: var(--colorPaletteRedForeground1);
|
||||||
|
border-color: var(--colorPaletteRedBorder1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--tint.thaw-badge--important {
|
||||||
|
background-color: var(--colorNeutralForeground3);
|
||||||
|
color: var(--colorNeutralBackground1);
|
||||||
|
border-color: var(--colorTransparentStroke);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--tint.thaw-badge--informative {
|
||||||
|
background-color: var(--colorNeutralBackground4);
|
||||||
|
color: var(--colorNeutralForeground3);
|
||||||
|
border-color: var(--colorNeutralStroke2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--tint.thaw-badge--severe {
|
||||||
|
background-color: var(--colorPaletteDarkOrangeBackground1);
|
||||||
|
color: var(--colorPaletteDarkOrangeForeground1);
|
||||||
|
border-color: var(--colorPaletteDarkOrangeBorder1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--tint.thaw-badge--subtle {
|
||||||
|
background-color: var(--colorNeutralBackground1);
|
||||||
|
color: var(--colorNeutralForeground3);
|
||||||
|
border-color: var(--colorNeutralStroke2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--tint.thaw-badge--success {
|
||||||
|
background-color: var(--colorPaletteGreenBackground1);
|
||||||
|
color: var(--colorPaletteGreenForeground1);
|
||||||
|
border-color: var(--colorPaletteGreenBorder1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--tint.thaw-badge--warning {
|
||||||
|
background-color: var(--colorPaletteYellowBackground1);
|
||||||
|
color: var(--colorPaletteYellowForeground1);
|
||||||
|
border-color: var(--colorPaletteYellowBorder1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--tiny {
|
||||||
|
min-width: unset;
|
||||||
|
line-height: 4px;
|
||||||
|
font-size: 4px;
|
||||||
|
height: 6px;
|
||||||
|
width: 6px;
|
||||||
|
padding: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--extra-small {
|
||||||
|
min-width: unset;
|
||||||
|
line-height: 6px;
|
||||||
|
font-size: 6px;
|
||||||
height: 10px;
|
height: 10px;
|
||||||
width: 10px;
|
width: 10px;
|
||||||
border-radius: 50%;
|
padding: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--small {
|
||||||
|
line-height: var(--lineHeightBase100);
|
||||||
|
font-size: var(--fontSizeBase100);
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
padding: 0 calc(var(--spacingHorizontalXXS) + var(--spacingHorizontalXXS));
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--large {
|
||||||
|
height: 24px;
|
||||||
|
width: 24px;
|
||||||
|
padding: 0 calc(var(--spacingHorizontalXS) + var(--spacingHorizontalXXS));
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge--extra-large {
|
||||||
|
height: 32px;
|
||||||
|
width: 32px;
|
||||||
|
padding: 0
|
||||||
|
calc(var(--spacingHorizontalSNudge) + var(--spacingHorizontalXXS));
|
||||||
|
}
|
||||||
|
|
||||||
|
.thaw-badge::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
inset: 0px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: inherit;
|
||||||
|
border-width: var(--strokeWidthThin);
|
||||||
|
border-radius: inherit;
|
||||||
}
|
}
|
||||||
|
|
106
thaw/src/badge/badge.rs
Normal file
106
thaw/src/badge/badge.rs
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
use leptos::*;
|
||||||
|
use thaw_components::OptionComp;
|
||||||
|
use thaw_utils::{class_list, mount_style};
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn Badge(
|
||||||
|
#[prop(optional, into)] class: MaybeProp<String>,
|
||||||
|
/// A Badge can be filled, outline, ghost, inverted
|
||||||
|
#[prop(optional, into)]
|
||||||
|
appearance: MaybeSignal<BadgeAppearance>,
|
||||||
|
/// A Badge can be on of several preset sizes.
|
||||||
|
#[prop(optional, into)]
|
||||||
|
size: MaybeSignal<BadgeSize>,
|
||||||
|
/// A Badge can be one of preset colors.
|
||||||
|
#[prop(optional, into)]
|
||||||
|
color: MaybeSignal<BadgeColor>,
|
||||||
|
#[prop(optional)] children: Option<Children>,
|
||||||
|
) -> impl IntoView {
|
||||||
|
mount_style("badge", include_str!("./badge.css"));
|
||||||
|
|
||||||
|
view! {
|
||||||
|
<div class=class_list![
|
||||||
|
"thaw-badge",
|
||||||
|
move || format!("thaw-badge--{}", appearance.get().as_str()),
|
||||||
|
move || format!("thaw-badge--{}", size.get().as_str()),
|
||||||
|
move || format!("thaw-badge--{}", color.get().as_str()),
|
||||||
|
class
|
||||||
|
]>
|
||||||
|
<OptionComp value=children let:children>
|
||||||
|
{children()}
|
||||||
|
</OptionComp>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Clone)]
|
||||||
|
pub enum BadgeAppearance {
|
||||||
|
#[default]
|
||||||
|
Filled,
|
||||||
|
Ghost,
|
||||||
|
Outline,
|
||||||
|
Tint,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BadgeAppearance {
|
||||||
|
pub fn as_str(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
BadgeAppearance::Filled => "filled",
|
||||||
|
BadgeAppearance::Ghost => "ghost",
|
||||||
|
BadgeAppearance::Outline => "outline",
|
||||||
|
BadgeAppearance::Tint => "tint",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Clone)]
|
||||||
|
pub enum BadgeSize {
|
||||||
|
Tiny,
|
||||||
|
ExtraSmall,
|
||||||
|
Small,
|
||||||
|
#[default]
|
||||||
|
Medium,
|
||||||
|
Large,
|
||||||
|
ExtraLarge,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BadgeSize {
|
||||||
|
pub fn as_str(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
BadgeSize::Tiny => "tiny",
|
||||||
|
BadgeSize::ExtraSmall => "extra-small",
|
||||||
|
BadgeSize::Small => "small",
|
||||||
|
BadgeSize::Medium => "medium",
|
||||||
|
BadgeSize::Large => "large",
|
||||||
|
BadgeSize::ExtraLarge => "extra-large",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Clone)]
|
||||||
|
pub enum BadgeColor {
|
||||||
|
#[default]
|
||||||
|
Brand,
|
||||||
|
Danger,
|
||||||
|
Important,
|
||||||
|
Informative,
|
||||||
|
Severe,
|
||||||
|
Subtle,
|
||||||
|
Success,
|
||||||
|
Warning,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BadgeColor {
|
||||||
|
pub fn as_str(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
BadgeColor::Brand => "brand",
|
||||||
|
BadgeColor::Danger => "danger",
|
||||||
|
BadgeColor::Important => "important",
|
||||||
|
BadgeColor::Informative => "informative",
|
||||||
|
BadgeColor::Severe => "severe",
|
||||||
|
BadgeColor::Subtle => "subtle",
|
||||||
|
BadgeColor::Success => "success",
|
||||||
|
BadgeColor::Warning => "warning",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,67 +1,3 @@
|
||||||
use crate::{theme::use_theme, Theme};
|
mod badge;
|
||||||
use leptos::*;
|
|
||||||
use thaw_utils::{class_list, mount_style, OptionalProp};
|
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
pub use badge::*;
|
||||||
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>
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -12,6 +12,7 @@ pub struct ColorTheme {
|
||||||
pub color_neutral_background_4: String,
|
pub color_neutral_background_4: String,
|
||||||
pub color_neutral_background_4_hover: String,
|
pub color_neutral_background_4_hover: String,
|
||||||
pub color_neutral_background_4_pressed: String,
|
pub color_neutral_background_4_pressed: String,
|
||||||
|
pub color_neutral_background_5: String,
|
||||||
pub color_neutral_background_6: String,
|
pub color_neutral_background_6: String,
|
||||||
|
|
||||||
pub color_neutral_foreground_disabled: String,
|
pub color_neutral_foreground_disabled: String,
|
||||||
|
@ -50,9 +51,37 @@ pub struct ColorTheme {
|
||||||
pub color_brand_background: String,
|
pub color_brand_background: String,
|
||||||
pub color_brand_background_hover: String,
|
pub color_brand_background_hover: String,
|
||||||
pub color_brand_background_pressed: String,
|
pub color_brand_background_pressed: String,
|
||||||
|
pub color_brand_background_2: String,
|
||||||
|
pub color_brand_foreground_1: String,
|
||||||
|
pub color_brand_foreground_2: String,
|
||||||
pub color_brand_stroke_1: String,
|
pub color_brand_stroke_1: String,
|
||||||
|
pub color_brand_stroke_2: String,
|
||||||
pub color_brand_stroke_2_contrast: String,
|
pub color_brand_stroke_2_contrast: String,
|
||||||
|
|
||||||
|
pub color_palette_red_background_1: String,
|
||||||
|
pub color_palette_red_background_3: String,
|
||||||
|
pub color_palette_red_foreground_1: String,
|
||||||
|
pub color_palette_red_foreground_3: String,
|
||||||
|
pub color_palette_red_border_1: String,
|
||||||
|
pub color_palette_red_border_2: String,
|
||||||
|
pub color_palette_green_background_1: String,
|
||||||
|
pub color_palette_green_background_3: String,
|
||||||
|
pub color_palette_green_foreground_1: String,
|
||||||
|
pub color_palette_green_foreground_3: String,
|
||||||
|
pub color_palette_green_border_1: String,
|
||||||
|
pub color_palette_green_border_2: String,
|
||||||
|
pub color_palette_yellow_background_1: String,
|
||||||
|
pub color_palette_yellow_background_3: String,
|
||||||
|
pub color_palette_yellow_foreground_1: String,
|
||||||
|
pub color_palette_yellow_foreground_2: String,
|
||||||
|
pub color_palette_yellow_border_1: String,
|
||||||
|
|
||||||
|
pub color_palette_dark_orange_background_1: String,
|
||||||
|
pub color_palette_dark_orange_background_3: String,
|
||||||
|
pub color_palette_dark_orange_foreground_1: String,
|
||||||
|
pub color_palette_dark_orange_foreground_3: String,
|
||||||
|
pub color_palette_dark_orange_border_1: String,
|
||||||
|
|
||||||
pub color_subtle_background: String,
|
pub color_subtle_background: String,
|
||||||
pub color_subtle_background_hover: String,
|
pub color_subtle_background_hover: String,
|
||||||
pub color_subtle_background_pressed: String,
|
pub color_subtle_background_pressed: String,
|
||||||
|
@ -77,6 +106,7 @@ impl ColorTheme {
|
||||||
color_neutral_background_4: "#f0f0f0".into(),
|
color_neutral_background_4: "#f0f0f0".into(),
|
||||||
color_neutral_background_4_hover: "#fafafa".into(),
|
color_neutral_background_4_hover: "#fafafa".into(),
|
||||||
color_neutral_background_4_pressed: "#f5f5f5".into(),
|
color_neutral_background_4_pressed: "#f5f5f5".into(),
|
||||||
|
color_neutral_background_5: "#ebebeb".into(),
|
||||||
color_neutral_background_6: "#e6e6e6".into(),
|
color_neutral_background_6: "#e6e6e6".into(),
|
||||||
|
|
||||||
color_neutral_foreground_disabled: "#bdbdbd".into(),
|
color_neutral_foreground_disabled: "#bdbdbd".into(),
|
||||||
|
@ -116,8 +146,37 @@ impl ColorTheme {
|
||||||
color_brand_background: "#0f6cbd".into(),
|
color_brand_background: "#0f6cbd".into(),
|
||||||
color_brand_background_hover: "#115ea3".into(),
|
color_brand_background_hover: "#115ea3".into(),
|
||||||
color_brand_background_pressed: "#0c3b5e".into(),
|
color_brand_background_pressed: "#0c3b5e".into(),
|
||||||
|
color_brand_background_2: "#ebf3fc".into(),
|
||||||
|
color_brand_foreground_1: "#0f6cbd".into(),
|
||||||
|
color_brand_foreground_2: "#115ea3".into(),
|
||||||
color_brand_stroke_1: "#0f6cbd".into(),
|
color_brand_stroke_1: "#0f6cbd".into(),
|
||||||
|
color_brand_stroke_2: "#b4d6fa".into(),
|
||||||
color_brand_stroke_2_contrast: "#b4d6fa".into(),
|
color_brand_stroke_2_contrast: "#b4d6fa".into(),
|
||||||
|
|
||||||
|
color_palette_red_background_1: "#fdf6f6".into(),
|
||||||
|
color_palette_red_background_3: "#d13438".into(),
|
||||||
|
color_palette_red_foreground_1: "#bc2f32".into(),
|
||||||
|
color_palette_red_foreground_3: "#d13438".into(),
|
||||||
|
color_palette_red_border_1: "#f1bbbc".into(),
|
||||||
|
color_palette_red_border_2: "#d13438".into(),
|
||||||
|
color_palette_green_background_1: "#f1faf1".into(),
|
||||||
|
color_palette_green_background_3: "#107c10".into(),
|
||||||
|
color_palette_green_foreground_1: "#0e700e".into(),
|
||||||
|
color_palette_green_foreground_3: "#107c10".into(),
|
||||||
|
color_palette_green_border_1: "#9fd89f".into(),
|
||||||
|
color_palette_green_border_2: "#107c10".into(),
|
||||||
|
color_palette_yellow_background_1: "#fffef5".into(),
|
||||||
|
color_palette_yellow_background_3: "#fde300".into(),
|
||||||
|
color_palette_yellow_foreground_1: "#817400".into(),
|
||||||
|
color_palette_yellow_foreground_2: "#817400".into(),
|
||||||
|
color_palette_yellow_border_1: "#fef7b2".into(),
|
||||||
|
|
||||||
|
color_palette_dark_orange_background_1: "#fdf6f3".into(),
|
||||||
|
color_palette_dark_orange_background_3: "#da3b01".into(),
|
||||||
|
color_palette_dark_orange_foreground_1: "#c43501".into(),
|
||||||
|
color_palette_dark_orange_foreground_3: "#da3b01".into(),
|
||||||
|
color_palette_dark_orange_border_1: "#f4bfab".into(),
|
||||||
|
|
||||||
color_subtle_background: "transparent".into(),
|
color_subtle_background: "transparent".into(),
|
||||||
color_subtle_background_hover: "#f5f5f5".into(),
|
color_subtle_background_hover: "#f5f5f5".into(),
|
||||||
color_subtle_background_pressed: "#e0e0e0".into(),
|
color_subtle_background_pressed: "#e0e0e0".into(),
|
||||||
|
@ -142,6 +201,7 @@ impl ColorTheme {
|
||||||
color_neutral_background_4: "#0a0a0a".into(),
|
color_neutral_background_4: "#0a0a0a".into(),
|
||||||
color_neutral_background_4_hover: "#1f1f1f".into(),
|
color_neutral_background_4_hover: "#1f1f1f".into(),
|
||||||
color_neutral_background_4_pressed: "#000000".into(),
|
color_neutral_background_4_pressed: "#000000".into(),
|
||||||
|
color_neutral_background_5: "#000000".into(),
|
||||||
color_neutral_background_6: "#333333".into(),
|
color_neutral_background_6: "#333333".into(),
|
||||||
|
|
||||||
color_neutral_foreground_disabled: "#5c5c5c".into(),
|
color_neutral_foreground_disabled: "#5c5c5c".into(),
|
||||||
|
@ -181,9 +241,37 @@ impl ColorTheme {
|
||||||
color_brand_background: "#115ea3".into(),
|
color_brand_background: "#115ea3".into(),
|
||||||
color_brand_background_hover: "#0f6cbd".into(),
|
color_brand_background_hover: "#0f6cbd".into(),
|
||||||
color_brand_background_pressed: "#0c3b5e".into(),
|
color_brand_background_pressed: "#0c3b5e".into(),
|
||||||
|
color_brand_background_2: "#082338".into(),
|
||||||
|
color_brand_foreground_1: "#479ef5".into(),
|
||||||
|
color_brand_foreground_2: "#62abf5".into(),
|
||||||
color_brand_stroke_1: "#479ef5".into(),
|
color_brand_stroke_1: "#479ef5".into(),
|
||||||
|
color_brand_stroke_2: "#0e4775".into(),
|
||||||
color_brand_stroke_2_contrast: "#0e4775".into(),
|
color_brand_stroke_2_contrast: "#0e4775".into(),
|
||||||
|
|
||||||
|
color_palette_red_background_1: "#3f1011".into(),
|
||||||
|
color_palette_red_background_3: "#d13438".into(),
|
||||||
|
color_palette_red_foreground_1: "#e37d80".into(),
|
||||||
|
color_palette_red_foreground_3: "#e37d80".into(),
|
||||||
|
color_palette_red_border_1: "#d13438".into(),
|
||||||
|
color_palette_red_border_2: "#e37d80".into(),
|
||||||
|
color_palette_green_background_1: "#052505".into(),
|
||||||
|
color_palette_green_background_3: "#107c10".into(),
|
||||||
|
color_palette_green_foreground_1: "#54b054".into(),
|
||||||
|
color_palette_green_foreground_3: "#9fd89f".into(),
|
||||||
|
color_palette_green_border_1: "#107c10".into(),
|
||||||
|
color_palette_green_border_2: "#9fd89f".into(),
|
||||||
|
color_palette_yellow_background_1: "#4c4400".into(),
|
||||||
|
color_palette_yellow_background_3: "#fde300".into(),
|
||||||
|
color_palette_yellow_foreground_1: "#feee66".into(),
|
||||||
|
color_palette_yellow_foreground_2: "#fef7b2".into(),
|
||||||
|
color_palette_yellow_border_1: "#fde300".into(),
|
||||||
|
|
||||||
|
color_palette_dark_orange_background_1: "#411200".into(),
|
||||||
|
color_palette_dark_orange_background_3: "#da3b01".into(),
|
||||||
|
color_palette_dark_orange_foreground_1: "#e9835e".into(),
|
||||||
|
color_palette_dark_orange_foreground_3: "#e9835e".into(),
|
||||||
|
color_palette_dark_orange_border_1: "#da3b01".into(),
|
||||||
|
|
||||||
color_subtle_background: "transparent".into(),
|
color_subtle_background: "transparent".into(),
|
||||||
color_subtle_background_hover: "#383838".into(),
|
color_subtle_background_hover: "#383838".into(),
|
||||||
color_subtle_background_pressed: "#2e2e2e".into(),
|
color_subtle_background_pressed: "#2e2e2e".into(),
|
||||||
|
|
Loading…
Add table
Reference in a new issue