From 277ee00d3d4ed7ee870a56f55759f2b00ceb10d8 Mon Sep 17 00:00:00 2001 From: luoxiao Date: Tue, 4 Apr 2023 15:55:14 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20perfect=20theme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/basic/src/main.rs | 3 +++ src/button/mod.rs | 42 +++++++++++++++++++++---------- src/button/theme.rs | 2 ++ src/lib.rs | 1 + src/theme/common.rs | 51 +++++++++++++++++++++----------------- src/theme/mod.rs | 36 +++++++++++++++++++++++++-- 6 files changed, 97 insertions(+), 38 deletions(-) diff --git a/examples/basic/src/main.rs b/examples/basic/src/main.rs index c8a49c9..3c2fe2f 100644 --- a/examples/basic/src/main.rs +++ b/examples/basic/src/main.rs @@ -7,6 +7,8 @@ fn main() { #[component] pub fn App(cx: Scope) -> impl IntoView { + let (theme, set_theme) = create_signal(cx, Theme::light()); + provide_context(cx, theme); let (count, set_count) = create_signal(cx, 0.0); let (open, set_open) = create_signal(cx, true); let (button_type, set_button_type) = create_signal(cx, ButtonType::TEXT); @@ -21,6 +23,7 @@ pub fn App(cx: Scope) -> impl IntoView { view! { cx, + {move || count.get()} diff --git a/src/button/mod.rs b/src/button/mod.rs index 26abd13..ec4f3cb 100644 --- a/src/button/mod.rs +++ b/src/button/mod.rs @@ -1,5 +1,5 @@ mod theme; -use crate::{theme::Theme, utils::mount_style::mount_style}; +use crate::{theme::*, utils::mount_style::mount_style}; use leptos::*; use stylers::style_sheet_str; pub use theme::ButtonTheme; @@ -9,17 +9,29 @@ pub enum ButtonType { #[default] PRIMARY, SOLID, - TEXT + TEXT, } -#[derive(Default)] +#[derive(Default, Clone)] pub enum ButtonColor { #[default] PRIMARY, + SUCCESS, WARNING, Error, } +impl ButtonColor { + pub fn theme_color(&self, theme: &Theme) -> String { + match self { + ButtonColor::PRIMARY => theme.common.color_primary.clone(), + ButtonColor::SUCCESS => theme.common.color_success.clone(), + ButtonColor::WARNING => theme.common.color_warning.clone(), + ButtonColor::Error => theme.common.color_error.clone(), + } + } +} + #[component] pub fn Button( cx: Scope, @@ -27,18 +39,22 @@ pub fn Button( #[prop(optional, into)] color: MaybeSignal, children: Children, ) -> impl IntoView { - // let theme = use_context::>(cx); - // let css_vars = create_memo(cx, |_| format!("--font-color")); + let theme = use_theme(cx, Theme::light); + let css_vars = create_memo(cx, move |_| { + let mut css_vars = String::new(); + let theme = theme.get(); + let bg_color = color.get().theme_color(&theme); + css_vars.push_str(&format!("--background-color: {bg_color}")); + css_vars + }); let class_name = mount_style("button", || style_sheet_str!("./src/button/button.css")); - let class = move || { - if type_.get() == ButtonType::TEXT { - "melt-button melt-button--text" - } else { - "melt-button" - } - }; + view! {cx, class=class_name, - } diff --git a/src/button/theme.rs b/src/button/theme.rs index debd26b..d8856b9 100644 --- a/src/button/theme.rs +++ b/src/button/theme.rs @@ -1,4 +1,6 @@ use crate::theme::ThemeMethod; + +#[derive(Clone)] pub struct ButtonTheme { } diff --git a/src/lib.rs b/src/lib.rs index add025f..c4c7dd4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,3 +15,4 @@ pub use modal::*; pub use progress::*; pub use space::*; pub use table::*; +pub use theme::Theme; diff --git a/src/theme/common.rs b/src/theme/common.rs index 990e32a..ba2b5df 100644 --- a/src/theme/common.rs +++ b/src/theme/common.rs @@ -1,8 +1,13 @@ use super::ThemeMethod; + +#[derive(Clone)] pub struct CommonTheme { pub font_family: String, pub color_primary: String, + pub color_success: String, + pub color_warning: String, + pub color_error: String, pub font_size: String, pub font_size_small: String, @@ -22,13 +27,16 @@ pub struct CommonTheme { pub border_radius_large: String, } -impl ThemeMethod for CommonTheme { - fn light() -> Self { +impl CommonTheme { + fn common() -> Self { Self { font_family: "-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(), - color_primary: "#f5222d".into(), - + color_primary: "".into(), + color_success: "".into(), + color_warning: "".into(), + color_error: "".into(), + font_size: "14px".into(), font_size_small: "12px".into(), font_size_medium: "16px".into(), @@ -47,28 +55,25 @@ impl ThemeMethod for CommonTheme { border_radius_large: "8px".into(), } } +} + +impl ThemeMethod for CommonTheme { + fn light() -> Self { + Self { + color_primary: "#f5222d".into(), + color_success: "#18a058".into(), + color_warning: "#f0a020".into(), + color_error: "#d03050".into(), + ..CommonTheme::common() + } + } fn dark() -> Self { Self { - font_family: "-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(), - color_primary: "#d32029".into(), - - font_size: "14px".into(), - font_size_small: "12px".into(), - font_size_medium: "16px".into(), - font_size_large: "20px".into(), - font_size_huge: "24px".into(), - - line_height: "22px".into(), - line_height_small: "20px".into(), - line_height_medium: "24px".into(), - line_height_large: "28px".into(), - line_height_huge: "32px".into(), - - border_radius: "3px".into(), - border_radius_small: "2px".into(), - border_radius_medium: "4px".into(), - border_radius_large: "8px".into(), + color_success: "#18a058".into(), + color_warning: "#f0a020".into(), + color_error: "#d03050".into(), + ..CommonTheme::common() } } } \ No newline at end of file diff --git a/src/theme/mod.rs b/src/theme/mod.rs index 292c27c..710078a 100644 --- a/src/theme/mod.rs +++ b/src/theme/mod.rs @@ -1,4 +1,6 @@ mod common; +use leptos::*; + use self::common::CommonTheme; use crate::ButtonTheme; @@ -7,9 +9,25 @@ pub trait ThemeMethod { fn dark() -> Self; } +#[derive(Clone)] pub struct Theme { - common: CommonTheme, - button: ButtonTheme, + pub common: CommonTheme, + pub button: ButtonTheme, +} + +impl Theme { + pub fn light() -> Self { + Self { + common: CommonTheme::light(), + button: ButtonTheme::light(), + } + } + pub fn dark() -> Self { + Self { + common: CommonTheme::dark(), + button: ButtonTheme::dark(), + } + } } impl ThemeMethod for Theme { @@ -26,3 +44,17 @@ impl ThemeMethod for Theme { } } } + +pub fn use_theme(cx: Scope, default: impl Fn() -> Theme) -> ReadSignal { + use_context::>(cx).unwrap_or_else(|| create_signal(cx, default()).0) +} + +#[cfg(test)] +mod tests { + use super::{use_theme, Theme, ThemeMethod}; + use leptos::*; + + fn t_use_theme(cx: Scope) { + use_theme(cx, Theme::dark); + } +}