feat: button shape

This commit is contained in:
luoxiao 2024-05-06 17:28:47 +08:00
parent b6b7df0a05
commit 4017606b18
14 changed files with 139 additions and 110 deletions

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=ButtonAppearance::Subtle appearance=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=ButtonAppearance::Subtle appearance=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=ButtonAppearance::Subtle appearance=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=ButtonAppearance::Subtle on_click=Callback::new(move |_| change_theme.call(()))> <Button appearance=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=ButtonAppearance::Subtle appearance=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=ButtonAppearance::Subtle appearance=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

@ -4,22 +4,21 @@
view! { view! {
<Space> <Space>
<Button>"Secondary"</Button> <Button>"Secondary"</Button>
<Button variant=ButtonAppearance::Primary>"Primary"</Button> <Button appearance=ButtonAppearance::Primary>"Primary"</Button>
<Button variant=ButtonAppearance::Subtle>"Subtle"</Button> <Button appearance=ButtonAppearance::Subtle>"Subtle"</Button>
<Button variant=ButtonAppearance::Transparent>"Transparent"</Button> <Button appearance=ButtonAppearance::Transparent>"Transparent"</Button>
</Space> </Space>
} }
``` ```
### Color ### Shape
```rust demo ```rust demo
view! { view! {
<Space> <Space>
<Button color=ButtonColor::Primary>"Primary Color"</Button> <Button>"Rounded"</Button>
<Button color=ButtonColor::Success>"Success Color"</Button> <Button shape=ButtonShape::Circular>"Circular"</Button>
<Button color=ButtonColor::Warning>"Warning Color"</Button> <Button shape=ButtonShape::Square>"Square"</Button>
<Button color=ButtonColor::Error>"Error Color"</Button>
</Space> </Space>
} }
``` ```
@ -76,6 +75,20 @@ view! {
} }
``` ```
### Color
```rust demo
view! {
<Space>
<Button color=ButtonColor::Primary>"Primary Color"</Button>
<Button color=ButtonColor::Success>"Success Color"</Button>
<Button color=ButtonColor::Warning>"Warning Color"</Button>
<Button color=ButtonColor::Error>"Error Color"</Button>
</Space>
}
```
### Loading ### Loading
```rust demo ```rust demo
@ -107,16 +120,16 @@ view! {
```rust demo ```rust demo
view! { view! {
<Space> <Space>
<Button variant=ButtonAppearance::Primary disabled=true> <Button appearance=ButtonAppearance::Primary disabled=true>
"Primary" "Primary"
</Button> </Button>
<Button disabled=true> <Button disabled=true>
"Outlined" "Outlined"
</Button> </Button>
<Button variant=ButtonAppearance::Subtle disabled=true> <Button appearance=ButtonAppearance::Subtle disabled=true>
"Subtle" "Subtle"
</Button> </Button>
<Button variant=ButtonAppearance::Transparent disabled=true> <Button appearance=ButtonAppearance::Transparent disabled=true>
"Transparent" "Transparent"
</Button> </Button>
</Space> </Space>
@ -171,7 +184,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<ButtonAppearance>` | `ButtonAppearance::Primary` | Button's variant. | | appearance | `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

@ -90,6 +90,13 @@
border-color: transparent; border-color: transparent;
} }
.thaw-button--circular {
border-radius: var(--borderRadiusCircular);
}
.thaw-button--square {
border-radius: var(--borderRadiusNone);
}
.thaw-button--block { .thaw-button--block {
display: flex; display: flex;
width: 100%; width: 100%;

View file

@ -29,6 +29,24 @@ impl ButtonAppearance {
} }
} }
#[derive(Default, PartialEq, Clone, Copy)]
pub enum ButtonShape {
#[default]
Rounded,
Circular,
Square
}
impl ButtonShape {
fn as_str(&self) -> &str {
match self {
ButtonShape::Rounded => "rounded",
ButtonShape::Circular => "circular",
ButtonShape::Square => "square",
}
}
}
#[derive(Default, Clone)] #[derive(Default, Clone)]
pub enum ButtonColor { pub enum ButtonColor {
#[default] #[default]
@ -76,15 +94,6 @@ pub enum ButtonSize {
} }
impl ButtonSize { impl ButtonSize {
fn theme_font_size(&self, theme: &Theme) -> String {
match self {
ButtonSize::Tiny => theme.common.font_size_tiny.clone(),
ButtonSize::Small => theme.common.font_size_small.clone(),
ButtonSize::Medium => theme.common.font_size_medium.clone(),
ButtonSize::Large => theme.common.font_size_large.clone(),
}
}
fn theme_height(&self, theme: &Theme) -> String { fn theme_height(&self, theme: &Theme) -> String {
match self { match self {
ButtonSize::Tiny => theme.common.height_tiny.clone(), ButtonSize::Tiny => theme.common.height_tiny.clone(),
@ -108,7 +117,8 @@ 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<ButtonAppearance>, #[prop(optional, into)] appearance: MaybeSignal<ButtonAppearance>,
#[prop(optional, into)] shape: MaybeSignal<ButtonShape>,
#[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>,
@ -129,10 +139,6 @@ pub fn Button(
"--thaw-font-color-disabled: {};", "--thaw-font-color-disabled: {};",
theme.button.color_text_disabled theme.button.color_text_disabled
)); ));
css_vars.push_str(&format!(
"--thaw-font-size: {};",
size.get().theme_font_size(theme)
));
css_vars.push_str(&format!( css_vars.push_str(&format!(
"--thaw-height: {};", "--thaw-height: {};",
size.get().theme_height(theme) size.get().theme_height(theme)
@ -142,7 +148,7 @@ pub fn Button(
size.get().theme_padding(theme) size.get().theme_padding(theme)
)); ));
match variant.get() { match appearance.get() {
ButtonAppearance::Secondary => {} ButtonAppearance::Secondary => {}
ButtonAppearance::Primary => { ButtonAppearance::Primary => {
let bg_color_hover = color.get().theme_color_hover(theme); let bg_color_hover = color.get().theme_color_hover(theme);
@ -190,7 +196,7 @@ pub fn Button(
mount_style("button", include_str!("./button.css")); mount_style("button", include_str!("./button.css"));
let icon_style = if children.is_some() { let icon_style = if children.is_some() {
"margin-right: 6px" "margin-right: var(--spacingHorizontalSNudge)"
} else { } else {
"" ""
}; };
@ -224,7 +230,8 @@ pub fn Button(
"thaw-button", ("thaw-button--round", move || round.get()), "thaw-button", ("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()), disabled.get()), ("thaw-button--block", move || block.get()),
move || format!("thaw-button--{}", variant.get().as_str()), move || format!("thaw-button--{}", appearance.get().as_str()),
move || format!("thaw-button--{}", shape.get().as_str()),
class.map(| c | move || c.get()) class.map(| c | move || c.get())
] ]

View file

@ -34,9 +34,10 @@ pub fn Card(
let css_vars = create_memo(move |_| { let css_vars = create_memo(move |_| {
let mut css_vars = String::new(); let mut css_vars = String::new();
theme.with(|theme| { theme.with(|theme| {
// TODO
css_vars.push_str(&format!( css_vars.push_str(&format!(
"--thaw-background-color: {};", "--thaw-background-color: ;",
theme.common.background_color // theme.common.background_color
)); ));
css_vars.push_str(&format!( css_vars.push_str(&format!(
"--thaw-border-color: {};", "--thaw-border-color: {};",

View file

@ -13,52 +13,52 @@ pub fn ConfigProvider(
let css_vars = Memo::new(move |_| { let css_vars = Memo::new(move |_| {
let mut css_vars = String::new(); let mut css_vars = String::new();
theme.with(|theme| { theme.with(|theme| {
css_vars.push_str(&format!( // css_vars.push_str(&format!(
"--fontFamilyBase: {};", // "--fontFamilyBase: {};",
theme.common.font_family_base // theme.common.font_family_base
)); // ));
css_vars.push_str(&format!( // css_vars.push_str(&format!(
"--fontSizeBase300: {};", // "--fontSizeBase300: {};",
theme.common.font_size_base_300 // theme.common.font_size_base_300
)); // ));
css_vars.push_str(&format!( // css_vars.push_str(&format!(
"--lineHeightBase300: {};", // "--lineHeightBase300: {};",
theme.common.line_height_base300, // theme.common.line_height_base300,
)); // ));
css_vars.push_str(&format!( // css_vars.push_str(&format!(
"--fontWeightRegular: {};", // "--fontWeightRegular: {};",
theme.common.font_weight_regular // theme.common.font_weight_regular
)); // ));
css_vars.push_str(&format!( // css_vars.push_str(&format!(
"--fontWeightSemibold: {};", // "--fontWeightSemibold: {};",
theme.common.font_weight_semibold // theme.common.font_weight_semibold
)); // ));
css_vars.push_str(&format!( // css_vars.push_str(&format!(
"--fontWeightBold: {};", // "--fontWeightBold: {};",
theme.common.font_weight_bold // theme.common.font_weight_bold
)); // ));
css_vars.push_str(&format!( // css_vars.push_str(&format!(
"--strokeWidthThin: {};", // "--strokeWidthThin: {};",
theme.common.stroke_width_thin, // theme.common.stroke_width_thin,
)); // ));
css_vars.push_str(&format!( // css_vars.push_str(&format!(
"--borderRadiusMedium: {};", // "--borderRadiusMedium: {};",
theme.common.border_radius_medium // theme.common.border_radius_medium
)); // ));
css_vars.push_str(&format!( // css_vars.push_str(&format!(
"--spacingHorizontalM: {};", // "--spacingHorizontalM: {};",
theme.common.spacing_horizontal_m // 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!(
// "--durationFaster: {};",
// theme.common.duration_faster
// ));
// css_vars.push_str(&format!(
// "--curveEasyEase: {};",
// theme.common.curve_easy_ease
// ));
theme.common.write_css_vars(&mut css_vars);
theme.color.write_css_vars(&mut css_vars); theme.color.write_css_vars(&mut css_vars);
}); });
css_vars css_vars

View file

@ -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=ButtonAppearance::Transparent appearance=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=ButtonAppearance::Transparent appearance=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=ButtonAppearance::Subtle appearance=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=ButtonAppearance::Subtle appearance=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=ButtonAppearance::Transparent appearance=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=ButtonAppearance::Transparent appearance=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

@ -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=ButtonAppearance::Transparent appearance=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=ButtonAppearance::Subtle appearance=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=ButtonAppearance::Transparent appearance=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

@ -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=ButtonAppearance::Transparent appearance=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=ButtonAppearance::Transparent appearance=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

@ -7,10 +7,10 @@ pub fn GlobalStyle() -> impl IntoView {
create_effect(move |_| { create_effect(move |_| {
theme.with(|theme| { theme.with(|theme| {
if let Some(body) = document().body() { if let Some(body) = document().body() {
_ = body // _ = body
.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 // _ = body
// .style() // .style()
// .set_property("font-size", &theme.common.font_size); // .set_property("font-size", &theme.common.font_size);

View file

@ -90,10 +90,10 @@ where
on_blur=set_within_range on_blur=set_within_range
> >
<InputSuffix slot> <InputSuffix slot>
<Button disabled=minus_disabled variant=ButtonAppearance::Transparent on_click=sub> <Button disabled=minus_disabled appearance=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=ButtonAppearance::Transparent on_click=add> <Button disabled=plus_disabled appearance=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

@ -38,7 +38,9 @@ pub fn Popover(
let font_color = if tooltip { let font_color = if tooltip {
"#fff" "#fff"
} else { } else {
&theme.common.font_color // TODO
// &theme.common.font_color
""
}; };
css_vars.push_str(&format!("--thaw-font-color: {};", font_color)); css_vars.push_str(&format!("--thaw-font-color: {};", font_color));
}); });

View file

@ -1,10 +1,9 @@
use super::ThemeMethod; use super::ThemeMethod;
use thaw_macro::WriteCSSVars;
#[derive(Clone)] #[derive(Clone, WriteCSSVars)]
pub struct CommonTheme { pub struct CommonTheme {
pub font_family_base: String, pub font_family_base: String,
pub font_color: String,
pub background_color: String,
pub border_color: String, pub border_color: String,
pub color_scheme: String, pub color_scheme: String,
@ -31,8 +30,11 @@ pub struct CommonTheme {
pub stroke_width_thin: String, pub stroke_width_thin: String,
pub border_radius_none: String,
pub border_radius_medium: String, pub border_radius_medium: String,
pub border_radius_circular: String,
pub spacing_horizontal_s_nudge: String,
pub spacing_horizontal_m: String, pub spacing_horizontal_m: String,
pub duration_faster: String, pub duration_faster: String,
@ -52,8 +54,6 @@ impl CommonTheme {
fn common() -> Self { fn common() -> Self {
Self { Self {
font_family_base: "'Segoe UI', 'Segoe UI Web (West European)', -apple-system, BlinkMacSystemFont, Roboto, 'Helvetica Neue', sans-serif".into(), font_family_base: "'Segoe UI', 'Segoe UI Web (West European)', -apple-system, BlinkMacSystemFont, Roboto, 'Helvetica Neue', sans-serif".into(),
font_color: "".into(),
background_color: "".into(),
border_color: "".into(), border_color: "".into(),
color_scheme: "".into(), color_scheme: "".into(),
color_primary: "".into(), color_primary: "".into(),
@ -79,8 +79,11 @@ impl CommonTheme {
stroke_width_thin: "1px".into(), stroke_width_thin: "1px".into(),
border_radius_none: "0".into(),
border_radius_medium: "4px".into(), border_radius_medium: "4px".into(),
border_radius_circular: "10000px".into(),
spacing_horizontal_s_nudge: "6px".into(),
spacing_horizontal_m: "12px".into(), spacing_horizontal_m: "12px".into(),
duration_faster: "100ms".into(), duration_faster: "100ms".into(),
@ -101,8 +104,6 @@ impl CommonTheme {
impl ThemeMethod for CommonTheme { impl ThemeMethod for CommonTheme {
fn light() -> Self { fn light() -> Self {
Self { Self {
font_color: "#11181c".into(),
background_color: "#fff".into(),
color_scheme: "light".into(), color_scheme: "light".into(),
color_primary: "#0078ff".into(), color_primary: "#0078ff".into(),
color_primary_hover: "#2994ff".into(), color_primary_hover: "#2994ff".into(),
@ -123,8 +124,6 @@ impl ThemeMethod for CommonTheme {
} }
fn dark() -> Self { fn dark() -> Self {
Self { Self {
font_color: "#ecedee".into(),
background_color: "#1a1d1e".into(),
color_scheme: "dark".into(), color_scheme: "dark".into(),
color_primary: "#0078ff".into(), color_primary: "#0078ff".into(),
color_primary_hover: "#2994ff".into(), color_primary_hover: "#2994ff".into(),