Skip to content

Commit 91ae2cd

Browse files
authored
Merge pull request #495 from dev-five-git/fix-selector-issue-3
Fix selector issue 3
2 parents 5116241 + 225511a commit 91ae2cd

20 files changed

+449
-92
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"changes": { "bindings/devup-ui-wasm/package.json": "Patch" },
3+
"note": "Fix selector issue",
4+
"date": "2025-11-19T07:56:23.681473700Z"
5+
}

libs/css/src/style_selector.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,12 @@ impl Ord for StyleSelector {
6767
if c == Ordering::Equal { aa.cmp(bb) } else { c }
6868
}
6969
(StyleSelector::Selector(a), StyleSelector::Selector(b)) => {
70-
get_selector_order(a).cmp(&get_selector_order(b))
70+
let order_cmp = get_selector_order(a).cmp(&get_selector_order(b));
71+
if order_cmp == Ordering::Equal {
72+
a.cmp(b)
73+
} else {
74+
order_cmp
75+
}
7176
}
7277
(
7378
StyleSelector::Media {

libs/extractor/src/extractor/extract_style_from_expression.rs

Lines changed: 37 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -197,51 +197,47 @@ pub fn extract_style_from_expression<'a>(
197197
}
198198
}
199199

200-
let sel = part_of_selector
201-
.iter()
202-
.map(|name| {
203-
if let Some(selector) = selector {
204-
if name.starts_with("_") {
205-
if name.starts_with("_theme") {
206-
StyleSelector::from([
207-
to_kebab_case(name.strip_prefix("_").unwrap_or(name))
208-
.as_str(),
209-
&selector.to_string(),
210-
])
211-
.to_string()
212-
} else {
213-
StyleSelector::from([
214-
&selector.to_string(),
215-
to_kebab_case(name.strip_prefix("_").unwrap_or(name))
216-
.as_str(),
217-
])
218-
.to_string()
219-
}
200+
for sel in part_of_selector.iter().map(|name| {
201+
if let Some(selector) = selector {
202+
if name.starts_with("_") {
203+
if name.starts_with("_theme") {
204+
StyleSelector::from([
205+
to_kebab_case(name.strip_prefix("_").unwrap_or(name))
206+
.as_str(),
207+
&selector.to_string(),
208+
])
209+
.to_string()
220210
} else {
221-
name.replace("&", &selector.to_string())
211+
StyleSelector::from([
212+
&selector.to_string(),
213+
to_kebab_case(name.strip_prefix("_").unwrap_or(name))
214+
.as_str(),
215+
])
216+
.to_string()
222217
}
223-
} else if name.starts_with("_") {
224-
StyleSelector::from(
225-
to_kebab_case(name.strip_prefix("_").unwrap_or(name)).as_str(),
226-
)
227-
.to_string()
228218
} else {
229-
StyleSelector::from(name.strip_prefix("_").unwrap_or(name))
230-
.to_string()
219+
name.replace("&", &selector.to_string())
231220
}
232-
})
233-
.collect::<Vec<_>>()
234-
.join(",");
235-
props.extend(
236-
extract_style_from_expression(
237-
ast_builder,
238-
None,
239-
&mut o.value,
240-
level,
241-
&Some(StyleSelector::Selector(sel)),
242-
)
243-
.styles,
244-
);
221+
} else if name.starts_with("_") {
222+
StyleSelector::from(
223+
to_kebab_case(name.strip_prefix("_").unwrap_or(name)).as_str(),
224+
)
225+
.to_string()
226+
} else {
227+
StyleSelector::from(name.strip_prefix("_").unwrap_or(name)).to_string()
228+
}
229+
}) {
230+
props.extend(
231+
extract_style_from_expression(
232+
ast_builder,
233+
None,
234+
&mut o.value,
235+
level,
236+
&Some(StyleSelector::Selector(sel)),
237+
)
238+
.styles,
239+
);
240+
}
245241
}
246242
}
247243
return ExtractResult {

libs/extractor/src/lib.rs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2310,6 +2310,83 @@ import clsx from 'clsx'
23102310
)
23112311
.unwrap()
23122312
));
2313+
2314+
reset_class_map();
2315+
assert_debug_snapshot!(ToBTreeSet::from(
2316+
extract(
2317+
"test.tsx",
2318+
r#"import {Box} from '@devup-ui/core'
2319+
<Box selectors={{
2320+
"& .a, & .b": {
2321+
bg: "$primary"
2322+
}
2323+
}} />
2324+
"#,
2325+
ExtractOption {
2326+
package: "@devup-ui/core".to_string(),
2327+
css_dir: "@devup-ui/core".to_string(),
2328+
single_css: true,
2329+
import_main_css: false
2330+
}
2331+
)
2332+
.unwrap()
2333+
));
2334+
2335+
reset_class_map();
2336+
assert_debug_snapshot!(ToBTreeSet::from(
2337+
extract(
2338+
"test.tsx",
2339+
r#"import {Box} from '@devup-ui/core'
2340+
<Box selectors={{
2341+
".test-picker__day--keyboard-selected": {
2342+
_hover: {
2343+
bg: "$primary"
2344+
},
2345+
selectors: {
2346+
"&:active": {
2347+
bg: "$primary"
2348+
}
2349+
}
2350+
}
2351+
}} />
2352+
"#,
2353+
ExtractOption {
2354+
package: "@devup-ui/core".to_string(),
2355+
css_dir: "@devup-ui/core".to_string(),
2356+
single_css: true,
2357+
import_main_css: false
2358+
}
2359+
)
2360+
.unwrap()
2361+
));
2362+
2363+
reset_class_map();
2364+
assert_debug_snapshot!(ToBTreeSet::from(
2365+
extract(
2366+
"test.tsx",
2367+
r#"import {Box} from '@devup-ui/core'
2368+
<Box selectors={{
2369+
".a, .b": {
2370+
_hover: {
2371+
bg: "$primary"
2372+
},
2373+
selectors: {
2374+
"&:active": {
2375+
bg: "$secondary"
2376+
}
2377+
}
2378+
}
2379+
}} />
2380+
"#,
2381+
ExtractOption {
2382+
package: "@devup-ui/core".to_string(),
2383+
css_dir: "@devup-ui/core".to_string(),
2384+
single_css: true,
2385+
import_main_css: false
2386+
}
2387+
)
2388+
.unwrap()
2389+
));
23132390
}
23142391

