diff --git a/.changeset/silver-teeth-stand.md b/.changeset/silver-teeth-stand.md
new file mode 100644
index 00000000..e11dba5e
--- /dev/null
+++ b/.changeset/silver-teeth-stand.md
@@ -0,0 +1,5 @@
+---
+"@devup-ui/wasm": patch
+---
+
+Fix className
diff --git a/libs/extractor/src/lib.rs b/libs/extractor/src/lib.rs
index 7dc9233a..02764c56 100644
--- a/libs/extractor/src/lib.rs
+++ b/libs/extractor/src/lib.rs
@@ -2673,6 +2673,45 @@ e(o, { className: "a", bg: variable, style: { color: "blue" }, ...props })
));
}
+ #[test]
+ #[serial]
+ fn props_multi_expression() {
+ reset_class_map();
+ assert_debug_snapshot!(ToBTreeSet::from(
+ extract(
+ "test.jsx",
+ r#"import {
+ Box,
+ Button as DevupButton,
+ Center,
+ css,
+} from '@devup-ui/core'
+
+
+"#,
+ ExtractOption {
+ package: "@devup-ui/core".to_string(),
+ css_file: None
+ }
+ )
+ .unwrap()
+ ));
+ }
+
#[test]
#[serial]
fn props_direct_object_select() {
@@ -3161,6 +3200,40 @@ import {Button} from '@devup/ui'
)
.unwrap()
));
+
+ reset_class_map();
+ assert_debug_snapshot!(ToBTreeSet::from(
+ extract(
+ "test.jsx",
+ r#"import {Box} from '@devup-ui/core'
+
+ "#,
+ ExtractOption {
+ package: "@devup-ui/core".to_string(),
+ css_file: None
+ }
+ )
+ .unwrap()
+ ));
+
+ reset_class_map();
+ assert_debug_snapshot!(ToBTreeSet::from(
+ extract(
+ "test.jsx",
+ r#"import {Box} from '@devup-ui/core'
+
+ "#,
+ ExtractOption {
+ package: "@devup-ui/core".to_string(),
+ css_file: None
+ }
+ )
+ .unwrap()
+ ));
}
#[test]
diff --git a/libs/extractor/src/prop_modify_utils.rs b/libs/extractor/src/prop_modify_utils.rs
index e653403f..16290ea8 100644
--- a/libs/extractor/src/prop_modify_utils.rs
+++ b/libs/extractor/src/prop_modify_utils.rs
@@ -233,7 +233,12 @@ fn merge_string_expressions<'a>(
if expressions.is_empty() {
return None;
}
- if expressions.len() == 1 {
+ if expressions.len() == 1
+ && !matches!(
+ expressions.first().unwrap(),
+ Expression::StringLiteral(_) | Expression::TemplateLiteral(_)
+ )
+ {
return Some(expressions.first().unwrap().clone_in(ast_builder.allocator));
}
@@ -241,41 +246,70 @@ fn merge_string_expressions<'a>(
let mut other_expressions = vec![];
let mut prev_str = String::new();
for (idx, ex) in expressions.iter().enumerate() {
- if let Expression::StringLiteral(literal) = ex {
- if !prev_str.trim().is_empty() {
- prev_str.push(' ');
+ match ex {
+ Expression::StringLiteral(literal) => {
+ prev_str.push_str(
+ format!(
+ "{}{}",
+ if prev_str.trim().is_empty() && other_expressions.is_empty() {
+ ""
+ } else {
+ " "
+ },
+ literal.value.trim()
+ )
+ .as_str(),
+ );
}
- prev_str.push_str(literal.value.trim());
- } else if let Expression::TemplateLiteral(template) = ex {
- for (idx, q) in template.quasis.iter().enumerate() {
- if idx == 0 {
- if !prev_str.trim().is_empty() {
- prev_str.push(' ');
- }
- prev_str.push_str(&q.value.raw);
- } else {
- if !prev_str.trim().is_empty() {
- string_literals.push(prev_str.clone());
- }
- if q.tail {
- prev_str = format!("{} ", q.value.raw);
+ Expression::TemplateLiteral(template) => {
+ for (idx, q) in template.quasis.iter().enumerate() {
+ if !prev_str.is_empty() {
+ string_literals.push(format!(
+ "{}{}{}{}",
+ prev_str.trim(),
+ if !prev_str.trim().is_empty() { " " } else { "" },
+ q.value.raw.trim(),
+ if idx == template.quasis.len() - 1 {
+ ""
+ } else {
+ " "
+ }
+ ));
+ prev_str = String::new();
+ } else if q.tail {
+ prev_str = q.value.raw.trim().to_string();
} else {
- string_literals.push(q.value.raw.into());
+ string_literals.push(format!(
+ "{}{}{}",
+ if idx == 0
+ && other_expressions.is_empty()
+ && string_literals.is_empty()
+ {
+ ""
+ } else {
+ " "
+ },
+ q.value.raw.trim(),
+ if q.value.raw.trim().is_empty() || !q.value.raw.ends_with(' ') {
+ ""
+ } else {
+ " "
+ }
+ ));
prev_str = String::new();
}
}
+ other_expressions.extend(template.expressions.clone_in(ast_builder.allocator));
}
- other_expressions.extend(template.expressions.clone_in(ast_builder.allocator));
- } else {
- if !prev_str.ends_with(' ') {
- string_literals.push(format!("{}{}", prev_str, if idx > 0 { " " } else { "" }));
- } else if idx > 0 {
- string_literals.push(" ".to_string());
- } else {
- string_literals.push("".to_string());
+ ex => {
+ string_literals.push(format!(
+ "{}{}",
+ prev_str.trim(),
+ if idx > 0 { " " } else { "" }
+ ));
+ other_expressions.push(ex.clone_in(ast_builder.allocator));
+ prev_str = String::new();
}
- other_expressions.push(ex.clone_in(ast_builder.allocator));
- prev_str = " ".to_string();
}
}
if !prev_str.is_empty() {
diff --git a/libs/extractor/src/snapshots/extractor__tests__props_multi_expression.snap b/libs/extractor/src/snapshots/extractor__tests__props_multi_expression.snap
new file mode 100644
index 00000000..0fbb58e2
--- /dev/null
+++ b/libs/extractor/src/snapshots/extractor__tests__props_multi_expression.snap
@@ -0,0 +1,81 @@
+---
+source: libs/extractor/src/lib.rs
+expression: "ToBTreeSet::from(extract(\"test.jsx\",\nr#\"import {\n Box,\n Button as DevupButton,\n Center,\n css,\n} from '@devup-ui/core'\n\n\n\"#,\nExtractOption\n{ package: \"@devup-ui/core\".to_string(), css_file: None }).unwrap())"
+---
+ToBTreeSet {
+ styles: {
+ Static(
+ ExtractStaticStyle {
+ property: "border",
+ value: "1px solid var(--border,#E4E4E4)",
+ level: 0,
+ selector: None,
+ style_order: None,
+ },
+ ),
+ Static(
+ ExtractStaticStyle {
+ property: "border",
+ value: "none",
+ level: 0,
+ selector: None,
+ style_order: None,
+ },
+ ),
+ Static(
+ ExtractStaticStyle {
+ property: "px",
+ value: "12px",
+ level: 0,
+ selector: None,
+ style_order: None,
+ },
+ ),
+ Static(
+ ExtractStaticStyle {
+ property: "px",
+ value: "16px",
+ level: 0,
+ selector: None,
+ style_order: None,
+ },
+ ),
+ Static(
+ ExtractStaticStyle {
+ property: "px",
+ value: "20px",
+ level: 0,
+ selector: None,
+ style_order: None,
+ },
+ ),
+ Static(
+ ExtractStaticStyle {
+ property: "px",
+ value: "24px",
+ level: 0,
+ selector: None,
+ style_order: None,
+ },
+ ),
+ Static(
+ ExtractStaticStyle {
+ property: "px",
+ value: "28px",
+ level: 0,
+ selector: None,
+ style_order: None,
+ },
+ ),
+ Static(
+ ExtractStaticStyle {
+ property: "px",
+ value: "32px",
+ level: 0,
+ selector: None,
+ style_order: None,
+ },
+ ),
+ },
+ code: "import \"@devup-ui/core/devup-ui.css\";\n;\n",
+}
diff --git a/libs/extractor/src/snapshots/extractor__tests__template_literal_props-5.snap b/libs/extractor/src/snapshots/extractor__tests__template_literal_props-5.snap
new file mode 100644
index 00000000..7001e39a
--- /dev/null
+++ b/libs/extractor/src/snapshots/extractor__tests__template_literal_props-5.snap
@@ -0,0 +1,8 @@
+---
+source: libs/extractor/src/lib.rs
+expression: "ToBTreeSet::from(extract(\"test.jsx\",\nr#\"import {Box} from '@devup-ui/core'\n \n \"#,\nExtractOption\n{ package: \"@devup-ui/core\".to_string(), css_file: None }).unwrap())"
+---
+ToBTreeSet {
+ styles: {},
+ code: "
;\n",
+}
diff --git a/libs/extractor/src/snapshots/extractor__tests__template_literal_props-6.snap b/libs/extractor/src/snapshots/extractor__tests__template_literal_props-6.snap
new file mode 100644
index 00000000..4d8da554
--- /dev/null
+++ b/libs/extractor/src/snapshots/extractor__tests__template_literal_props-6.snap
@@ -0,0 +1,35 @@
+---
+source: libs/extractor/src/lib.rs
+expression: "ToBTreeSet::from(extract(\"test.jsx\",\nr#\"import {Box} from '@devup-ui/core'\n \n \"#,\nExtractOption\n{ package: \"@devup-ui/core\".to_string(), css_file: None }).unwrap())"
+---
+ToBTreeSet {
+ styles: {
+ Static(
+ ExtractStaticStyle {
+ property: "background",
+ value: "black",
+ level: 0,
+ selector: Some(
+ Selector(
+ ":root[data-theme=dark] &:hover",
+ ),
+ ),
+ style_order: None,
+ },
+ ),
+ Static(
+ ExtractStaticStyle {
+ property: "background",
+ value: "red",
+ level: 0,
+ selector: Some(
+ Selector(
+ "&:hover",
+ ),
+ ),
+ style_order: None,
+ },
+ ),
+ },
+ code: "import \"@devup-ui/core/devup-ui.css\";\n;\n",
+}