mirror of
https://github.com/adoyle0/thaw.git
synced 2025-01-22 22:09:22 -05:00
feat: component theme
This commit is contained in:
parent
9ab8367c21
commit
b6b7df0a05
9 changed files with 181 additions and 204 deletions
10
Cargo.toml
10
Cargo.toml
|
@ -1,9 +1,17 @@
|
|||
[workspace]
|
||||
resolver = "2"
|
||||
members = ["thaw", "thaw_components", "thaw_utils", "demo", "demo_markdown"]
|
||||
members = [
|
||||
"thaw",
|
||||
"thaw_components",
|
||||
"thaw_macro",
|
||||
"thaw_utils",
|
||||
"demo",
|
||||
"demo_markdown",
|
||||
]
|
||||
exclude = ["examples"]
|
||||
|
||||
[workspace.dependencies]
|
||||
thaw = { version = "0.3.1", path = "./thaw" }
|
||||
thaw_components = { version = "0.1.1", path = "./thaw_components" }
|
||||
thaw_macro = { version = "0.1.0", path = "./thaw_macro" }
|
||||
thaw_utils = { version = "0.0.3", path = "./thaw_utils" }
|
||||
|
|
|
@ -15,6 +15,7 @@ license = "MIT"
|
|||
[dependencies]
|
||||
leptos = { version = "0.6.10" }
|
||||
thaw_components = { workspace = true }
|
||||
thaw_macro = { workspace = true }
|
||||
thaw_utils = { workspace = true }
|
||||
web-sys = { version = "0.3.69", features = [
|
||||
"DomRect",
|
||||
|
|
|
@ -59,91 +59,7 @@ pub fn ConfigProvider(
|
|||
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
|
||||
));
|
||||
theme.color.write_css_vars(&mut css_vars);
|
||||
});
|
||||
css_vars
|
||||
});
|
||||
|
|
|
@ -11,9 +11,9 @@ pub fn GlobalStyle() -> impl IntoView {
|
|||
.style()
|
||||
.set_property("background-color", &theme.common.background_color);
|
||||
_ = body.style().set_property("color", &theme.common.font_color);
|
||||
_ = body
|
||||
.style()
|
||||
.set_property("font-size", &theme.common.font_size);
|
||||
// _ = body
|
||||
// .style()
|
||||
// .set_property("font-size", &theme.common.font_size);
|
||||
_ = body
|
||||
.style()
|
||||
.set_property("color-scheme", &theme.common.color_scheme);
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
use thaw_macro::WriteCSSVars;
|
||||
|
||||
#[derive(Clone, WriteCSSVars)]
|
||||
pub struct ColorTheme {
|
||||
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,
|
||||
}
|
||||
|
||||
impl ColorTheme {
|
||||
pub fn light() -> Self {
|
||||
Self {
|
||||
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_foreground_on_brand: "#fff".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: "transparent".into(),
|
||||
color_subtle_background_hover: "#f5f5f5".into(),
|
||||
color_subtle_background_pressed: "#e0e0e0".into(),
|
||||
color_transparent_background: "transparent".into(),
|
||||
color_transparent_background_hover: "transparent".into(),
|
||||
color_transparent_background_pressed: "transparent".into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dark() -> Self {
|
||||
Self {
|
||||
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_foreground_on_brand: "#fff".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: "transparent".into(),
|
||||
color_subtle_background_hover: "#383838".into(),
|
||||
color_subtle_background_pressed: "#2e2e2e".into(),
|
||||
color_transparent_background: "transparent".into(),
|
||||
color_transparent_background_hover: "transparent".into(),
|
||||
color_transparent_background_pressed: "transparent".into(),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,31 +21,6 @@ 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,
|
||||
|
@ -63,24 +38,11 @@ pub struct CommonTheme {
|
|||
pub duration_faster: String,
|
||||
pub curve_easy_ease: String,
|
||||
|
||||
pub font_size: String,
|
||||
pub font_size_tiny: String,
|
||||
pub font_size_small: String,
|
||||
pub font_size_medium: String,
|
||||
pub font_size_large: String,
|
||||
pub font_size_huge: String,
|
||||
|
||||
pub height_tiny: String,
|
||||
pub height_small: String,
|
||||
pub height_medium: String,
|
||||
pub height_large: String,
|
||||
|
||||
pub line_height: String,
|
||||
pub line_height_small: String,
|
||||
pub line_height_medium: String,
|
||||
pub line_height_large: String,
|
||||
pub line_height_huge: String,
|
||||
|
||||
pub border_radius: String,
|
||||
pub border_radius_small: String,
|
||||
pub border_radius_large: String,
|
||||
|
@ -107,31 +69,6 @@ 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(),
|
||||
|
@ -149,24 +86,11 @@ impl CommonTheme {
|
|||
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(),
|
||||
font_size_medium: "14px".into(),
|
||||
font_size_large: "15px".into(),
|
||||
font_size_huge: "16px".into(),
|
||||
|
||||
height_tiny: "22px".into(),
|
||||
height_small: "28px".into(),
|
||||
height_medium: "34px".into(),
|
||||
height_large: "40px".into(),
|
||||
|
||||
line_height: "22px".into(),
|
||||
line_height_small: "22px".into(),
|
||||
line_height_medium: "22px".into(),
|
||||
line_height_large: "23px".into(),
|
||||
line_height_huge: "24px".into(),
|
||||
|
||||
border_radius: "3px".into(),
|
||||
border_radius_small: "2px".into(),
|
||||
border_radius_large: "8px".into(),
|
||||
|
@ -193,25 +117,7 @@ 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()
|
||||
}
|
||||
}
|
||||
|
@ -235,25 +141,6 @@ 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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
mod common;
|
||||
mod color;
|
||||
|
||||
use self::common::CommonTheme;
|
||||
pub use color::ColorTheme;
|
||||
use crate::{
|
||||
mobile::{NavBarTheme, TabbarTheme},
|
||||
AlertTheme, AnchorTheme, AutoCompleteTheme, AvatarTheme, BackTopTheme, BreadcrumbTheme,
|
||||
|
@ -20,6 +22,7 @@ pub trait ThemeMethod {
|
|||
pub struct Theme {
|
||||
pub name: String,
|
||||
pub common: CommonTheme,
|
||||
pub color: ColorTheme,
|
||||
pub button: ButtonTheme,
|
||||
pub input: InputTheme,
|
||||
pub menu: MenuTheme,
|
||||
|
@ -56,6 +59,7 @@ impl Theme {
|
|||
Self {
|
||||
name: "light".into(),
|
||||
common: CommonTheme::light(),
|
||||
color: ColorTheme::light(),
|
||||
button: ButtonTheme::light(),
|
||||
input: InputTheme::light(),
|
||||
menu: MenuTheme::light(),
|
||||
|
@ -91,6 +95,7 @@ impl Theme {
|
|||
Self {
|
||||
name: "dark".into(),
|
||||
common: CommonTheme::dark(),
|
||||
color: ColorTheme::dark(),
|
||||
button: ButtonTheme::dark(),
|
||||
input: InputTheme::dark(),
|
||||
menu: MenuTheme::dark(),
|
||||
|
|
14
thaw_macro/Cargo.toml
Normal file
14
thaw_macro/Cargo.toml
Normal file
|
@ -0,0 +1,14 @@
|
|||
[package]
|
||||
name = "thaw_macro"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
quote = "1.0.36"
|
||||
syn = "2.0.60"
|
||||
proc-macro2 = "1.0.81"
|
57
thaw_macro/src/lib.rs
Normal file
57
thaw_macro/src/lib.rs
Normal file
|
@ -0,0 +1,57 @@
|
|||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{parse_macro_input, Data, DeriveInput, Fields};
|
||||
|
||||
#[proc_macro_derive(WriteCSSVars)]
|
||||
pub fn write_css_vars(input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
let struct_name = &input.ident;
|
||||
let data = match input.data {
|
||||
Data::Struct(data) => data,
|
||||
_ => panic!("Expected a struct!"),
|
||||
};
|
||||
|
||||
let mut css_var_names = vec![];
|
||||
let mut field_names = vec![];
|
||||
match data.fields {
|
||||
Fields::Named(fields) => {
|
||||
for field in fields.named {
|
||||
let field_name = field.ident.unwrap();
|
||||
css_var_names.push(format!(
|
||||
"--{}: {{}};",
|
||||
to_camel_case(field_name.to_string())
|
||||
));
|
||||
field_names.push(field_name);
|
||||
}
|
||||
}
|
||||
_ => panic!("Expected named fields!"),
|
||||
};
|
||||
|
||||
let field_names = field_names.iter();
|
||||
quote! {
|
||||
impl #struct_name {
|
||||
pub fn write_css_vars(&self, css_vars: &mut String) {
|
||||
#(css_vars.push_str(&format!(#css_var_names, self.#field_names));)*
|
||||
}
|
||||
}
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
fn to_camel_case(s: String) -> String {
|
||||
let mut camel_case = String::new();
|
||||
let mut capitalize_next = false;
|
||||
for c in s.chars() {
|
||||
if c.is_alphanumeric() {
|
||||
if capitalize_next {
|
||||
camel_case.push(c.to_ascii_uppercase());
|
||||
capitalize_next = false;
|
||||
} else {
|
||||
camel_case.push(c.to_ascii_lowercase());
|
||||
}
|
||||
} else {
|
||||
capitalize_next = true;
|
||||
}
|
||||
}
|
||||
camel_case
|
||||
}
|
Loading…
Add table
Reference in a new issue