Skip to content

Commit 7fdc5dc

Browse files
committed
Update
1 parent 21d7c78 commit 7fdc5dc

27 files changed

Lines changed: 777 additions & 48 deletions

libs/extractor/src/lib.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ mod gen_style;
88
mod prop_modify_utils;
99
mod util_type;
1010
mod utils;
11+
mod vanilla_extract;
1112
mod visit;
1213
use crate::extract_style::extract_style_value::ExtractStyleValue;
1314
use crate::visit::DevupVisitor;
@@ -111,6 +112,40 @@ pub fn extract(
111112
});
112113
}
113114

115+
// Handle vanilla-extract style files (.css.ts, .css.js)
116+
let (processed_code, is_vanilla_extract) = if vanilla_extract::is_vanilla_extract_file(filename)
117+
{
118+
match vanilla_extract::execute_vanilla_extract(code, &option.package) {
119+
Ok(collected) => {
120+
let generated =
121+
vanilla_extract::collected_styles_to_code(&collected, &option.package);
122+
(generated, true)
123+
}
124+
Err(_) => {
125+
// Fall back to treating as regular file if execution fails
126+
(code.to_string(), false)
127+
}
128+
}
129+
} else {
130+
(code.to_string(), false)
131+
};
132+
133+
// For vanilla-extract files, if no styles were collected, return early
134+
if is_vanilla_extract && processed_code.is_empty() {
135+
return Ok(ExtractOutput {
136+
styles: HashSet::new(),
137+
code: code.to_string(),
138+
map: None,
139+
css_file: None,
140+
});
141+
}
142+
143+
let code_to_parse = if is_vanilla_extract {
144+
&processed_code
145+
} else {
146+
code
147+
};
148+
114149
let source_type = SourceType::from_path(filename)?;
115150
let css_file = if option.single_css {
116151
format!("{}/devup-ui.css", option.css_dir)
@@ -131,7 +166,7 @@ pub fn extract(
131166
mut program, // AST
132167
panicked, // Parser encountered an error it couldn't recover from
133168
..
134-
} = Parser::new(&allocator, code, source_type).parse();
169+
} = Parser::new(&allocator, code_to_parse, source_type).parse();
135170
if panicked {
136171
return Err("Parser panicked".into());
137172
}

libs/extractor/src/snapshots/extractor__tests__vanilla_extract_composition.snap

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,61 @@ source: libs/extractor/src/lib.rs
33
expression: "ToBTreeSet::from(extract(\"composition.css.ts\",\nr#\"import { style } from '@devup-ui/react'\nconst base = style({\n padding: 12,\n borderRadius: 4\n})\nconst interactive = style({\n cursor: 'pointer',\n transition: 'all 0.2s'\n})\nexport const button = style([base, interactive, {\n background: 'blue',\n color: 'white'\n}])\n\"#,\nExtractOption\n{\n package: \"@devup-ui/react\".to_string(), css_dir:\n \"@devup-ui/react\".to_string(), single_css: true, import_main_css: false\n}).unwrap())"
44
---
55
ToBTreeSet {
6-
styles: {},
7-
code: "import { style } from \"@devup-ui/react\";\nconst base = style({\n\tpadding: 12,\n\tborderRadius: 4\n});\nconst interactive = style({\n\tcursor: \"pointer\",\n\ttransition: \"all 0.2s\"\n});\nexport const button = style([\n\tbase,\n\tinteractive,\n\t{\n\t\tbackground: \"blue\",\n\t\tcolor: \"white\"\n\t}\n]);\n",
6+
styles: {
7+
Static(
8+
ExtractStaticStyle {
9+
property: "background",
10+
value: "blue",
11+
level: 0,
12+
selector: None,
13+
style_order: None,
14+
},
15+
),
16+
Static(
17+
ExtractStaticStyle {
18+
property: "border-radius",
19+
value: "16px",
20+
level: 0,
21+
selector: None,
22+
style_order: None,
23+
},
24+
),
25+
Static(
26+
ExtractStaticStyle {
27+
property: "color",
28+
value: "white",
29+
level: 0,
30+
selector: None,
31+
style_order: None,
32+
},
33+
),
34+
Static(
35+
ExtractStaticStyle {
36+
property: "cursor",
37+
value: "pointer",
38+
level: 0,
39+
selector: None,
40+
style_order: None,
41+
},
42+
),
43+
Static(
44+
ExtractStaticStyle {
45+
property: "padding",
46+
value: "48px",
47+
level: 0,
48+
selector: None,
49+
style_order: None,
50+
},
51+
),
52+
Static(
53+
ExtractStaticStyle {
54+
property: "transition",
55+
value: "all .2s",
56+
level: 0,
57+
selector: None,
58+
style_order: None,
59+
},
60+
),
61+
},
62+
code: "import \"@devup-ui/react/devup-ui.css\";\nconst base = \"a b\";\nexport const button = \"a b c d e f\";\nconst interactive = \"c d\";\n",
863
}

