From 9ab8367c215873515b687b885af2a0c6ae414c9b Mon Sep 17 00:00:00 2001 From: luoxiao Date: Wed, 1 May 2024 20:26:17 +0800 Subject: [PATCH] refactor: button appearance --- demo/src/app.rs | 14 +- demo/src/components/site_header.rs | 10 +- demo/src/pages/home.rs | 2 +- demo_markdown/docs/button/mod.md | 34 ++-- thaw/src/button/button.css | 99 +++++++++-- thaw/src/button/mod.rs | 51 +++--- thaw/src/calendar/mod.rs | 6 +- thaw/src/config_provider/config-provider.css | 8 + thaw/src/config_provider/mod.rs | 165 +++++++++++++++++++ thaw/src/date_picker/panel/date_panel.rs | 16 +- thaw/src/date_picker/panel/month_panel.rs | 8 +- thaw/src/date_picker/panel/year_panel.rs | 6 +- thaw/src/global_style/mod.rs | 3 - thaw/src/input_number/mod.rs | 6 +- thaw/src/lib.rs | 2 + thaw/src/theme/color.rs | 0 thaw/src/theme/common.rs | 128 +++++++++++++- thaw/src/time_picker/mod.rs | 4 +- 18 files changed, 460 insertions(+), 102 deletions(-) create mode 100644 thaw/src/config_provider/config-provider.css create mode 100644 thaw/src/config_provider/mod.rs create mode 100644 thaw/src/theme/color.rs diff --git a/demo/src/app.rs b/demo/src/app.rs index a243770..735822a 100644 --- a/demo/src/app.rs +++ b/demo/src/app.rs @@ -115,11 +115,13 @@ fn TheProvider(children: Children) -> impl IntoView { let theme = create_rw_signal(theme); view! { - - - - {children()} - - + + + + + {children()} + + + } } diff --git a/demo/src/components/site_header.rs b/demo/src/components/site_header.rs index 5777aef..78593e7 100644 --- a/demo/src/components/site_header.rs +++ b/demo/src/components/site_header.rs @@ -152,7 +152,7 @@ pub fn SiteHeader() -> impl IntoView { - - - - + + + + } ``` @@ -107,17 +107,17 @@ view! { ```rust demo view! { - - - - } @@ -152,14 +152,14 @@ view! { view! { - - - + + + - - - + + + } @@ -171,7 +171,7 @@ view! { | --- | --- | --- | --- | | class | `OptionalProp>` | `Default::default()` | Additional classes for the button element. | | style | `Option>` | `Default::default()` | Button's style. | -| variant | `MaybeSignal` | `ButtonVariant::Primary` | Button's variant. | +| variant | `MaybeSignal` | `ButtonAppearance::Primary` | Button's variant. | | color | `MaybeSignal` | `ButtonColor::Primary` | Button's color. | | block | `MaybeSignal` | `false` | Whether the button is displayed as block. | | round | `MaybeSignal` | `false` | Whether the button shows rounded corners. | diff --git a/thaw/src/button/button.css b/thaw/src/button/button.css index ad249c1..9f6fab3 100644 --- a/thaw/src/button/button.css +++ b/thaw/src/button/button.css @@ -1,24 +1,93 @@ .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; align-items: 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) { - border-color: var(--thaw-border-color-hover); - background-color: var(--thaw-background-color-hover); +.thaw-button:hover { + background-color: var(--colorNeutralBackground1Hover); + color: var(--colorNeutralForeground1Hover); + border-color: var(--colorNeutralStroke1Hover); 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 { @@ -36,11 +105,11 @@ cursor: not-allowed; } -.thaw-button:active:not(.thaw-button--disabled) { +/* .thaw-button:active:not(.thaw-button--disabled) { transition: all 0.3s; border-color: var(--thaw-border-color-hover); background-color: var(--thaw-background-color-active); -} +} */ .thaw-button--outlined { background-color: transparent; diff --git a/thaw/src/button/mod.rs b/thaw/src/button/mod.rs index ff4cbb5..ef3e674 100644 --- a/thaw/src/button/mod.rs +++ b/thaw/src/button/mod.rs @@ -10,12 +10,23 @@ use thaw_components::{OptionComp, Wave, WaveRef}; use thaw_utils::{class_list, mount_style, ComponentRef, OptionalMaybeSignal, OptionalProp}; #[derive(Default, PartialEq, Clone, Copy)] -pub enum ButtonVariant { +pub enum ButtonAppearance { #[default] + Secondary, Primary, - Outlined, - Text, - Link, + Subtle, + Transparent, +} + +impl ButtonAppearance { + fn as_str(&self) -> &str { + match self { + ButtonAppearance::Secondary => "secondary", + ButtonAppearance::Primary => "primary", + ButtonAppearance::Subtle => "subtle", + ButtonAppearance::Transparent => "transparent", + } + } } #[derive(Default, Clone)] @@ -97,7 +108,7 @@ impl ButtonSize { pub fn Button( #[prop(optional, into)] style: Option>, #[prop(optional, into)] class: OptionalProp>, - #[prop(optional, into)] variant: MaybeSignal, + #[prop(optional, into)] variant: MaybeSignal, #[prop(optional, into)] color: MaybeSignal, #[prop(optional, into)] size: MaybeSignal, #[prop(optional, into)] block: MaybeSignal, @@ -132,7 +143,8 @@ pub fn Button( )); match variant.get() { - ButtonVariant::Primary => { + ButtonAppearance::Secondary => {} + ButtonAppearance::Primary => { let bg_color_hover = color.get().theme_color_hover(theme); let bg_color_active = color.get().theme_color_active(theme); css_vars.push_str(&format!("--thaw-background-color: {bg_color};")); @@ -154,20 +166,7 @@ pub fn Button( theme.button.color_border_disabled )); } - ButtonVariant::Outlined => { - 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 => { + ButtonAppearance::Subtle => { css_vars.push_str(&format!("--thaw-font-color-hover: {bg_color};")); css_vars.push_str(&format!( "--thaw-background-color-hover: {};", @@ -179,7 +178,7 @@ pub fn Button( )); 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("--thaw-ripple-color: #0000;"); } @@ -222,13 +221,11 @@ pub fn Button( view! { diff --git a/thaw/src/date_picker/panel/month_panel.rs b/thaw/src/date_picker/panel/month_panel.rs index d54ca7e..4dfe415 100644 --- a/thaw/src/date_picker/panel/month_panel.rs +++ b/thaw/src/date_picker/panel/month_panel.rs @@ -1,5 +1,5 @@ use super::PanelVariant; -use crate::{Button, ButtonSize, ButtonVariant}; +use crate::{Button, ButtonSize, ButtonAppearance}; use chrono::{Datelike, Month, Months, NaiveDate}; use leptos::*; @@ -23,14 +23,14 @@ pub fn MonthPanel(
- diff --git a/thaw/src/lib.rs b/thaw/src/lib.rs index 396ce71..1854676 100644 --- a/thaw/src/lib.rs +++ b/thaw/src/lib.rs @@ -12,6 +12,7 @@ mod checkbox; mod code; mod collapse; mod color_picker; +mod config_provider; mod date_picker; mod divider; mod drawer; @@ -59,6 +60,7 @@ pub use checkbox::*; pub use code::*; pub use collapse::*; pub use color_picker::*; +pub use config_provider::*; pub use date_picker::*; pub use divider::*; pub use drawer::*; diff --git a/thaw/src/theme/color.rs b/thaw/src/theme/color.rs new file mode 100644 index 0000000..e69de29 diff --git a/thaw/src/theme/common.rs b/thaw/src/theme/common.rs index a10a92a..7cde7de 100644 --- a/thaw/src/theme/common.rs +++ b/thaw/src/theme/common.rs @@ -2,7 +2,7 @@ use super::ThemeMethod; #[derive(Clone)] pub struct CommonTheme { - pub font_family: String, + pub font_family_base: String, pub font_color: String, pub background_color: String, pub border_color: String, @@ -21,6 +21,48 @@ pub struct CommonTheme { pub color_error_hover: 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_tiny: String, pub font_size_small: String, @@ -41,14 +83,13 @@ pub struct CommonTheme { pub border_radius: String, pub border_radius_small: String, - pub border_radius_medium: String, pub border_radius_large: String, } impl CommonTheme { fn common() -> 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(), background_color: "".into(), border_color: "".into(), @@ -66,6 +107,48 @@ impl CommonTheme { color_error_hover: "".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_tiny: "12px".into(), font_size_small: "14px".into(), @@ -86,7 +169,6 @@ impl CommonTheme { border_radius: "3px".into(), border_radius_small: "2px".into(), - border_radius_medium: "4px".into(), border_radius_large: "8px".into(), } } @@ -111,6 +193,25 @@ impl ThemeMethod for CommonTheme { color_error_hover: "#de576d".into(), color_error_active: "#ab1f3f".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() } } @@ -134,6 +235,25 @@ impl ThemeMethod for CommonTheme { color_error_hover: "#de576d".into(), color_error_active: "#e57272".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() } } diff --git a/thaw/src/time_picker/mod.rs b/thaw/src/time_picker/mod.rs index 31d1319..027a7bf 100644 --- a/thaw/src/time_picker/mod.rs +++ b/thaw/src/time_picker/mod.rs @@ -3,7 +3,7 @@ mod theme; pub use theme::TimePickerTheme; use crate::{ - use_theme, Button, ButtonSize, ButtonVariant, Icon, Input, InputSuffix, Scrollbar, + use_theme, Button, ButtonSize, ButtonAppearance, Icon, Input, InputSuffix, Scrollbar, ScrollbarRef, SignalWatch, Theme, }; use chrono::{Local, NaiveTime, Timelike}; @@ -286,7 +286,7 @@ fn Panel(