Skip to content

Commit a7c50bf

Browse files
committed
Implement theme
1 parent c35e741 commit a7c50bf

File tree

21 files changed

+350
-70
lines changed

21 files changed

+350
-70
lines changed

Cargo.lock

Lines changed: 25 additions & 27 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/next/devup.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"theme": {
3+
"colors": {
4+
"default": {
5+
"text": "#333"
6+
},
7+
"dark": {
8+
"text": "#fff"
9+
}
10+
}
11+
}
12+
}

apps/next/src/app/page.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client'
22

3-
import { Box } from '@devup-ui/react'
3+
import { Box, css, Text } from '@devup-ui/react'
44
import { useState } from 'react'
55

66
export default function HomePage() {
@@ -26,6 +26,15 @@ export default function HomePage() {
2626
>
2727
hello
2828
</Box>
29+
<Text
30+
className={css`
31+
background: red;
32+
color: blue;
33+
`}
34+
>
35+
text
36+
</Text>
37+
<Text color="$text">text</Text>
2938
<Box color={enabled ? 'green' : 'blue'} fontSize={[32]} pr="20px">
3039
hello
3140
</Box>

bindings/devup-ui-wasm/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ crate-type = ["cdylib", "rlib"]
1111
default = ["console_error_panic_hook"]
1212

1313
[dependencies]
14-
wasm-bindgen = "0.2.99"
14+
wasm-bindgen = "0.2.100"
1515
extractor = { path = "../../libs/extractor" }
1616
sheet = { path = "../../libs/sheet" }
1717

@@ -21,9 +21,10 @@ sheet = { path = "../../libs/sheet" }
2121
# code size when deploying.
2222
console_error_panic_hook = { version = "0.1.7", optional = true }
2323
once_cell = "1.20.2"
24+
js-sys = "0.3.76"
2425

2526
[dev-dependencies]
26-
wasm-bindgen-test = "0.3.49"
27+
wasm-bindgen-test = "0.3.50"
2728

2829
[profile.release]
2930
# Tell `rustc` to optimize for small code size.

bindings/devup-ui-wasm/src/lib.rs

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use extractor::{extract, ExtractOption, ExtractStyleValue, StyleProperty};
2+
use js_sys::{Object, Reflect};
23
use once_cell::sync::Lazy;
4+
use sheet::theme::{ColorTheme, Theme};
35
use sheet::StyleSheet;
46
use std::sync::Mutex;
57
use wasm_bindgen::prelude::*;
@@ -14,7 +16,7 @@ pub struct Output {
1416
#[wasm_bindgen]
1517
extern "C" {
1618
#[wasm_bindgen(js_namespace = console)]
17-
fn log(s: &str);
19+
fn log(s: &JsValue);
1820
}
1921

2022
#[wasm_bindgen]
@@ -41,7 +43,7 @@ impl Output {
4143
};
4244
match style {
4345
ExtractStyleValue::Static(st) => {
44-
if let Some(css) = sheet.add_property(
46+
if sheet.add_property(
4547
cls,
4648
st.property.clone(),
4749
st.level,
@@ -52,7 +54,7 @@ impl Output {
5254
}
5355
}
5456
ExtractStyleValue::Dynamic(dy) => {
55-
if let Some(css) = sheet.add_property(
57+
if sheet.add_property(
5658
cls,
5759
dy.property.clone(),
5860
dy.level,
@@ -63,7 +65,7 @@ impl Output {
6365
}
6466
}
6567
ExtractStyleValue::Css(cs) => {
66-
if let Some(css) = sheet.add_css(cls, cs.css.clone()) {
68+
if sheet.add_css(cls, cs.css.clone()) {
6769
collected = true;
6870
}
6971
}
@@ -76,7 +78,7 @@ impl Output {
7678
}
7779
}
7880

79-
#[wasm_bindgen(js_name = "codeExtract", catch)]
81+
#[wasm_bindgen(js_name = "codeExtract")]
8082
pub fn code_extract(
8183
filename: &str,
8284
code: &str,
@@ -102,3 +104,58 @@ pub fn code_extract(
102104
Err(error) => Err(JsValue::from_str(error.to_string().as_str())),
103105
}
104106
}
107+
pub fn theme_object_to_hashmap(js_value: JsValue) -> Result<Theme, JsValue> {
108+
let mut theme = Theme::new();
109+
110+
if let Some(obj) = js_value.dyn_into::<Object>().ok() {
111+
// get colors
112+
if let Some(colors_obj) = Reflect::get(&obj, &JsValue::from_str("colors"))
113+
.ok()
114+
.and_then(|v| v.dyn_into::<Object>().ok())
115+
{
116+
for entry in Object::entries(&colors_obj).into_iter() {
117+
if let (Ok(key), Ok(value)) = (
118+
Reflect::get(&entry, &JsValue::from_f64(0f64)),
119+
Reflect::get(&entry, &JsValue::from_f64(1f64)),
120+
) {
121+
if let (Some(key_str), Some(theme_value)) =
122+
(key.as_string(), value.dyn_into::<Object>().ok())
123+
{
124+
let mut color_theme = ColorTheme::new();
125+
for var_entry in Object::entries(&theme_value).into_iter() {
126+
if let (Ok(var_key), Ok(var_value)) = (
127+
Reflect::get(&var_entry, &JsValue::from_f64(0f64)),
128+
Reflect::get(&var_entry, &JsValue::from_f64(1f64)),
129+
) {
130+
if let (Some(var_key_str), Some(var_value_str)) =
131+
(var_key.as_string(), var_value.as_string())
132+
{
133+
color_theme.add_color(var_key_str, var_value_str);
134+
} else {
135+
return Err(JsValue::from_str(
136+
"Failed to get key and value from the theme object",
137+
));
138+
}
139+
}
140+
}
141+
theme.colors.add_theme(key_str, color_theme);
142+
}
143+
}
144+
}
145+
}
146+
} else {
147+
return Err(JsValue::from_str(
148+
"Failed to convert the provided object to a hashmap",
149+
));
150+
}
151+
Ok(theme)
152+
}
153+
154+
#[wasm_bindgen(js_name = "registerTheme")]
155+
pub fn register_theme(theme_object: JsValue) -> Result<(), JsValue> {
156+
log(&theme_object);
157+
let theme_object = theme_object_to_hashmap(theme_object)?;
158+
let mut sheet = GLOBAL_STYLE_SHEET.lock().unwrap();
159+
sheet.set_theme(theme_object);
160+
Ok(())
161+
}

libs/extractor/src/lib.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,4 +727,19 @@ mod tests {
727727
)
728728
.unwrap());
729729
}
730+
731+
#[test]
732+
fn extract_static_css_with_theme() {
733+
assert_debug_snapshot!(extract(
734+
"test.tsx",
735+
r#"import {Box} from '@devup-ui/core'
736+
<Box color="$nice" />
737+
"#,
738+
ExtractOption {
739+
package: "@devup-ui/core".to_string(),
740+
css_file: None
741+
}
742+
)
743+
.unwrap());
744+
}
730745
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
source: libs/extractor/src/lib.rs
3+
expression: "extract(\"test.tsx\",\nr#\"import {Box} from '@devup-ui/core'\n <Box color=\"$nice\" />\n \"#,\nExtractOption\n{ package: \"@devup-ui/core\".to_string(), css_file: None }).unwrap()"
4+
---
5+
ExtractOutput {
6+
styles: [
7+
Static(
8+
ExtractStaticStyle {
9+
property: "color",
10+
value: "$nice",
11+
level: 0,
12+
selector: None,
13+
},
14+
),
15+
],
16+
code: "import \"@devup-ui/core/devup-ui.css\";\nimport { Box } from \"@devup-ui/core\";\n<div className=\"d10616791853849289151\" />;\n",
17+
}

0 commit comments

Comments
 (0)