libs/extractor/src/snapshots/extractor__tests__vanilla_extract_container.snap

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,40 @@ source: libs/extractor/src/lib.rs
33
expression: "ToBTreeSet::from(extract(\"container.css.ts\",\nr#\"import { createContainer, style } from '@devup-ui/react'\nexport const sidebar = createContainer()\nexport const sidebarContainer = style({\n containerName: sidebar,\n containerType: 'inline-size'\n})\nexport const responsive = style({\n '@container': {\n [`${sidebar} (min-width: 400px)`]: {\n flexDirection: 'row'\n }\n }\n})\n\"#,\nExtractOption\n{\n package: \"@devup-ui/react\".to_string(), css_dir:\n \"@devup-ui/react\".to_string(), single_css: true, import_main_css: false\n}).unwrap())"
44
---
55
ToBTreeSet {
6-
styles: {},
7-
code: "import { createContainer, style } from \"@devup-ui/react\";\nexport const sidebar = createContainer();\nexport const sidebarContainer = style({\n\tcontainerName: sidebar,\n\tcontainerType: \"inline-size\"\n});\nexport const responsive = style({ \"@container\": { [`${sidebar} (min-width: 400px)`]: { flexDirection: \"row\" } } });\n",
6+
styles: {
7+
Static(
8+
ExtractStaticStyle {
9+
property: "container-name",
10+
value: "__container_0__",
11+
level: 0,
12+
selector: None,
13+
style_order: None,
14+
},
15+
),
16+
Static(
17+
ExtractStaticStyle {
18+
property: "container-type",
19+
value: "inline-size",
20+
level: 0,
21+
selector: None,
22+
style_order: None,
23+
},
24+
),
25+
Static(
26+
ExtractStaticStyle {
27+
property: "flex-direction",
28+
value: "row",
29+
level: 0,
30+
selector: Some(
31+
At {
32+
kind: Container,
33+
query: "__container_0__ (min-width: 400px)",
34+
selector: None,
35+
},
36+
),
37+
style_order: None,
38+
},
39+
),
40+
},
41+
code: "import \"@devup-ui/react/devup-ui.css\";\nexport const responsive = \"a\";\nexport const sidebarContainer = \"b c\";\nexport const sidebar = \"__container_0__\";\n",
842
}

