diff --git a/.changepacks/changepack_log_aGWCTsZEAqVKwqmGlTexZ.json b/.changepacks/changepack_log_aGWCTsZEAqVKwqmGlTexZ.json new file mode 100644 index 00000000..651f1dcc --- /dev/null +++ b/.changepacks/changepack_log_aGWCTsZEAqVKwqmGlTexZ.json @@ -0,0 +1,5 @@ +{ + "changes": { "bindings/devup-ui-wasm/package.json": "Patch" }, + "note": "Fix selectors normialized class when including underscore(_)", + "date": "2025-11-18T08:18:08.445637Z" +} diff --git a/libs/css/src/selector_separator.rs b/libs/css/src/selector_separator.rs index d64856ba..ff0f2116 100644 --- a/libs/css/src/selector_separator.rs +++ b/libs/css/src/selector_separator.rs @@ -5,6 +5,7 @@ use crate::constant::DOUBLE_SEPARATOR; pub enum SelectorSeparator { Single, Double, + Space, None, } impl Display for SelectorSeparator { @@ -15,6 +16,7 @@ impl Display for SelectorSeparator { match self { SelectorSeparator::Single => ":", SelectorSeparator::Double => "::", + SelectorSeparator::Space => " ", SelectorSeparator::None => "", } ) @@ -22,10 +24,16 @@ impl Display for SelectorSeparator { } impl From<&str> for SelectorSeparator { fn from(value: &str) -> Self { - if value.starts_with(":") || value.is_empty() || value.starts_with("[") { + if value.starts_with(":") + || value.is_empty() + || value.starts_with("[") + || value.starts_with(" ") + { SelectorSeparator::None } else if DOUBLE_SEPARATOR.contains(value) { SelectorSeparator::Double + } else if value.starts_with("#") || value.starts_with(".") || value.starts_with("*") { + SelectorSeparator::Space } else { SelectorSeparator::Single } diff --git a/libs/extractor/src/css_utils.rs b/libs/extractor/src/css_utils.rs index 3082ee6a..1ffe19ae 100644 --- a/libs/extractor/src/css_utils.rs +++ b/libs/extractor/src/css_utils.rs @@ -149,24 +149,20 @@ pub fn optimize_css_block(css: &str) -> String { .join("}") .split(";") .map(|s| { - println!("s: {}", s); let parts = s.split("{").collect::>(); let first_part = if parts.len() == 1 { "".to_string() } else { format!("{}{{", parts.first().unwrap().trim()) }; - println!("first_part: {}", first_part); let last_part = parts.last().unwrap().trim(); if !last_part.contains(":") { - println!("last_part: {}", last_part); format!("{first_part}{last_part}") } else { let mut iter = last_part.split(":"); let property = iter.next().unwrap().trim(); let value = iter.next().unwrap().trim(); - println!("property: {}, value: {}", property, value); let value = if check_multi_css_optimize(property.split("{").last().unwrap()) { optimize_mutli_css_value(value) } else { diff --git a/libs/extractor/src/extractor/extract_style_from_expression.rs b/libs/extractor/src/extractor/extract_style_from_expression.rs index ee6d97db..650bda0f 100644 --- a/libs/extractor/src/extractor/extract_style_from_expression.rs +++ b/libs/extractor/src/extractor/extract_style_from_expression.rs @@ -204,14 +204,16 @@ pub fn extract_style_from_expression<'a>( if name.starts_with("_") { if name.starts_with("_theme") { StyleSelector::from([ - to_kebab_case(name.replace("_", "").as_str()).as_str(), + to_kebab_case(name.strip_prefix("_").unwrap_or(name)) + .as_str(), &selector.to_string(), ]) .to_string() } else { StyleSelector::from([ &selector.to_string(), - to_kebab_case(name.replace("_", "").as_str()).as_str(), + to_kebab_case(name.strip_prefix("_").unwrap_or(name)) + .as_str(), ]) .to_string() } @@ -219,10 +221,13 @@ pub fn extract_style_from_expression<'a>( name.replace("&", &selector.to_string()) } } else if name.starts_with("_") { - StyleSelector::from(to_kebab_case(&name.replace("_", "")).as_str()) - .to_string() + StyleSelector::from( + to_kebab_case(name.strip_prefix("_").unwrap_or(name)).as_str(), + ) + .to_string() } else { - StyleSelector::from(name.replace("_", "").as_str()).to_string() + StyleSelector::from(name.strip_prefix("_").unwrap_or(name)) + .to_string() } }) .collect::>() diff --git a/libs/extractor/src/lib.rs b/libs/extractor/src/lib.rs index 8f7e217c..db2b1b95 100644 --- a/libs/extractor/src/lib.rs +++ b/libs/extractor/src/lib.rs @@ -2289,6 +2289,27 @@ import clsx from 'clsx' ) .unwrap() )); + + reset_class_map(); + assert_debug_snapshot!(ToBTreeSet::from( + extract( + "test.tsx", + r#"import {Box} from '@devup-ui/core' + + "#, + ExtractOption { + package: "@devup-ui/core".to_string(), + css_dir: "@devup-ui/core".to_string(), + single_css: true, + import_main_css: false + } + ) + .unwrap() + )); } #[test] diff --git a/libs/extractor/src/snapshots/extractor__tests__extract_selector-13.snap b/libs/extractor/src/snapshots/extractor__tests__extract_selector-13.snap new file mode 100644 index 00000000..67f1a251 --- /dev/null +++ b/libs/extractor/src/snapshots/extractor__tests__extract_selector-13.snap @@ -0,0 +1,22 @@ +--- +source: libs/extractor/src/lib.rs +expression: "ToBTreeSet::from(extract(\"test.tsx\",\nr#\"import {Box} from '@devup-ui/core'\n \n \"#,\nExtractOption\n{\n package: \"@devup-ui/core\".to_string(), css_dir:\n \"@devup-ui/core\".to_string(), single_css: true, import_main_css: false\n}).unwrap())" +--- +ToBTreeSet { + styles: { + Static( + ExtractStaticStyle { + property: "background", + value: "$primary", + level: 0, + selector: Some( + Selector( + "& .test-picker__day--keyboard-selected", + ), + ), + style_order: None, + }, + ), + }, + code: "import \"@devup-ui/core/devup-ui.css\";\n
;\n", +}