Skip to content

Commit 118417a

Browse files
committed
Add ve case
1 parent 0533b5d commit 118417a

File tree

30 files changed

+3087
-39
lines changed

30 files changed

+3087
-39
lines changed

Cargo.lock

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

libs/extractor/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,14 @@ oxc_allocator = "0.106.0"
1111
oxc_ast = "0.106.0"
1212
oxc_ast_visit = "0.106.0"
1313
oxc_codegen = "0.106.0"
14+
oxc_transformer = "0.106.0"
15+
oxc_semantic = "0.106.0"
1416
css = { path = "../css" }
1517
phf = "0.13"
1618
strum = "0.27.2"
1719
strum_macros = "0.27.2"
20+
serde_json = "1.0"
21+
boa_engine = "0.20"
1822

1923
[dev-dependencies]
2024
insta = "1.45.1"

libs/extractor/src/lib.rs

Lines changed: 94 additions & 25 deletions
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
}
@@ -9020,9 +9055,8 @@ const margin = 5;
90209055
));
90219056
}
90229057

9023-
/*
90249058
// ============================================================================
9025-
// VANILLA-EXTRACT API TESTS (commented out until style/globalStyle support)
9059+
// VANILLA-EXTRACT API TESTS
90269060
// ============================================================================
90279061

90289062
/// Test vanilla-extract style files (.css.ts, .css.js)
@@ -9036,7 +9070,7 @@ const margin = 5;
90369070
extract(
90379071
"styles.css.ts",
90389072
r#"import { style } from '@devup-ui/react'
9039-
export const container = style({ background: "red", padding: 16 })
9073+
export const container: string = style({ background: "red", padding: 16 })
90409074
"#,
90419075
ExtractOption {
90429076
package: "@devup-ui/react".to_string(),
@@ -9047,14 +9081,18 @@ export const container = style({ background: "red", padding: 16 })
90479081
)
90489082
.unwrap()
90499083
));
9084+
}
90509085

9086+
#[test]
9087+
#[serial]
9088+
fn test_vanilla_extract_style_css_js() {
90519089
reset_class_map();
9052-
// .css.ts file with style function using camelCase CSS properties
9090+
// .css.js file with style function
90539091
assert_debug_snapshot!(ToBTreeSet::from(
90549092
extract(
9055-
"button.css.ts",
9093+
"styles.css.js",
90569094
r#"import { style } from '@devup-ui/react'
9057-
export const button = style({ backgroundColor: "blue", color: "white", padding: 8 })
9095+
export const wrapper = style({ backgroundColor: "white", margin: 8 })
90589096
"#,
90599097
ExtractOption {
90609098
package: "@devup-ui/react".to_string(),
@@ -9067,14 +9105,12 @@ export const button = style({ backgroundColor: "blue", color: "white", padding:
90679105
));
90689106

90699107
reset_class_map();
9070-
// .css.ts file with multiple style exports
9108+
// .css.js file with style function for link
90719109
assert_debug_snapshot!(ToBTreeSet::from(
90729110
extract(
9073-
"theme.css.ts",
9111+
"components.css.js",
90749112
r#"import { style } from '@devup-ui/react'
9075-
export const primaryButton = style({ backgroundColor: "blue", color: "white" })
9076-
export const secondaryButton = style({ backgroundColor: "gray", color: "black" })
9077-
export const card = style({ padding: 16, borderRadius: "8px" })
9113+
export const link = style({ color: "blue", textDecoration: "underline" })
90789114
"#,
90799115
ExtractOption {
90809116
package: "@devup-ui/react".to_string(),
@@ -9089,14 +9125,16 @@ export const card = style({ padding: 16, borderRadius: "8px" })
90899125

90909126
#[test]
90919127
#[serial]
9092-
fn test_vanilla_extract_style_css_js() {
9128+
fn test_vanilla_extract_with_variable() {
90939129
reset_class_map();
9094-
// .css.js file with style function
9130+
// Variables should be evaluated at execution time
90959131
assert_debug_snapshot!(ToBTreeSet::from(
90969132
extract(
9097-
"styles.css.js",
9133+
"vars.css.ts",
90989134
r#"import { style } from '@devup-ui/react'
9099-
export const wrapper = style({ backgroundColor: "white", margin: 8 })
9135+
const primaryColor = "blue";
9136+
const spacing = 16;
9137+
export const button = style({ background: primaryColor, padding: spacing })
91009138
"#,
91019139
ExtractOption {
91029140
package: "@devup-ui/react".to_string(),
@@ -9107,14 +9145,19 @@ export const wrapper = style({ backgroundColor: "white", margin: 8 })
91079145
)
91089146
.unwrap()
91099147
));
9148+
}
91109149

9150+
#[test]
9151+
#[serial]
9152+
fn test_vanilla_extract_with_computed() {
91119153
reset_class_map();
9112-
// .css.js file with style function for link
9154+
// Computed values should be evaluated
91139155
assert_debug_snapshot!(ToBTreeSet::from(
91149156
extract(
9115-
"components.css.js",
9157+
"computed.css.ts",
91169158
r#"import { style } from '@devup-ui/react'
9117-
export const link = style({ color: "blue", textDecoration: "underline" })
9159+
const base = 8;
9160+
export const box = style({ padding: base * 2, margin: base / 2 })
91189161
"#,
91199162
ExtractOption {
91209163
package: "@devup-ui/react".to_string(),
@@ -9129,14 +9172,15 @@ export const link = style({ color: "blue", textDecoration: "underline" })
91299172

91309173
#[test]
91319174
#[serial]
9132-
fn test_vanilla_extract_with_responsive_and_pseudo() {
9175+
fn test_vanilla_extract_with_spread() {
91339176
reset_class_map();
9134-
// .css.ts file with responsive values (devup-ui extension)
9177+
// Spread operator should work
91359178
assert_debug_snapshot!(ToBTreeSet::from(
91369179
extract(
9137-
"responsive.css.ts",
9180+
"spread.css.ts",
91389181
r#"import { style } from '@devup-ui/react'
9139-
export const responsiveBox = style({ padding: [8, 16, 32], display: ["block", "flex"] })
9182+
const baseStyle = { padding: 8, margin: 4 };
9183+
export const extended = style({ ...baseStyle, background: "red" })
91409184
"#,
91419185
ExtractOption {
91429186
package: "@devup-ui/react".to_string(),
@@ -9147,9 +9191,13 @@ export const responsiveBox = style({ padding: [8, 16, 32], display: ["block", "f
91479191
)
91489192
.unwrap()
91499193
));
9194+
}
91509195

9196+
#[test]
9197+
#[serial]
9198+
fn test_vanilla_extract_with_pseudo_selector() {
91519199
reset_class_map();
9152-
// .css.ts file with selectors (vanilla-extract style)
9200+
// devup-ui extension: _hover pseudo selector
91539201
assert_debug_snapshot!(ToBTreeSet::from(
91549202
extract(
91559203
"hover.css.ts",
@@ -9167,6 +9215,28 @@ export const hoverButton = style({ background: "gray", _hover: { background: "bl
91679215
));
91689216
}
91699217

9218+
#[test]
9219+
#[serial]
9220+
fn test_vanilla_extract_with_responsive_array() {
9221+
reset_class_map();
9222+
// devup-ui extension: responsive arrays
9223+
assert_debug_snapshot!(ToBTreeSet::from(
9224+
extract(
9225+
"responsive.css.ts",
9226+
r#"import { style } from '@devup-ui/react'
9227+
export const responsiveBox = style({ padding: [8, 16, 32] })
9228+
"#,
9229+
ExtractOption {
9230+
package: "@devup-ui/react".to_string(),
9231+
css_dir: "@devup-ui/react".to_string(),
9232+
single_css: true,
9233+
import_main_css: false
9234+
}
9235+
)
9236+
.unwrap()
9237+
));
9238+
}
9239+
91709240
#[test]
91719241
#[serial]
91729242
fn test_vanilla_extract_with_keyframes_and_global() {
@@ -9687,7 +9757,6 @@ export const grid = style({
96879757
.unwrap()
96889758
));
96899759
}
9690-
*/
96919760
// END VANILLA-EXTRACT API TESTS
96929761

96939762
#[rstest]
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
---
2+
source: libs/extractor/src/lib.rs
3+
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())"
4+
---
5+
ToBTreeSet {
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",
63+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
source: libs/extractor/src/lib.rs
3+
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())"
4+
---
5+
ToBTreeSet {
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+
Selector(
32+
"&:_container_0__ (min-width: 400px)",
33+
),
34+
),
35+
style_order: None,
36+
},
37+
),
38+
},
39+
code: "import \"@devup-ui/react/devup-ui.css\";\nexport const responsive = \"a\";\nexport const sidebarContainer = \"b c\";\nexport const sidebar = \"__container_0__\";\n",
40+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
source: libs/extractor/src/lib.rs
3+
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())"
4+
---
5+
ToBTreeSet {
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",
18+
}

0 commit comments

Comments
 (0)