libs/extractor/src/snapshots/extractor__tests__vanilla_extract_create_var-2.snap

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@ source: libs/extractor/src/lib.rs
33
expression: "ToBTreeSet::from(extract(\"fallback.css.ts\",\nr#\"import { createVar, fallbackVar, style } from '@devup-ui/react'\nexport const colorVar = createVar()\nexport const box = style({\n color: fallbackVar(colorVar, 'red')\n})\n\"#,\nExtractOption\n{\n package: \"@devup-ui/react\".to_string(), css_dir:\n \"@devup-ui/react\".to_string(), single_css: true, import_main_css: false\n}).unwrap())"
44
---
55
ToBTreeSet {
6-
styles: {},
7-
code: "import { createVar, fallbackVar, style } from \"@devup-ui/react\";\nexport const colorVar = createVar();\nexport const box = style({ color: fallbackVar(colorVar, \"red\") });\n",
6+
styles: {
7+
Static(
8+
ExtractStaticStyle {
9+
property: "color",
10+
value: "var(--var0,red)",
11+
level: 0,
12+
selector: None,
13+
style_order: None,
14+
},
15+
),
16+
},
17+
code: "import \"@devup-ui/react/devup-ui.css\";\nexport const box = \"a\";\nexport const colorVar = \"--var-0\";\n",
818
}

libs/extractor/src/snapshots/extractor__tests__vanilla_extract_create_var.snap

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,25 @@ source: libs/extractor/src/lib.rs
33
expression: "ToBTreeSet::from(extract(\"vars.css.ts\",\nr#\"import { createVar, style } from '@devup-ui/react'\nexport const colorVar = createVar()\nexport const box = style({\n vars: {\n [colorVar]: 'blue'\n },\n color: colorVar\n})\n\"#,\nExtractOption\n{\n package: \"@devup-ui/react\".to_string(), css_dir:\n \"@devup-ui/react\".to_string(), single_css: true, import_main_css: false\n}).unwrap())"
44
---
55
ToBTreeSet {
6-
styles: {},
7-
code: "import { createVar, style } from \"@devup-ui/react\";\nexport const colorVar = createVar();\nexport const box = style({\n\tvars: { [colorVar]: \"blue\" },\n\tcolor: colorVar\n});\n",
6+
styles: {
7+
Static(
8+
ExtractStaticStyle {
9+
property: "color",
10+
value: "var(--var0)",
11+
level: 0,
12+
selector: None,
13+
style_order: None,
14+
},
15+
),
16+
Static(
17+
ExtractStaticStyle {
18+
property: "var(--var-0)",
19+
value: "blue",
20+
level: 0,
21+
selector: None,
22+
style_order: None,
23+
},
24+
),
25+
},
26+
code: "import \"@devup-ui/react/devup-ui.css\";\nexport const box = \"a b\";\nexport const colorVar = \"--var-0\";\n",
827
}

libs/extractor/src/snapshots/extractor__tests__vanilla_extract_font_face-2.snap

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@ source: libs/extractor/src/lib.rs
33
expression: "ToBTreeSet::from(extract(\"fonts-multi.css.ts\",\nr#\"import { fontFace, style } from '@devup-ui/react'\nconst roboto = fontFace({\n src: 'url(\"/fonts/Roboto.woff2\") format(\"woff2\")',\n fontWeight: 400,\n fontStyle: 'normal'\n})\nexport const body = style({\n fontFamily: roboto\n})\n\"#,\nExtractOption\n{\n package: \"@devup-ui/react\".to_string(), css_dir:\n \"@devup-ui/react\".to_string(), single_css: true, import_main_css: false\n}).unwrap())"
44
---
55
ToBTreeSet {
6-
styles: {},
7-
code: "import { fontFace, style } from \"@devup-ui/react\";\nconst roboto = fontFace({\n\tsrc: \"url(\\\"/fonts/Roboto.woff2\\\") format(\\\"woff2\\\")\",\n\tfontWeight: 400,\n\tfontStyle: \"normal\"\n});\nexport const body = style({ fontFamily: roboto });\n",
6+
styles: {
7+
Static(
8+
ExtractStaticStyle {
9+
property: "font-family",
10+
value: "__font_1__",
11+
level: 0,
12+
selector: None,
13+
style_order: None,
14+
},
15+
),
16+
},
17+
code: "import \"@devup-ui/react/devup-ui.css\";\nconst roboto = \"a\";\n",
818
}

