Skip to content

Commit 5c98f25

Browse files
committed
Add group selector
1 parent 576901f commit 5c98f25

2 files changed

Lines changed: 47 additions & 3 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"changes":{"bindings/devup-ui-wasm/package.json":"Patch"},"note":"Apply order into group selector","date":"2026-01-15T11:45:16.988823800Z"}

libs/css/src/style_selector.rs

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -266,9 +266,23 @@ fn get_selector_order(selector: &str) -> u8 {
266266
selector.to_string()
267267
};
268268

269-
*SELECTOR_ORDER_MAP
270-
.get(&t)
271-
.unwrap_or(if t.starts_with("&") { &0 } else { &99 })
269+
// First, try to find the order in the map (for regular selectors like &:hover)
270+
if let Some(order) = SELECTOR_ORDER_MAP.get(&t) {
271+
return *order;
272+
}
273+
274+
// For group selectors like "*[role=group]:hover &", the pseudo-selector is before &
275+
// Check if the selector ends with " &" (group pattern) and contains a known pseudo-selector
276+
if selector.ends_with(" &") {
277+
let before_ampersand = selector.strip_suffix(" &").unwrap_or(selector);
278+
for (pseudo, order) in SELECTOR_ORDER_MAP.iter() {
279+
if before_ampersand.ends_with(pseudo) {
280+
return *order;
281+
}
282+
}
283+
}
284+
285+
if t.starts_with("&") { 0 } else { 99 }
272286
}
273287

274288
#[cfg(test)]
@@ -442,6 +456,27 @@ mod tests {
442456
StyleSelector::Global("div:".to_string(), "file2.rs".to_string()),
443457
std::cmp::Ordering::Greater
444458
)]
459+
// Group selector ordering tests - _groupHover should come before _groupActive
460+
#[case(
461+
StyleSelector::Selector("*[role=group]:hover &".to_string()),
462+
StyleSelector::Selector("*[role=group]:active &".to_string()),
463+
std::cmp::Ordering::Less
464+
)]
465+
#[case(
466+
StyleSelector::Selector("*[role=group]:focus-visible &".to_string()),
467+
StyleSelector::Selector("*[role=group]:focus &".to_string()),
468+
std::cmp::Ordering::Less
469+
)]
470+
#[case(
471+
StyleSelector::Selector("*[role=group]:active &".to_string()),
472+
StyleSelector::Selector("*[role=group]:hover &".to_string()),
473+
std::cmp::Ordering::Greater
474+
)]
475+
#[case(
476+
StyleSelector::Selector("*[role=group]:hover &".to_string()),
477+
StyleSelector::Selector("*[role=group]:hover &".to_string()),
478+
std::cmp::Ordering::Equal
479+
)]
445480
fn test_style_selector_ord(
446481
#[case] a: StyleSelector,
447482
#[case] b: StyleSelector,
@@ -467,6 +502,14 @@ mod tests {
467502
#[case(":root[data-theme=dark] &:selected", 4)]
468503
#[case(":root[data-theme=dark] &:disabled", 5)]
469504
#[case(":root[data-theme=dark] &:not-exist", 99)]
505+
// Group selectors - pseudo-selector is before &
506+
#[case("*[role=group]:hover &", 0)]
507+
#[case("*[role=group]:focus-visible &", 1)]
508+
#[case("*[role=group]:focus &", 2)]
509+
#[case("*[role=group]:active &", 3)]
510+
#[case("*[role=group]:selected &", 4)]
511+
#[case("*[role=group]:disabled &", 5)]
512+
#[case("*[role=group]:not-exist &", 99)]
470513
fn test_get_selector_order(#[case] selector: &str, #[case] expected: u8) {
471514
assert_eq!(get_selector_order(selector), expected);
472515
}

0 commit comments

Comments
 (0)