Skip to content

Commit 5445e78

Browse files
committed
Implement theme
1 parent c641250 commit 5445e78

File tree

27 files changed

+662
-627
lines changed

27 files changed

+662
-627
lines changed

Cargo.lock

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

apps/next/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
/.pnp
66
.pnp.*
77
.yarn/*
8+
.df
89
!.yarn/patches
910
!.yarn/plugins
1011
!.yarn/releases

apps/next/devup.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,34 @@
77
"dark": {
88
"text": "#fff"
99
}
10+
},
11+
"typography": {
12+
"bold": {
13+
"fontFamily": "Freesentation",
14+
"fontSize": "14px",
15+
"fontWeight": "800",
16+
"lineHeight": "120%",
17+
"letterSpacing": "-0.28px"
18+
},
19+
"header": [
20+
{
21+
"fontFamily": "Freesentation",
22+
"fontSize": "12px",
23+
"fontWeight": "600",
24+
"lineHeight": "120%",
25+
"letterSpacing": "-0.24px"
26+
},
27+
null,
28+
null,
29+
null,
30+
{
31+
"fontFamily": "Freesentation",
32+
"fontSize": "16px",
33+
"fontWeight": "600",
34+
"lineHeight": "120%",
35+
"letterSpacing": "-0.32px"
36+
}
37+
]
1038
}
1139
}
1240
}

apps/next/src/app/page.tsx

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,43 +9,38 @@ export default function HomePage() {
99

1010
return (
1111
<div>
12-
<p>Track & field champions:</p>
12+
<p
13+
style={{
14+
backgroundColor: 'blue',
15+
}}
16+
>
17+
Track & field champions:
18+
</p>
1319
<Box
1420
_hover={{
15-
bg: ['yellow', 'red'],
21+
bg: 'yellow',
1622
cursor: 'cell',
1723
}}
18-
as="span"
19-
bg="blue"
24+
as="section"
25+
bg="$text"
2026
color={color}
2127
cursor="pointer"
2228
data-testid="box"
2329
fontSize={32}
2430
position="relative"
2531
py="28px"
2632
>
27-
<Box
28-
_lastChild={{
29-
color: 'purple',
30-
}}
31-
>
32-
hello
33-
</Box>
34-
<Box
35-
_lastChild={{
36-
color: 'purple',
37-
}}
38-
>
39-
hello
40-
</Box>
33+
<Box>hello</Box>
34+
<Box>hello</Box>
4135
</Box>
4236
<Text
4337
className={css`
4438
background: red;
4539
color: blue;
4640
`}
41+
typography="bold"
4742
>
48-
text
43+
text typo
4944
</Text>
5045
<Text color="$text">text</Text>
5146
<Box color={enabled ? 'green' : 'blue'} fontSize={[32]} pr="20px">

apps/next/tsconfig.json

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
{
22
"compilerOptions": {
33
"target": "ES2017",
4-
"lib": ["dom", "dom.iterable", "esnext"],
4+
"lib": [
5+
"dom",
6+
"dom.iterable",
7+
"esnext"
8+
],
59
"allowJs": true,
610
"skipLibCheck": true,
711
"strict": true,
@@ -19,9 +23,19 @@
1923
}
2024
],
2125
"paths": {
22-
"@/*": ["./src/*"]
26+
"@/*": [
27+
"./src/*"
28+
]
2329
}
2430
},
25-
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26-
"exclude": ["node_modules"]
31+
"include": [
32+
"next-env.d.ts",
33+
"**/*.ts",
34+
"**/*.tsx",
35+
".next/types/**/*.ts",
36+
".df/*.d.ts"
37+
],
38+
"exclude": [
39+
"node_modules"
40+
]
2741
}

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

Lines changed: 99 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use extractor::{extract, ExtractOption, ExtractStyleValue, StyleProperty};
22
use js_sys::{Object, Reflect};
33
use once_cell::sync::Lazy;
4-
use sheet::theme::{ColorTheme, Theme};
4+
use sheet::theme::{ColorTheme, Theme, Typography};
55
use sheet::StyleSheet;
6+
use std::collections::HashSet;
67
use std::sync::Mutex;
78
use wasm_bindgen::prelude::*;
89