libs/extractor/src/snapshots/extractor__tests__vanilla_extract_font_face.snap

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@ source: libs/extractor/src/lib.rs
33
expression: "ToBTreeSet::from(extract(\"fonts.css.ts\",\nr#\"import { fontFace, style } from '@devup-ui/react'\nconst myFont = fontFace({\n src: 'local(\"Comic Sans MS\")'\n})\nexport const text = style({\n fontFamily: myFont\n})\n\"#,\nExtractOption\n{\n package: \"@devup-ui/react\".to_string(), css_dir:\n \"@devup-ui/react\".to_string(), single_css: true, import_main_css: false\n}).unwrap())"
44
---
55
ToBTreeSet {
6-
styles: {},
7-
code: "import { fontFace, style } from \"@devup-ui/react\";\nconst myFont = fontFace({ src: \"local(\\\"Comic Sans MS\\\")\" });\nexport const text = style({ fontFamily: myFont });\n",
6+
styles: {
7+
Static(
8+
ExtractStaticStyle {
9+
property: "font-family",
10+
value: "__font_1__",
11+
level: 0,
12+
selector: None,
13+
style_order: None,
14+
},
15+
),
16+
},
17+
code: "import \"@devup-ui/react/devup-ui.css\";\nconst myFont = \"a\";\n",
818
}

libs/extractor/src/snapshots/extractor__tests__vanilla_extract_global_theme.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ expression: "ToBTreeSet::from(extract(\"global-theme.css.ts\",\nr#\"import { cre
44
---
55
ToBTreeSet {
66
styles: {},
7-
code: "import { createGlobalTheme } from \"@devup-ui/react\";\nexport const vars = createGlobalTheme(\":root\", {\n\tcolor: {\n\t\tbrand: \"blue\",\n\t\ttext: \"black\",\n\t\tbackground: \"white\"\n\t},\n\tfont: { body: \"system-ui, sans-serif\" }\n});\n",
7+
code: "export const vars = createGlobalTheme(\":root\", {\n\tcolor: {\n\t\tbrand: \"blue\",\n\t\ttext: \"black\",\n\t\tbackground: \"white\"\n\t},\n\tfont: { body: \"system-ui, sans-serif\" }\n});\n",
88
}

libs/extractor/src/snapshots/extractor__tests__vanilla_extract_layer.snap

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,55 @@ source: libs/extractor/src/lib.rs
33
expression: "ToBTreeSet::from(extract(\"layers.css.ts\",\nr#\"import { layer, style, globalStyle } from '@devup-ui/react'\nexport const reset = layer('reset')\nexport const base = layer('base')\nexport const components = layer('components')\nglobalStyle('*', {\n '@layer': reset,\n margin: 0,\n padding: 0\n})\n\"#,\nExtractOption\n{\n package: \"@devup-ui/react\".to_string(), css_dir:\n \"@devup-ui/react\".to_string(), single_css: true, import_main_css: false\n}).unwrap())"
44
---
55
ToBTreeSet {
6-
styles: {},
7-
code: "import { layer, style, globalStyle } from \"@devup-ui/react\";\nexport const reset = layer(\"reset\");\nexport const base = layer(\"base\");\nexport const components = layer(\"components\");\nglobalStyle(\"*\", {\n\t\"@layer\": reset,\n\tmargin: 0,\n\tpadding: 0\n});\n",
6+
styles: {
7+
Static(
8+
ExtractStaticStyle {
9+
property: "@layer",
10+
value: "reset",
11+
level: 0,
12+
selector: Some(
13+
Global(
14+
"*",
15+
"layers.css.ts",
16+
),
17+
),
18+
style_order: Some(
19+
0,
20+
),
21+
},
22+
),
23+
Static(
24+
ExtractStaticStyle {
25+
property: "margin",
26+
value: "0",
27+
level: 0,
28+
selector: Some(
29+
Global(
30+
"*",
31+
"layers.css.ts",
32+
),
33+
),
34+
style_order: Some(
35+
0,
36+
),
37+
},
38+
),
39+
Static(
40+
ExtractStaticStyle {
41+
property: "padding",
42+
value: "0",
43+
level: 0,
44+
selector: Some(
45+
Global(
46+
"*",
47+
"layers.css.ts",
48+
),
49+
),
50+
style_order: Some(
51+
0,
52+
),
53+
},
54+
),
55+
},
56+
code: "import \"@devup-ui/react/devup-ui.css\";\n;\nexport const base = \"base\";\nexport const components = \"components\";\nexport const reset = \"reset\";\n",
857
}

