diff --git a/.changeset/violet-masks-speak.md b/.changeset/violet-masks-speak.md new file mode 100644 index 00000000..afb1f762 --- /dev/null +++ b/.changeset/violet-masks-speak.md @@ -0,0 +1,5 @@ +--- +"@devup-ui/wasm": patch +--- + +Fix selector order in theme diff --git a/libs/css/src/lib.rs b/libs/css/src/lib.rs index 82fc8f3e..6ac4aab2 100644 --- a/libs/css/src/lib.rs +++ b/libs/css/src/lib.rs @@ -10,11 +10,19 @@ use std::sync::Mutex; static SELECTOR_ORDER_MAP: Lazy> = Lazy::new(|| { let mut map = HashMap::new(); - map.insert("&:disabled".to_string(), 5); - map.insert("&:selected".to_string(), 4); - map.insert("&:active".to_string(), 3); - map.insert("&:focus".to_string(), 2); - map.insert("&:hover".to_string(), 1); + for (idx, selector) in [ + "hover", + "focus-visible", + "focus", + "active", + "selected", + "disabled", + ] + .into_iter() + .enumerate() + { + map.insert(format!("&:{}", selector), idx as u8); + } map }); @@ -41,18 +49,30 @@ impl PartialOrd for StyleSelector { } } +fn get_selector_order(selector: &str) -> u8 { + // & count + let t = if selector.chars().filter(|c| c == &'&').count() == 1 { + selector + .split('&') + .last() + .map(|a| format!("&{}", a)) + .unwrap_or(selector.to_string()) + } else { + selector.to_string() + }; + + *SELECTOR_ORDER_MAP + .get(&t) + .unwrap_or(if t.starts_with("&") { &0 } else { &99 }) +} + impl Ord for StyleSelector { fn cmp(&self, other: &Self) -> Ordering { match (self, other) { (StyleSelector::Media(a), StyleSelector::Media(b)) => a.cmp(b), - (StyleSelector::Selector(a), StyleSelector::Selector(b)) => SELECTOR_ORDER_MAP - .get(a) - .unwrap_or(if a.starts_with("&") { &0 } else { &99 }) - .cmp(SELECTOR_ORDER_MAP.get(b).unwrap_or(if b.starts_with("&") { - &0 - } else { - &99 - })), + (StyleSelector::Selector(a), StyleSelector::Selector(b)) => { + get_selector_order(a).cmp(&get_selector_order(b)) + } (StyleSelector::Media(_), StyleSelector::Selector(_)) => Ordering::Greater, (StyleSelector::Selector(_), StyleSelector::Media(_)) => Ordering::Less, } diff --git a/libs/sheet/src/lib.rs b/libs/sheet/src/lib.rs index 14b399aa..9d625899 100644 --- a/libs/sheet/src/lib.rs +++ b/libs/sheet/src/lib.rs @@ -515,6 +515,25 @@ mod tests { sheet.add_property("test", "mx", 0, "51px", Some(&"themeLight".into()), None); sheet.add_property("test", "mx", 0, "42px", None, None); assert_debug_snapshot!(sheet.create_css()); + + let mut sheet = StyleSheet::default(); + sheet.add_property( + "test", + "mx", + 0, + "50px", + Some(&["themeLight", "active"].into()), + None, + ); + sheet.add_property( + "test", + "mx", + 0, + "50px", + Some(&["themeLight", "hover"].into()), + None, + ); + assert_debug_snapshot!(sheet.create_css()); } #[test] diff --git a/libs/sheet/src/snapshots/sheet__tests__theme_selector-3.snap b/libs/sheet/src/snapshots/sheet__tests__theme_selector-3.snap new file mode 100644 index 00000000..e5becd7f --- /dev/null +++ b/libs/sheet/src/snapshots/sheet__tests__theme_selector-3.snap @@ -0,0 +1,5 @@ +--- +source: libs/sheet/src/lib.rs +expression: sheet.create_css() +--- +":root[data-theme=light] .test:hover{margin-left:50px;margin-right:50px;}:root[data-theme=light] .test:active{margin-left:50px;margin-right:50px;}"