23152392
#[test]
Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
source: libs/extractor/src/lib.rs
3-
expression: "ToBTreeSet::from(extract(\"test.tsx\",\nr#\"import {Box} from '@devup-ui/core'\n <Box \n selectors={{\n _hover: {\n selectors: {\n \"_themeDark,_active\": {\n color: \"red\",\n }\n }\n }\n }}\n />\n \"#,\nExtractOption\n{ package: \"@devup-ui/core\".to_string(), css_file: None }).unwrap())"
3+
expression: "ToBTreeSet::from(extract(\"test.tsx\",\nr#\"import {Box} from '@devup-ui/core'\n <Box \n selectors={{\n _hover: {\n selectors: {\n \"_themeDark,_active\": {\n color: \"red\",\n }\n }\n }\n }}\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())"
44
---
55
ToBTreeSet {
66
styles: {
@@ -11,12 +11,25 @@ ToBTreeSet {
1111
level: 0,
1212
selector: Some(
1313
Selector(
14-
":root[data-theme=dark] &:hover,&:hover:active",
14+
":root[data-theme=dark] &:hover",
15+
),
16+
),
17+
style_order: None,
18+
},
19+
),
20+
Static(
21+
ExtractStaticStyle {
22+
property: "color",
23+
value: "red",
24+
level: 0,
25+
selector: Some(
26+
Selector(
27+
"&:hover:active",
1528
),
1629
),
1730
style_order: None,
1831
},
1932
),
2033
},
21-
code: "import \"@devup-ui/core/devup-ui.css\";\n<div className=\"a\" />;\n",
34+
code: "import \"@devup-ui/core/devup-ui.css\";\n<div className=\"a b\" />;\n",
2235
}
Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
source: libs/extractor/src/lib.rs
3-
expression: "ToBTreeSet::from(extract(\"test.tsx\",\nr#\"import {Box} from '@devup-ui/core'\n <Box \n selectors={{\n _hover: {\n selectors: {\n \"_themeDark,_placeholder\": {\n color: \"red\",\n }\n }\n }\n }}\n />\n \"#,\nExtractOption\n{ package: \"@devup-ui/core\".to_string(), css_file: None }).unwrap())"
3+
expression: "ToBTreeSet::from(extract(\"test.tsx\",\nr#\"import {Box} from '@devup-ui/core'\n <Box \n selectors={{\n _hover: {\n selectors: {\n \"_themeDark,_placeholder\": {\n color: \"red\",\n }\n }\n }\n }}\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())"
44
---
55
ToBTreeSet {
66
styles: {
@@ -11,12 +11,25 @@ ToBTreeSet {
1111
level: 0,
1212
selector: Some(
1313
Selector(
14-
":root[data-theme=dark] &:hover,&:hover::placeholder",
14+
":root[data-theme=dark] &:hover",
15+
),
16+
),
17+
style_order: None,
18+
},
19+
),
20+
Static(
21+
ExtractStaticStyle {
22+
property: "color",
23+
value: "red",
24+
level: 0,
25+
selector: Some(
26+
Selector(
27+
"&:hover::placeholder",
1528
),
1629
),
1730
style_order: None,
1831
},
1932
),
2033
},
21-
code: "import \"@devup-ui/core/devup-ui.css\";\n<div className=\"a\" />;\n",
34+
code: "import \"@devup-ui/core/devup-ui.css\";\n<div className=\"a b\" />;\n",
2235
}
Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
source: libs/extractor/src/lib.rs
3-
expression: "ToBTreeSet::from(extract(\"test.tsx\",\nr#\"import {Box} from '@devup-ui/core'\n <Box _hover={{\n selectors: {\n \"&::placeholder, &:active\": {\n color: \"blue\"\n }\n },\n }} />\n \"#,\nExtractOption\n{ package: \"@devup-ui/core\".to_string(), css_file: None }).unwrap())"
3+
expression: "ToBTreeSet::from(extract(\"test.tsx\",\nr#\"import {Box} from '@devup-ui/core'\n <Box _hover={{\n selectors: {\n \"&::placeholder, &:active\": {\n color: \"blue\"\n }\n },\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())"
44
---
55
ToBTreeSet {
66
styles: {
@@ -11,12 +11,25 @@ ToBTreeSet {
1111
level: 0,
1212
selector: Some(
1313
Selector(
14-
"&:hover::placeholder,&:hover:active",
14+
"&:hover::placeholder",
15+
),
16+
),
17+
style_order: None,
18+
},
19+
),
20+
Static(
21+
ExtractStaticStyle {
22+
property: "color",
23+
value: "blue",
24+
level: 0,
25+
selector: Some(
26+
Selector(
27+
"&:hover:active",
1528
),
1629
),
1730
style_order: None,
1831
},
1932
),
2033
},
21-
code: "import \"@devup-ui/core/devup-ui.css\";\n<div className=\"a\" />;\n",
34+
code: "import \"@devup-ui/core/devup-ui.css\";\n<div className=\"a b\" />;\n",
2235
}

