refactor: button appearance

This commit is contained in:
luoxiao 2024-05-01 20:26:17 +08:00
parent 9706360bad
commit 9ab8367c21
18 changed files with 460 additions and 102 deletions

View file

@ -115,11 +115,13 @@ fn TheProvider(children: Children) -> impl IntoView {
let theme = create_rw_signal(theme); let theme = create_rw_signal(theme);
view! { view! {
<ThemeProvider theme> <ConfigProvider theme>
<GlobalStyle/> <ThemeProvider theme>
<MessageProvider> <GlobalStyle/>
<LoadingBarProvider>{children()}</LoadingBarProvider> <MessageProvider>
</MessageProvider> <LoadingBarProvider>{children()}</LoadingBarProvider>
</ThemeProvider> </MessageProvider>
</ThemeProvider>
</ConfigProvider>
} }
} }

View file

@ -152,7 +152,7 @@ pub fn SiteHeader() -> impl IntoView {
<Popover placement=PopoverPlacement::BottomEnd class="demo-header__menu-popover-mobile"> <Popover placement=PopoverPlacement::BottomEnd class="demo-header__menu-popover-mobile">
<PopoverTrigger slot class="demo-header__menu-mobile"> <PopoverTrigger slot class="demo-header__menu-mobile">
<Button <Button
variant=ButtonVariant::Text variant=ButtonAppearance::Subtle
icon=icondata::AiUnorderedListOutlined icon=icondata::AiUnorderedListOutlined
style="font-size: 22px; padding: 0px 6px;" style="font-size: 22px; padding: 0px 6px;"
/> />
@ -173,7 +173,7 @@ pub fn SiteHeader() -> impl IntoView {
</Popover> </Popover>
<Space class="demo-header__right-btn" align=SpaceAlign::Center> <Space class="demo-header__right-btn" align=SpaceAlign::Center>
<Button <Button
variant=ButtonVariant::Text variant=ButtonAppearance::Subtle
on_click=move |_| { on_click=move |_| {
let navigate = use_navigate(); let navigate = use_navigate();
navigate("/guide/installation", Default::default()); navigate("/guide/installation", Default::default());
@ -183,7 +183,7 @@ pub fn SiteHeader() -> impl IntoView {
"Guide" "Guide"
</Button> </Button>
<Button <Button
variant=ButtonVariant::Text variant=ButtonAppearance::Subtle
on_click=move |_| { on_click=move |_| {
let navigate = use_navigate(); let navigate = use_navigate();
navigate("/components/button", Default::default()); navigate("/components/button", Default::default());
@ -192,12 +192,12 @@ pub fn SiteHeader() -> impl IntoView {
"Components" "Components"
</Button> </Button>
<Button variant=ButtonVariant::Text on_click=Callback::new(move |_| change_theme.call(()))> <Button variant=ButtonAppearance::Subtle on_click=Callback::new(move |_| change_theme.call(()))>
{move || theme_name.get()} {move || theme_name.get()}
</Button> </Button>
<SwitchVersion /> <SwitchVersion />
<Button <Button
variant=ButtonVariant::Text variant=ButtonAppearance::Subtle
icon=icondata::AiGithubOutlined icon=icondata::AiGithubOutlined
round=true round=true
style="font-size: 22px; padding: 0px 6px;" style="font-size: 22px; padding: 0px 6px;"

View file

@ -23,7 +23,7 @@ pub fn Home() -> impl IntoView {
navigate("/components/button", Default::default()); navigate("/components/button", Default::default());
}>"Read the docs"</Button> }>"Read the docs"</Button>
<Button <Button
variant=ButtonVariant::Text variant=ButtonAppearance::Subtle
on_click=move |_| { on_click=move |_| {
_ = window().open_with_url("http://github.com/thaw-ui/thaw"); _ = window().open_with_url("http://github.com/thaw-ui/thaw");
} }

View file

@ -3,10 +3,10 @@
```rust demo ```rust demo
view! { view! {
<Space> <Space>
<Button variant=ButtonVariant::Primary>"Primary"</Button> <Button>"Secondary"</Button>
<Button variant=ButtonVariant::Outlined>"Outlined"</Button> <Button variant=ButtonAppearance::Primary>"Primary"</Button>
<Button variant=ButtonVariant::Text>"Text"</Button> <Button variant=ButtonAppearance::Subtle>"Subtle"</Button>
<Button variant=ButtonVariant::Link>"Link"</Button> <Button variant=ButtonAppearance::Transparent>"Transparent"</Button>
</Space> </Space>
} }
``` ```
@ -107,17 +107,17 @@ view! {
```rust demo ```rust demo
view! { view! {
<Space> <Space>
<Button variant=ButtonVariant::Primary disabled=true> <Button variant=ButtonAppearance::Primary disabled=true>
"Primary" "Primary"
</Button> </Button>
<Button variant=ButtonVariant::Outlined disabled=true> <Button disabled=true>
"Outlined" "Outlined"
</Button> </Button>
<Button variant=ButtonVariant::Text disabled=true> <Button variant=ButtonAppearance::Subtle disabled=true>
"Text" "Subtle"
</Button> </Button>
<Button variant=ButtonVariant::Link disabled=true> <Button variant=ButtonAppearance::Transparent disabled=true>
"Link" "Transparent"
</Button> </Button>
</Space> </Space>
} }
@ -152,14 +152,14 @@ view! {
view! { view! {
<Space> <Space>
<ButtonGroup> <ButtonGroup>
<Button variant=ButtonVariant::Outlined>"Outlined"</Button> <Button>"Outlined"</Button>
<Button variant=ButtonVariant::Outlined>"Outlined"</Button> <Button>"Outlined"</Button>
<Button variant=ButtonVariant::Outlined>"Outlined"</Button> <Button>"Outlined"</Button>
</ButtonGroup> </ButtonGroup>
<ButtonGroup vertical=true> <ButtonGroup vertical=true>
<Button variant=ButtonVariant::Outlined>"Outlined"</Button> <Button>"Outlined"</Button>
<Button variant=ButtonVariant::Outlined>"Outlined"</Button> <Button>"Outlined"</Button>
<Button variant=ButtonVariant::Outlined>"Outlined"</Button> <Button>"Outlined"</Button>
</ButtonGroup> </ButtonGroup>
</Space> </Space>
} }
@ -171,7 +171,7 @@ view! {
| --- | --- | --- | --- | | --- | --- | --- | --- |
| class | `OptionalProp<MaybeSignal<String>>` | `Default::default()` | Additional classes for the button element. | | class | `OptionalProp<MaybeSignal<String>>` | `Default::default()` | Additional classes for the button element. |
| style | `Option<MaybeSignal<String>>` | `Default::default()` | Button's style. | | style | `Option<MaybeSignal<String>>` | `Default::default()` | Button's style. |
| variant | `MaybeSignal<ButtonVariant>` | `ButtonVariant::Primary` | Button's variant. | | variant | `MaybeSignal<ButtonAppearance>` | `ButtonAppearance::Primary` | Button's variant. |
| color | `MaybeSignal<ButtonColor>` | `ButtonColor::Primary` | Button's color. | | color | `MaybeSignal<ButtonColor>` | `ButtonColor::Primary` | Button's color. |
| block | `MaybeSignal<bool>` | `false` | Whether the button is displayed as block. | | block | `MaybeSignal<bool>` | `false` | Whether the button is displayed as block. |
| round | `MaybeSignal<bool>` | `false` | Whether the button shows rounded corners. | | round | `MaybeSignal<bool>` | `false` | Whether the button shows rounded corners. |

View file

@ -1,24 +1,93 @@
.thaw-button { .thaw-button {
height: var(--thaw-height);
padding: var(--thaw-padding);
font-size: var(--thaw-font-size);
background-color: var(--thaw-background-color);
color: var(--thaw-font-color);
border: 1px solid var(--thaw-border-color);
border-radius: 5px;
position: relative;
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
user-select: none; min-width: 96px;
box-sizing: border-box;
padding: 5px var(--spacingHorizontalM);
font-family: var(--fontFamilyBase);
font-size: var(--fontSizeBase300);
font-weight: var(--fontWeightSemibold);
line-height: var(--lineHeightBase300);
background-color: var(--colorNeutralBackground1);
color: var(--colorNeutralForeground1);
border: var(--strokeWidthThin) solid var(--colorNeutralStroke1);
border-radius: var(--borderRadiusMedium);
transition-duration: var(--durationFaster);
transition-property: background, border, color;
transition-timing-function: var(--curveEasyEase);
} }
.thaw-button:hover:not(.thaw-button--disabled, .thaw-button--outlined) { .thaw-button:hover {
border-color: var(--thaw-border-color-hover); background-color: var(--colorNeutralBackground1Hover);
background-color: var(--thaw-background-color-hover); color: var(--colorNeutralForeground1Hover);
border-color: var(--colorNeutralStroke1Hover);
cursor: pointer; cursor: pointer;
}
transition: all 0.3s; .thaw-button:hover:active {
background-color: var(--colorNeutralBackground1Pressed);
color: var(--colorNeutralForeground1Pressed);
border-color: var(--colorNeutralStroke1Pressed);
}
.thaw-button--primary {
background-color: var(--colorBrandBackground);
color: var(--colorNeutralForegroundOnBrand);
border-color: transparent;
}
.thaw-button--primary:hover {
background-color: var(--colorBrandBackgroundHover);
color: var(--colorNeutralForegroundOnBrand);
border-color: transparent;
}
.thaw-button--primary:hover:active {
background-color: var(--colorBrandBackgroundPressed);
color: var(--colorNeutralForegroundOnBrand);
border-color: transparent;
}
.thaw-button--subtle {
background-color: var(--colorSubtleBackground);
color: var(--colorNeutralForeground2);
border-color: transparent;
}
.thaw-button--subtle:hover {
background-color: var(--colorSubtleBackgroundHover);
color: var(--colorNeutralForeground2Hover);
border-color: transparent;
}
.thaw-button--subtle:hover:active {
background-color: var(--colorSubtleBackgroundPressed);
color: var(--colorNeutralForeground2Pressed);
border-color: transparent;
}
.thaw-button--transparent {
background-color: var(--colorTransparentBackground);
color: var(--colorNeutralForeground2);
border-color: transparent;
}
.thaw-button--transparent:hover {
background-color: var(--colorTransparentBackgroundHover);
color: var(--colorNeutralForeground2BrandHover);
border-color: transparent;
}
.thaw-button--transparent:hover:active {
background-color: var(--colorTransparentBackgroundPressed);
color: var(--colorNeutralForeground2BrandPressed);
border-color: transparent;
} }
.thaw-button--block { .thaw-button--block {
@ -36,11 +105,11 @@
cursor: not-allowed; cursor: not-allowed;
} }
.thaw-button:active:not(.thaw-button--disabled) { /* .thaw-button:active:not(.thaw-button--disabled) {
transition: all 0.3s; transition: all 0.3s;
border-color: var(--thaw-border-color-hover); border-color: var(--thaw-border-color-hover);
background-color: var(--thaw-background-color-active); background-color: var(--thaw-background-color-active);
} } */
.thaw-button--outlined { .thaw-button--outlined {
background-color: transparent; background-color: transparent;

View file

@ -10,12 +10,23 @@ use thaw_components::{OptionComp, Wave, WaveRef};
use thaw_utils::{class_list, mount_style, ComponentRef, OptionalMaybeSignal, OptionalProp}; use thaw_utils::{class_list, mount_style, ComponentRef, OptionalMaybeSignal, OptionalProp};
#[derive(Default, PartialEq, Clone, Copy)] #[derive(Default, PartialEq, Clone, Copy)]
pub enum ButtonVariant { pub enum ButtonAppearance {
#[default] #[default]
Secondary,
Primary, Primary,
Outlined, Subtle,
Text, Transparent,
Link, }
impl ButtonAppearance {
fn as_str(&self) -> &str {
match self {
ButtonAppearance::Secondary => "secondary",
ButtonAppearance::Primary => "primary",
ButtonAppearance::Subtle => "subtle",
ButtonAppearance::Transparent => "transparent",
}
}
} }
#[derive(Default, Clone)] #[derive(Default, Clone)]
@ -97,7 +108,7 @@ impl ButtonSize {
pub fn Button( pub fn Button(
#[prop(optional, into)] style: Option<MaybeSignal<String>>, #[prop(optional, into)] style: Option<MaybeSignal<String>>,
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>,
#[prop(optional, into)] variant: MaybeSignal<ButtonVariant>, #[prop(optional, into)] variant: MaybeSignal<ButtonAppearance>,
#[prop(optional, into)] color: MaybeSignal<ButtonColor>, #[prop(optional, into)] color: MaybeSignal<ButtonColor>,
#[prop(optional, into)] size: MaybeSignal<ButtonSize>, #[prop(optional, into)] size: MaybeSignal<ButtonSize>,
#[prop(optional, into)] block: MaybeSignal<bool>, #[prop(optional, into)] block: MaybeSignal<bool>,
@ -132,7 +143,8 @@ pub fn Button(
)); ));
match variant.get() { match variant.get() {
ButtonVariant::Primary => { ButtonAppearance::Secondary => {}
ButtonAppearance::Primary => {
let bg_color_hover = color.get().theme_color_hover(theme); let bg_color_hover = color.get().theme_color_hover(theme);
let bg_color_active = color.get().theme_color_active(theme); let bg_color_active = color.get().theme_color_active(theme);
css_vars.push_str(&format!("--thaw-background-color: {bg_color};")); css_vars.push_str(&format!("--thaw-background-color: {bg_color};"));
@ -154,20 +166,7 @@ pub fn Button(
theme.button.color_border_disabled theme.button.color_border_disabled
)); ));
} }
ButtonVariant::Outlined => { ButtonAppearance::Subtle => {
css_vars.push_str(&format!("--thaw-font-color-hover: {bg_color};"));
css_vars.push_str(&format!(
"--thaw-border-color: {};",
theme.button.border_color_outlined
));
css_vars.push_str(&format!("--thaw-border-color-hover: {bg_color};"));
css_vars.push_str(&format!("--thaw-ripple-color: {bg_color};"));
css_vars.push_str(&format!(
"--thaw-border-color-disabled: {};",
theme.button.color_border_disabled
));
}
ButtonVariant::Text => {
css_vars.push_str(&format!("--thaw-font-color-hover: {bg_color};")); css_vars.push_str(&format!("--thaw-font-color-hover: {bg_color};"));
css_vars.push_str(&format!( css_vars.push_str(&format!(
"--thaw-background-color-hover: {};", "--thaw-background-color-hover: {};",
@ -179,7 +178,7 @@ pub fn Button(
)); ));
css_vars.push_str("--thaw-ripple-color: #0000;"); css_vars.push_str("--thaw-ripple-color: #0000;");
} }
ButtonVariant::Link => { ButtonAppearance::Transparent => {
css_vars.push_str(&format!("--thaw-font-color-hover: {bg_color};")); css_vars.push_str(&format!("--thaw-font-color-hover: {bg_color};"));
css_vars.push_str("--thaw-ripple-color: #0000;"); css_vars.push_str("--thaw-ripple-color: #0000;");
} }
@ -222,13 +221,11 @@ pub fn Button(
view! { view! {
<button <button
class=class_list![ class=class_list![
"thaw-button", ("thaw-button--outlined", move || variant.get() == "thaw-button", ("thaw-button--round", move || round.get()),
ButtonVariant::Outlined), ("thaw-button--text", move || variant.get() ==
ButtonVariant::Text), ("thaw-button--link", move || variant.get() ==
ButtonVariant::Link), ("thaw-button--round", move || round.get()),
("thaw-button--circle", move || circle.get()), ("thaw-button--disabled", move || ("thaw-button--circle", move || circle.get()), ("thaw-button--disabled", move ||
disabled.get()), ("thaw-button--block", move || block.get()), class.map(| c | move disabled.get()), ("thaw-button--block", move || block.get()),
|| c.get()) move || format!("thaw-button--{}", variant.get().as_str()),
class.map(| c | move || c.get())
] ]
style=move || { style=move || {

View file

@ -2,7 +2,7 @@ mod theme;
pub use theme::CalendarTheme; pub use theme::CalendarTheme;
use crate::{use_theme, Button, ButtonGroup, ButtonVariant, Theme}; use crate::{use_theme, Button, ButtonGroup, ButtonAppearance, Theme};
use chrono::{Datelike, Days, Local, Month, Months, NaiveDate}; use chrono::{Datelike, Days, Local, Month, Months, NaiveDate};
use leptos::*; use leptos::*;
use std::ops::Deref; use std::ops::Deref;
@ -135,15 +135,13 @@ pub fn Calendar(
<span> <span>
<ButtonGroup> <ButtonGroup>
<Button <Button
variant=ButtonVariant::Outlined
icon=icondata_ai::AiLeftOutlined icon=icondata_ai::AiLeftOutlined
on_click=previous_month on_click=previous_month
/> />
<Button variant=ButtonVariant::Outlined on_click=today> <Button on_click=today>
"Today" "Today"
</Button> </Button>
<Button <Button
variant=ButtonVariant::Outlined
icon=icondata_ai::AiRightOutlined icon=icondata_ai::AiRightOutlined
on_click=next_month on_click=next_month
/> />

View file

@ -0,0 +1,8 @@
.thaw-config-provider {
font-family: var(--fontFamilyBase);
font-size: var(--fontSizeBase300);
line-height: var(--lineHeightBase300);
font-weight: var(--fontWeightRegular);
background-color: var(--colorNeutralBackground1);
color: var(--colorNeutralForeground1);
}

View file

@ -0,0 +1,165 @@
use crate::Theme;
use leptos::*;
use thaw_utils::mount_style;
#[component]
pub fn ConfigProvider(
#[prop(optional, into)] theme: Option<RwSignal<Theme>>,
children: Children,
) -> impl IntoView {
mount_style("config-provider", include_str!("./config-provider.css"));
let theme = theme.unwrap_or_else(|| RwSignal::new(Theme::light()));
let css_vars = Memo::new(move |_| {
let mut css_vars = String::new();
theme.with(|theme| {
css_vars.push_str(&format!(
"--fontFamilyBase: {};",
theme.common.font_family_base
));
css_vars.push_str(&format!(
"--fontSizeBase300: {};",
theme.common.font_size_base_300
));
css_vars.push_str(&format!(
"--lineHeightBase300: {};",
theme.common.line_height_base300,
));
css_vars.push_str(&format!(
"--fontWeightRegular: {};",
theme.common.font_weight_regular
));
css_vars.push_str(&format!(
"--fontWeightSemibold: {};",
theme.common.font_weight_semibold
));
css_vars.push_str(&format!(
"--fontWeightBold: {};",
theme.common.font_weight_bold
));
css_vars.push_str(&format!(
"--strokeWidthThin: {};",
theme.common.stroke_width_thin,
));
css_vars.push_str(&format!(
"--borderRadiusMedium: {};",
theme.common.border_radius_medium
));
css_vars.push_str(&format!(
"--spacingHorizontalM: {};",
theme.common.spacing_horizontal_m
));
css_vars.push_str(&format!(
"--durationFaster: {};",
theme.common.duration_faster
));
css_vars.push_str(&format!(
"--curveEasyEase: {};",
theme.common.curve_easy_ease
));
css_vars.push_str(&format!(
"--colorNeutralBackground1: {};",
theme.common.color_neutral_background_1
));
css_vars.push_str(&format!(
"--colorNeutralBackground1Hover: {};",
theme.common.color_neutral_background_1_hover
));
css_vars.push_str(&format!(
"--colorNeutralBackground1Pressed: {};",
theme.common.color_neutral_background_1_pressed
));
css_vars.push_str(&format!(
"--colorNeutralForeground1: {};",
theme.common.color_neutral_foreground_1
));
css_vars.push_str(&format!(
"--colorNeutralForeground1Hover: {};",
theme.common.color_neutral_foreground_1_hover
));
css_vars.push_str(&format!(
"--colorNeutralForeground1Pressed: {};",
theme.common.color_neutral_foreground_1_pressed
));
css_vars.push_str(&format!(
"--colorNeutralForeground2: {};",
theme.common.color_neutral_foreground_2
));
css_vars.push_str(&format!(
"--colorNeutralForeground2Hover: {};",
theme.common.color_neutral_foreground_2_hover
));
css_vars.push_str(&format!(
"--colorNeutralForeground2Pressed: {};",
theme.common.color_neutral_foreground_2_pressed
));
css_vars.push_str(&format!(
"--colorNeutralForeground2BrandHover: {};",
theme.common.color_neutral_foreground_2_brand_hover
));
css_vars.push_str(&format!(
"--colorNeutralForeground2BrandPressed: {};",
theme.common.color_neutral_foreground_2_brand_pressed
));
css_vars.push_str(&format!(
"--colorNeutralForegroundOnBrand: {};",
theme.common.color_neutral_foreground_on_brand
));
css_vars.push_str(&format!(
"--colorNeutralStroke1: {};",
theme.common.color_neutral_stroke_1
));
css_vars.push_str(&format!(
"--colorNeutralStroke1Hover: {};",
theme.common.color_neutral_stroke_1_hover
));
css_vars.push_str(&format!(
"--colorNeutralStroke1Pressed: {};",
theme.common.color_neutral_stroke_1_pressed
));
css_vars.push_str(&format!(
"--colorBrandBackground: {};",
theme.common.color_brand_background
));
css_vars.push_str(&format!(
"--colorBrandBackgroundHover: {};",
theme.common.color_brand_background_hover
));
css_vars.push_str(&format!(
"--colorBrandBackgroundPressed: {};",
theme.common.color_brand_background_pressed
));
css_vars.push_str(&format!(
"--colorSubtleBackground: {};",
theme.common.color_subtle_background
));
css_vars.push_str(&format!(
"--colorSubtleBackgroundHover {};",
theme.common.color_subtle_background_hover
));
css_vars.push_str(&format!(
"--colorSubtleBackgroundPressed: {};",
theme.common.color_subtle_background_pressed
));
});
css_vars
});
let config_injection = ConfigInjection { theme };
view! {
<Provider value=config_injection>
<div style=move || css_vars.get() class="thaw-config-provider">
{children()}
</div>
</Provider>
}
}
#[derive(Clone)]
pub struct ConfigInjection {
theme: RwSignal<Theme>,
}

View file

@ -1,5 +1,5 @@
use super::PanelVariant; use super::PanelVariant;
use crate::{Button, ButtonSize, ButtonVariant, CalendarItemDate}; use crate::{Button, ButtonSize, ButtonAppearance, CalendarItemDate};
use chrono::{Datelike, Days, Month, Months, NaiveDate}; use chrono::{Datelike, Days, Month, Months, NaiveDate};
use leptos::*; use leptos::*;
use std::ops::Deref; use std::ops::Deref;
@ -88,27 +88,27 @@ pub fn DatePanel(
<div class="thaw-date-picker-date-panel__calendar"> <div class="thaw-date-picker-date-panel__calendar">
<div class="thaw-date-picker-date-panel__header"> <div class="thaw-date-picker-date-panel__header">
<Button <Button
variant=ButtonVariant::Link variant=ButtonAppearance::Transparent
size=ButtonSize::Small size=ButtonSize::Small
icon=icondata_ai::AiArrowLeftOutlined icon=icondata_ai::AiArrowLeftOutlined
on_click=previous_year on_click=previous_year
/> />
<Button <Button
variant=ButtonVariant::Link variant=ButtonAppearance::Transparent
size=ButtonSize::Small size=ButtonSize::Small
icon=icondata_ai::AiLeftOutlined icon=icondata_ai::AiLeftOutlined
on_click=previous_month on_click=previous_month
/> />
<div class="thaw-date-picker-date-panel__header-month-year"> <div class="thaw-date-picker-date-panel__header-month-year">
<Button <Button
variant=ButtonVariant::Text variant=ButtonAppearance::Subtle
size=ButtonSize::Small size=ButtonSize::Small
on_click=move |_| panel_variant.set(PanelVariant::Month) on_click=move |_| panel_variant.set(PanelVariant::Month)
> >
{move || Month::try_from(show_date.get().month() as u8).unwrap().name()} {move || Month::try_from(show_date.get().month() as u8).unwrap().name()}
</Button> </Button>
<Button <Button
variant=ButtonVariant::Text variant=ButtonAppearance::Subtle
size=ButtonSize::Small size=ButtonSize::Small
on_click=move |_| panel_variant.set(PanelVariant::Year) on_click=move |_| panel_variant.set(PanelVariant::Year)
> >
@ -116,13 +116,13 @@ pub fn DatePanel(
</Button> </Button>
</div> </div>
<Button <Button
variant=ButtonVariant::Link variant=ButtonAppearance::Transparent
size=ButtonSize::Small size=ButtonSize::Small
icon=icondata_ai::AiRightOutlined icon=icondata_ai::AiRightOutlined
on_click=next_month on_click=next_month
/> />
<Button <Button
variant=ButtonVariant::Link variant=ButtonAppearance::Transparent
size=ButtonSize::Small size=ButtonSize::Small
icon=icondata_ai::AiArrowRightOutlined icon=icondata_ai::AiArrowRightOutlined
on_click=next_year on_click=next_year
@ -157,7 +157,7 @@ pub fn DatePanel(
</div> </div>
</div> </div>
<div class="thaw-date-picker-date-panel__footer"> <div class="thaw-date-picker-date-panel__footer">
<Button variant=ButtonVariant::Outlined size=ButtonSize::Tiny on_click=now> <Button size=ButtonSize::Tiny on_click=now>
"Now" "Now"
</Button> </Button>
</div> </div>

View file

@ -1,5 +1,5 @@
use super::PanelVariant; use super::PanelVariant;
use crate::{Button, ButtonSize, ButtonVariant}; use crate::{Button, ButtonSize, ButtonAppearance};
use chrono::{Datelike, Month, Months, NaiveDate}; use chrono::{Datelike, Month, Months, NaiveDate};
use leptos::*; use leptos::*;
@ -23,14 +23,14 @@ pub fn MonthPanel(
<div class="thaw-date-picker-month-panel"> <div class="thaw-date-picker-month-panel">
<div class="thaw-date-picker-month-panel__header"> <div class="thaw-date-picker-month-panel__header">
<Button <Button
variant=ButtonVariant::Link variant=ButtonAppearance::Transparent
size=ButtonSize::Small size=ButtonSize::Small
icon=icondata_ai::AiArrowLeftOutlined icon=icondata_ai::AiArrowLeftOutlined
on_click=previous_year on_click=previous_year
/> />
<div class="thaw-date-picker-date-panel__header-year"> <div class="thaw-date-picker-date-panel__header-year">
<Button <Button
variant=ButtonVariant::Text variant=ButtonAppearance::Subtle
size=ButtonSize::Small size=ButtonSize::Small
on_click=move |_| panel_variant.set(PanelVariant::Year) on_click=move |_| panel_variant.set(PanelVariant::Year)
> >
@ -38,7 +38,7 @@ pub fn MonthPanel(
</Button> </Button>
</div> </div>
<Button <Button
variant=ButtonVariant::Link variant=ButtonAppearance::Transparent
size=ButtonSize::Small size=ButtonSize::Small
icon=icondata_ai::AiArrowRightOutlined icon=icondata_ai::AiArrowRightOutlined
on_click=next_year on_click=next_year

View file

@ -1,5 +1,5 @@
use super::PanelVariant; use super::PanelVariant;
use crate::{Button, ButtonSize, ButtonVariant}; use crate::{Button, ButtonSize, ButtonAppearance};
use chrono::{Datelike, NaiveDate}; use chrono::{Datelike, NaiveDate};
use leptos::*; use leptos::*;
@ -30,7 +30,7 @@ pub fn YearPanel(
<div> <div>
<div class="thaw-date-picker-year-panel__header"> <div class="thaw-date-picker-year-panel__header">
<Button <Button
variant=ButtonVariant::Link variant=ButtonAppearance::Transparent
size=ButtonSize::Small size=ButtonSize::Small
icon=icondata_ai::AiArrowLeftOutlined icon=icondata_ai::AiArrowLeftOutlined
on_click=previous_year_range on_click=previous_year_range
@ -43,7 +43,7 @@ pub fn YearPanel(
</div> </div>
<Button <Button
variant=ButtonVariant::Link variant=ButtonAppearance::Transparent
size=ButtonSize::Small size=ButtonSize::Small
icon=icondata_ai::AiArrowRightOutlined icon=icondata_ai::AiArrowRightOutlined
on_click=next_year_range on_click=next_year_range

View file

@ -11,9 +11,6 @@ pub fn GlobalStyle() -> impl IntoView {
.style() .style()
.set_property("background-color", &theme.common.background_color); .set_property("background-color", &theme.common.background_color);
_ = body.style().set_property("color", &theme.common.font_color); _ = body.style().set_property("color", &theme.common.font_color);
_ = body
.style()
.set_property("font-family", &theme.common.font_family);
_ = body _ = body
.style() .style()
.set_property("font-size", &theme.common.font_size); .set_property("font-size", &theme.common.font_size);

View file

@ -1,4 +1,4 @@
use crate::{Button, ButtonVariant, ComponentRef, Icon, Input, InputRef, InputSuffix}; use crate::{Button, ButtonAppearance, ComponentRef, Icon, Input, InputRef, InputSuffix};
use leptos::*; use leptos::*;
use num_traits::Bounded; use num_traits::Bounded;
use std::ops::{Add, Sub}; use std::ops::{Add, Sub};
@ -90,10 +90,10 @@ where
on_blur=set_within_range on_blur=set_within_range
> >
<InputSuffix slot> <InputSuffix slot>
<Button disabled=minus_disabled variant=ButtonVariant::Link on_click=sub> <Button disabled=minus_disabled variant=ButtonAppearance::Transparent on_click=sub>
<Icon icon=icondata_ai::AiMinusOutlined style="font-size: 18px"/> <Icon icon=icondata_ai::AiMinusOutlined style="font-size: 18px"/>
</Button> </Button>
<Button disabled=plus_disabled variant=ButtonVariant::Link on_click=add> <Button disabled=plus_disabled variant=ButtonAppearance::Transparent on_click=add>
<Icon icon=icondata_ai::AiPlusOutlined style="font-size: 18px"/> <Icon icon=icondata_ai::AiPlusOutlined style="font-size: 18px"/>
</Button> </Button>
</InputSuffix> </InputSuffix>

View file

@ -12,6 +12,7 @@ mod checkbox;
mod code; mod code;
mod collapse; mod collapse;
mod color_picker; mod color_picker;
mod config_provider;
mod date_picker; mod date_picker;
mod divider; mod divider;
mod drawer; mod drawer;
@ -59,6 +60,7 @@ pub use checkbox::*;
pub use code::*; pub use code::*;
pub use collapse::*; pub use collapse::*;
pub use color_picker::*; pub use color_picker::*;
pub use config_provider::*;
pub use date_picker::*; pub use date_picker::*;
pub use divider::*; pub use divider::*;
pub use drawer::*; pub use drawer::*;

0
thaw/src/theme/color.rs Normal file
View file

View file

@ -2,7 +2,7 @@ use super::ThemeMethod;
#[derive(Clone)] #[derive(Clone)]
pub struct CommonTheme { pub struct CommonTheme {
pub font_family: String, pub font_family_base: String,
pub font_color: String, pub font_color: String,
pub background_color: String, pub background_color: String,
pub border_color: String, pub border_color: String,
@ -21,6 +21,48 @@ pub struct CommonTheme {
pub color_error_hover: String, pub color_error_hover: String,
pub color_error_active: String, pub color_error_active: String,
pub color_neutral_background_1: String,
pub color_neutral_background_1_hover: String,
pub color_neutral_background_1_pressed: String,
pub color_neutral_foreground_1: String,
pub color_neutral_foreground_1_hover: String,
pub color_neutral_foreground_1_pressed: String,
pub color_neutral_foreground_2: String,
pub color_neutral_foreground_2_hover: String,
pub color_neutral_foreground_2_pressed: String,
pub color_neutral_foreground_2_brand_hover: String,
pub color_neutral_foreground_2_brand_pressed: String,
pub color_neutral_foreground_on_brand: String,
pub color_neutral_stroke_1: String,
pub color_neutral_stroke_1_hover: String,
pub color_neutral_stroke_1_pressed: String,
pub color_brand_background: String,
pub color_brand_background_hover: String,
pub color_brand_background_pressed: String,
pub color_subtle_background: String,
pub color_subtle_background_hover: String,
pub color_subtle_background_pressed: String,
pub color_transparent_background: String,
pub color_transparent_background_hover: String,
pub color_transparent_background_pressed: String,
pub font_size_base_300: String,
pub line_height_base300: String,
pub font_weight_regular: String,
pub font_weight_semibold: String,
pub font_weight_bold: String,
pub stroke_width_thin: String,
pub border_radius_medium: String,
pub spacing_horizontal_m: String,
pub duration_faster: String,
pub curve_easy_ease: String,
pub font_size: String, pub font_size: String,
pub font_size_tiny: String, pub font_size_tiny: String,
pub font_size_small: String, pub font_size_small: String,
@ -41,14 +83,13 @@ pub struct CommonTheme {
pub border_radius: String, pub border_radius: String,
pub border_radius_small: String, pub border_radius_small: String,
pub border_radius_medium: String,
pub border_radius_large: String, pub border_radius_large: String,
} }
impl CommonTheme { impl CommonTheme {
fn common() -> Self { fn common() -> Self {
Self { Self {
font_family: r#"Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", Segoe UI Symbol, "Noto Color Emoji""#.into(), font_family_base: "'Segoe UI', 'Segoe UI Web (West European)', -apple-system, BlinkMacSystemFont, Roboto, 'Helvetica Neue', sans-serif".into(),
font_color: "".into(), font_color: "".into(),
background_color: "".into(), background_color: "".into(),
border_color: "".into(), border_color: "".into(),
@ -66,6 +107,48 @@ impl CommonTheme {
color_error_hover: "".into(), color_error_hover: "".into(),
color_error_active: "".into(), color_error_active: "".into(),
color_neutral_background_1: "".into(),
color_neutral_background_1_hover: "".into(),
color_neutral_background_1_pressed: "".into(),
color_neutral_foreground_1: "".into(),
color_neutral_foreground_1_hover: "".into(),
color_neutral_foreground_1_pressed: "".into(),
color_neutral_foreground_2: "".into(),
color_neutral_foreground_2_hover: "".into(),
color_neutral_foreground_2_pressed: "".into(),
color_neutral_foreground_2_brand_hover: "".into(),
color_neutral_foreground_2_brand_pressed: "".into(),
color_neutral_foreground_on_brand: "#fff".into(),
color_neutral_stroke_1: "".into(),
color_neutral_stroke_1_hover: "".into(),
color_neutral_stroke_1_pressed: "".into(),
color_brand_background: "".into(),
color_brand_background_hover: "".into(),
color_brand_background_pressed: "".into(),
color_subtle_background: "transparent".into(),
color_subtle_background_hover: "".into(),
color_subtle_background_pressed: "".into(),
color_transparent_background: "transparent".into(),
color_transparent_background_hover: "transparent".into(),
color_transparent_background_pressed: "transparent".into(),
font_size_base_300: "14px".into(),
line_height_base300: "20px".into(),
font_weight_regular: "400".into(),
font_weight_semibold: "600".into(),
font_weight_bold: "700".into(),
stroke_width_thin: "1px".into(),
border_radius_medium: "4px".into(),
spacing_horizontal_m: "12px".into(),
duration_faster: "100ms".into(),
curve_easy_ease: "cubic-bezier(0.33,0,0.67,1)".into(),
font_size: "14px".into(), font_size: "14px".into(),
font_size_tiny: "12px".into(), font_size_tiny: "12px".into(),
font_size_small: "14px".into(), font_size_small: "14px".into(),
@ -86,7 +169,6 @@ impl CommonTheme {
border_radius: "3px".into(), border_radius: "3px".into(),
border_radius_small: "2px".into(), border_radius_small: "2px".into(),
border_radius_medium: "4px".into(),
border_radius_large: "8px".into(), border_radius_large: "8px".into(),
} }
} }
@ -111,6 +193,25 @@ impl ThemeMethod for CommonTheme {
color_error_hover: "#de576d".into(), color_error_hover: "#de576d".into(),
color_error_active: "#ab1f3f".into(), color_error_active: "#ab1f3f".into(),
border_color: "#e5e8eb".into(), border_color: "#e5e8eb".into(),
color_neutral_background_1: "#fff".into(),
color_neutral_background_1_hover: "#f5f5f5".into(),
color_neutral_background_1_pressed: "#e0e0e0".into(),
color_neutral_foreground_1: "#242424".into(),
color_neutral_foreground_1_hover: "#242424".into(),
color_neutral_foreground_1_pressed: "#242424".into(),
color_neutral_foreground_2: "#424242".into(),
color_neutral_foreground_2_hover: "#242424".into(),
color_neutral_foreground_2_pressed: "#242424".into(),
color_neutral_foreground_2_brand_hover: "#0f6cbd".into(),
color_neutral_foreground_2_brand_pressed: "#115ea3".into(),
color_neutral_stroke_1: "#d1d1d1".into(),
color_neutral_stroke_1_hover: "#c7c7c7".into(),
color_neutral_stroke_1_pressed: "#b3b3b3".into(),
color_brand_background: "#0f6cbd".into(),
color_brand_background_hover: "#115ea3".into(),
color_brand_background_pressed: "#0c3b5e".into(),
color_subtle_background_hover: "#f5f5f5".into(),
color_subtle_background_pressed: "#e0e0e0".into(),
..CommonTheme::common() ..CommonTheme::common()
} }
} }
@ -134,6 +235,25 @@ impl ThemeMethod for CommonTheme {
color_error_hover: "#de576d".into(), color_error_hover: "#de576d".into(),
color_error_active: "#e57272".into(), color_error_active: "#e57272".into(),
border_color: "#1f2537".into(), border_color: "#1f2537".into(),
color_neutral_background_1: "#292929".into(),
color_neutral_background_1_hover: "#3d3d3d".into(),
color_neutral_background_1_pressed: "#1f1f1f".into(),
color_neutral_foreground_1: "#fff".into(),
color_neutral_foreground_1_hover: "#fff".into(),
color_neutral_foreground_1_pressed: "#fff".into(),
color_neutral_foreground_2: "#d6d6d6".into(),
color_neutral_foreground_2_hover: "#fff".into(),
color_neutral_foreground_2_pressed: "#fff".into(),
color_neutral_foreground_2_brand_hover: "#479ef5".into(),
color_neutral_foreground_2_brand_pressed: "#2886de".into(),
color_neutral_stroke_1: "#666666".into(),
color_neutral_stroke_1_hover: "#757575".into(),
color_neutral_stroke_1_pressed: "#6b6b6b".into(),
color_brand_background: "#115ea3".into(),
color_brand_background_hover: "#0f6cbd".into(),
color_brand_background_pressed: "#0c3b5e".into(),
color_subtle_background_hover: "#383838".into(),
color_subtle_background_pressed: "#2e2e2e".into(),
..CommonTheme::common() ..CommonTheme::common()
} }
} }

View file

@ -3,7 +3,7 @@ mod theme;
pub use theme::TimePickerTheme; pub use theme::TimePickerTheme;
use crate::{ use crate::{
use_theme, Button, ButtonSize, ButtonVariant, Icon, Input, InputSuffix, Scrollbar, use_theme, Button, ButtonSize, ButtonAppearance, Icon, Input, InputSuffix, Scrollbar,
ScrollbarRef, SignalWatch, Theme, ScrollbarRef, SignalWatch, Theme,
}; };
use chrono::{Local, NaiveTime, Timelike}; use chrono::{Local, NaiveTime, Timelike};
@ -286,7 +286,7 @@ fn Panel(
</div> </div>
</div> </div>
<div class="thaw-time-picker-panel__footer"> <div class="thaw-time-picker-panel__footer">
<Button variant=ButtonVariant::Outlined size=ButtonSize::Tiny on_click=now> <Button size=ButtonSize::Tiny on_click=now>
"Now" "Now"
</Button> </Button>
<Button size=ButtonSize::Tiny on_click=ok> <Button size=ButtonSize::Tiny on_click=ok>