libs/extractor/src/snapshots/extractor__tests__vanilla_extract_media_queries.snap

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,76 @@ source: libs/extractor/src/lib.rs
33
expression: "ToBTreeSet::from(extract(\"media.css.ts\",\nr#\"import { style } from '@devup-ui/react'\nexport const responsive = style({\n display: 'block',\n '@media': {\n 'screen and (min-width: 768px)': {\n display: 'flex'\n },\n 'screen and (min-width: 1024px)': {\n display: 'grid'\n },\n '(prefers-color-scheme: dark)': {\n background: 'black',\n color: 'white'\n }\n }\n})\n\"#,\nExtractOption\n{\n package: \"@devup-ui/react\".to_string(), css_dir:\n \"@devup-ui/react\".to_string(), single_css: true, import_main_css: false\n}).unwrap())"
44
---
55
ToBTreeSet {
6-
styles: {},
7-
code: "import { style } from \"@devup-ui/react\";\nexport const responsive = style({\n\tdisplay: \"block\",\n\t\"@media\": {\n\t\t\"screen and (min-width: 768px)\": { display: \"flex\" },\n\t\t\"screen and (min-width: 1024px)\": { display: \"grid\" },\n\t\t\"(prefers-color-scheme: dark)\": {\n\t\t\tbackground: \"black\",\n\t\t\tcolor: \"white\"\n\t\t}\n\t}\n});\n",
6+
styles: {
7+
Static(
8+
ExtractStaticStyle {
9+
property: "background",
10+
value: "black",
11+
level: 0,
12+
selector: Some(
13+
At {
14+
kind: Media,
15+
query: "(prefers-color-scheme: dark)",
16+
selector: None,
17+
},
18+
),
19+
style_order: None,
20+
},
21+
),
22+
Static(
23+
ExtractStaticStyle {
24+
property: "color",
25+
value: "white",
26+
level: 0,
27+
selector: Some(
28+
At {
29+
kind: Media,
30+
query: "(prefers-color-scheme: dark)",
31+
selector: None,
32+
},
33+
),
34+
style_order: None,
35+
},
36+
),
37+
Static(
38+
ExtractStaticStyle {
39+
property: "display",
40+
value: "block",
41+
level: 0,
42+
selector: None,
43+
style_order: None,
44+
},
45+
),
46+
Static(
47+
ExtractStaticStyle {
48+
property: "display",
49+
value: "flex",
50+
level: 0,
51+
selector: Some(
52+
At {
53+
kind: Media,
54+
query: "screen and (min-width: 768px)",
55+
selector: None,
56+
},
57+
),
58+
style_order: None,
59+
},
60+
),
61+
Static(
62+
ExtractStaticStyle {
63+
property: "display",
64+
value: "grid",
65+
level: 0,
66+
selector: Some(
67+
At {
68+
kind: Media,
69+
query: "screen and (min-width: 1024px)",
70+
selector: None,
71+
},
72+
),
73+
style_order: None,
74+
},
75+
),
76+
},
77+
code: "import \"@devup-ui/react/devup-ui.css\";\nexport const responsive = \"a b c d e\";\n",
878
}

0 commit comments

Comments
 (0)