libs/extractor/src/snapshots/extractor__tests__extract_nested_selector-3.snap

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
source: libs/extractor/src/lib.rs
3-
expression: "ToBTreeSet::from(extract(\"test.tsx\",\nr#\"import {Box} from '@devup-ui/core'\n <Box _hover={{\n selectors: {\n \"&::placeholder\": {\n color: \"red\"\n },\n \"&::placeholder, &:active\": {\n color: \"blue\"\n }\n },\n }} />\n \"#,\nExtractOption\n{ package: \"@devup-ui/core\".to_string(), css_file: None }).unwrap())"
3+
expression: "ToBTreeSet::from(extract(\"test.tsx\",\nr#\"import {Box} from '@devup-ui/core'\n <Box _hover={{\n selectors: {\n \"&::placeholder\": {\n color: \"red\"\n },\n \"&::placeholder, &:active\": {\n color: \"blue\"\n }\n },\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())"
44
---
55
ToBTreeSet {
66
styles: {
@@ -11,7 +11,20 @@ ToBTreeSet {
1111
level: 0,
1212
selector: Some(
1313
Selector(
14-
"&:hover::placeholder,&:hover:active",
14+
"&:hover::placeholder",
15+
),
16+
),
17+
style_order: None,
18+
},
19+
),
20+
Static(
21+
ExtractStaticStyle {
22+
property: "color",
23+
value: "blue",
24+
level: 0,
25+
selector: Some(
26+
Selector(
27+
"&:hover:active",
1528
),
1629
),
1730
style_order: None,
@@ -31,5 +44,5 @@ ToBTreeSet {
3144
},
3245
),
3346
},
34-
code: "import \"@devup-ui/core/devup-ui.css\";\n<div className=\"a b\" />;\n",
47+
code: "import \"@devup-ui/core/devup-ui.css\";\n<div className=\"a b c\" />;\n",
3548
}
Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
source: libs/extractor/src/lib.rs
3-
expression: "ToBTreeSet::from(extract(\"test.tsx\",\nr#\"import {Box} from '@devup-ui/core'\n <Box \n selectors={{\n _hover: {\n selectors: {\n \"&:active, _hover\": {\n color: \"red\",\n }\n }\n }\n }}\n />\n \"#,\nExtractOption\n{ package: \"@devup-ui/core\".to_string(), css_file: None }).unwrap())"
3+
expression: "ToBTreeSet::from(extract(\"test.tsx\",\nr#\"import {Box} from '@devup-ui/core'\n <Box \n selectors={{\n _hover: {\n selectors: {\n \"&:active, _hover\": {\n color: \"red\",\n }\n }\n }\n }}\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())"
44
---
55
ToBTreeSet {
66
styles: {
@@ -11,12 +11,25 @@ ToBTreeSet {
1111
level: 0,
1212
selector: Some(
1313
Selector(
14-
"&:hover:active,&:hover:hover",
14+
"&:hover:active",
15+
),
16+
),
17+
style_order: None,
18+
},
19+
),
20+
Static(
21+
ExtractStaticStyle {
22+
property: "color",
23+
value: "red",
24+
level: 0,
25+
selector: Some(
26+
Selector(
27+
"&:hover:hover",
1528
),
1629
),
1730
style_order: None,
1831
},
1932
),
2033
},
21-
code: "import \"@devup-ui/core/devup-ui.css\";\n<div className=\"a\" />;\n",
34+
code: "import \"@devup-ui/core/devup-ui.css\";\n<div className=\"a b\" />;\n",
2235
}

0 commit comments

Comments
 (0)