@@ -69,6 +70,7 @@ impl Output {
6970
collected = true;
7071
}
7172
}
73+
ExtractStyleValue::Typography(_) => {}
7274
}
7375
}
7476
if !collected {
@@ -104,10 +106,31 @@ pub fn code_extract(
104106
Err(error) => Err(JsValue::from_str(error.to_string().as_str())),
105107
}
106108
}
109+
fn object_to_typography(obj: Object, level: u8) -> Result<Typography, JsValue> {
110+
Ok(Typography::new(
111+
Reflect::get(&obj, &JsValue::from_str("fontFamily"))?
112+
.as_string()
113+
.unwrap(),
114+
Reflect::get(&obj, &JsValue::from_str("fontSize"))?
115+
.as_string()
116+
.unwrap(),
117+
Reflect::get(&obj, &JsValue::from_str("fontWeight"))?
118+
.as_string()
119+
.unwrap(),
120+
Reflect::get(&obj, &JsValue::from_str("lineHeight"))?
121+
.as_string()
122+
.unwrap(),
123+
Reflect::get(&obj, &JsValue::from_str("letterSpacing"))?
124+
.as_string()
125+
.unwrap(),
126+
level,
127+
))
128+
}
129+
107130
fn theme_object_to_hashmap(js_value: JsValue) -> Result<Theme, JsValue> {
108131
let mut theme = Theme::new();
109132

110-
if let Some(obj) = js_value.dyn_into::<Object>().ok() {
133+
if let Ok(obj) = js_value.dyn_into::<Object>() {
111134
// get colors
112135
if let Some(colors_obj) = Reflect::get(&obj, &JsValue::from_str("colors"))
113136
.ok()
@@ -143,6 +166,38 @@ fn theme_object_to_hashmap(js_value: JsValue) -> Result<Theme, JsValue> {
143166
}
144167
}
145168
}
169+
170+
if let Some(typography_obj) = Reflect::get(&obj, &JsValue::from_str("typography"))
171+
.ok()
172+
.and_then(|v| v.dyn_into::<Object>().ok())
173+
{
174+
for entry in Object::entries(&typography_obj).into_iter() {
175+
if let (Ok(key), Ok(value)) = (
176+
Reflect::get(&entry, &JsValue::from_f64(0f64)),
177+
Reflect::get(&entry, &JsValue::from_f64(1f64)),
178+
) {
179+
if let (Some(key_str), Some(typo_value)) =
180+
(key.as_string(), value.dyn_into::<Object>().ok())
181+
{
182+
let mut typo_vec = vec![];
183+
if typo_value.is_array() {
184+
if let Ok(typo_arr) = typo_value.dyn_into::<js_sys::Array>() {
185+
for i in 0..typo_arr.length() {
186+
if let Ok(typo_obj) = typo_arr.get(i).dyn_into::<Object>() {
187+
typo_vec.push(object_to_typography(typo_obj, i as u8)?);
188+
}
189+
}
190+
}
191+
} else if typo_value.is_object() && !typo_value.is_null() {
192+
if let Ok(typo_obj) = typo_value.dyn_into::<Object>() {
193+
typo_vec.push(object_to_typography(typo_obj, 0)?);
194+
}
195+
}
196+
theme.typography.insert(key_str, typo_vec);
197+
}
198+
}
199+
}
200+
}
146201
} else {
147202
return Err(JsValue::from_str(
148203
"Failed to convert the provided object to a hashmap",
@@ -161,6 +216,47 @@ pub fn register_theme(theme_object: JsValue) -> Result<(), JsValue> {
161216

162217
#[wasm_bindgen(js_name = "getCss")]
163218
pub fn get_css() -> Result<String, JsValue> {
164-
let mut sheet = GLOBAL_STYLE_SHEET.lock().unwrap();
219+
let sheet = GLOBAL_STYLE_SHEET.lock().unwrap();
165220
Ok(sheet.create_css())
166221
}
222+
223+
#[wasm_bindgen(js_name = "getThemeInterface")]
224+
pub fn get_theme_interface(
225+
package_name: &str,
226+
color_interface_name: &str,
227+
typography_interface_name: &str,
228+
) -> Result<String, JsValue> {
229+
let sheet = GLOBAL_STYLE_SHEET.lock().unwrap();
230+
let mut color_keys = HashSet::new();
231+
let mut typography_keys = HashSet::new();
232+
for color_theme in sheet.theme.colors.themes.values() {
233+
color_theme.keys().for_each(|key| {
234+
color_keys.insert(key.clone());
235+
});
236+
}
237+
sheet.theme.typography.keys().for_each(|key| {
238+
typography_keys.insert(key.clone());
239+
});
240+
241+
if color_keys.is_empty() && typography_keys.is_empty() {
242+
Ok("".to_string())
243+
} else {
244+
Ok(format!(
245+
"import \"{}\";declare module \"{}\"{{interface {} {{{}}}interface {} {{{}}}}}",
246+
package_name,
247+
package_name,
248+
color_interface_name,
249+
color_keys
250+
.into_iter()
251+
.map(|key| format!("${}:null;", key))
252+
.collect::<Vec<String>>()
253+
.join(""),
254+
typography_interface_name,
255+
typography_keys
256+
.into_iter()
257+
.map(|key| format!("{}:null;", key))
258+
.collect::<Vec<String>>()
259+
.join("")
260+
))
261+
}
262+
}

libs/extractor/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,4 @@ oxc_codegen = "0.45.0"
1313
css = { path = "../css" }
1414

1515
[dev-dependencies]
16-
insta = "1.42.0"
17-
cargo-insta = "1.42.0"
16+
insta = "1.42.0"

libs/extractor/src/component.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -87,18 +87,20 @@ impl ExportVariableKind {
8787
}
8888
}
8989

90-
impl From<String> for ExportVariableKind {
91-
fn from(kind: String) -> Self {
92-
match kind.as_str() {
93-
"Box" => ExportVariableKind::Box,
94-
"Text" => ExportVariableKind::Text,
95-
"Button" => ExportVariableKind::Button,
96-
"Input" => ExportVariableKind::Input,
97-
"Flex" => ExportVariableKind::Flex,
98-
"VStack" => ExportVariableKind::VStack,
99-
"Center" => ExportVariableKind::Center,
100-
"css" => ExportVariableKind::Css,
101-
_ => panic!("Unknown component kind: {}", kind),
90+
impl TryFrom<String> for ExportVariableKind {
91+
type Error = ();
92+
93+
fn try_from(value: String) -> Result<Self, Self::Error> {
94+
match value.as_str() {
95+
"Box" => Ok(ExportVariableKind::Box),
96+
"Text" => Ok(ExportVariableKind::Text),
97+
"Button" => Ok(ExportVariableKind::Button),
98+
"Input" => Ok(ExportVariableKind::Input),
99+
"Flex" => Ok(ExportVariableKind::Flex),
100+
"VStack" => Ok(ExportVariableKind::VStack),
101+
"Center" => Ok(ExportVariableKind::Center),
102+
"css" => Ok(ExportVariableKind::Css),
103+
_ => Err(()),
102104
}
103105
}
104106
}

libs/extractor/src/lib.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ impl ExtractStyleProperty for ExtractDynamicStyle {
135135
#[derive(Debug, PartialEq, Clone)]
136136
pub enum ExtractStyleValue {
137137
Static(ExtractStaticStyle),
138+
Typography(String),
138139
Dynamic(ExtractDynamicStyle),
139140
Css(ExtractCss),
140141
}
@@ -145,6 +146,9 @@ impl ExtractStyleValue {
145146
ExtractStyleValue::Static(style) => style.extract(),
146147
ExtractStyleValue::Dynamic(style) => style.extract(),
147148
ExtractStyleValue::Css(css) => css.extract(),
149+
ExtractStyleValue::Typography(typo) => {
150+
StyleProperty::ClassName(format!("typo-{}", typo))
151+
}
148152
}
149153
}
150154
}
@@ -734,6 +738,21 @@ mod tests {
734738
.unwrap());
735739
}
736740

741+
#[test]
742+
fn apply_typography() {
743+
assert_debug_snapshot!(extract(
744+
"test.tsx",
745+
r#"import {Text} from '@devup-ui/core'
746+
<Text typography="bold" />
747+
"#,
748+
ExtractOption {
749+
package: "@devup-ui/core".to_string(),
750+
css_file: None
751+
}
752+
)
753+
.unwrap());
754+
}
755+
737756
#[test]
738757
fn raise_error() {
739758
assert!(extract(
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
source: libs/extractor/src/lib.rs
3+
expression: "extract(\"test.tsx\",\nr#\"import {Text} from '@devup-ui/core'\n <Text typography=\"bold\" />\n \"#,\nExtractOption\n{ package: \"@devup-ui/core\".to_string(), css_file: None }).unwrap()"
4+
---
5+
ExtractOutput {
6+
styles: [
7+
Typography(
8+
"bold",
9+
),
10+
],
11+
code: "import \"@devup-ui/core/devup-ui.css\";\nimport { Text } from \"@devup-ui/core\";\n<span className=\"typo-bold\" />;\n",
12+
}

0 commit comments

Comments
 (0)