diff --git a/.changeset/shiny-ways-try.md b/.changeset/shiny-ways-try.md new file mode 100644 index 00000000..e50f4890 --- /dev/null +++ b/.changeset/shiny-ways-try.md @@ -0,0 +1,5 @@ +--- +"@devup-ui/wasm": patch +--- + +Support $ var with anywhere diff --git a/Cargo.lock b/Cargo.lock index ab2d58f1..afed87fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + [[package]] name = "allocator-api2" version = "0.2.21" @@ -116,6 +125,7 @@ name = "css" version = "0.1.0" dependencies = [ "once_cell", + "regex", "serde", "serial_test", ] @@ -815,6 +825,35 @@ dependencies = [ "bitflags", ] +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + [[package]] name = "ropey" version = "1.6.1" @@ -965,6 +1004,8 @@ version = "0.1.0" dependencies = [ "css", "insta", + "once_cell", + "regex", "serde", "serde_json", ] diff --git a/libs/css/Cargo.toml b/libs/css/Cargo.toml index 2b23bb12..76ad828a 100644 --- a/libs/css/Cargo.toml +++ b/libs/css/Cargo.toml @@ -7,3 +7,4 @@ edition = "2021" once_cell = "1.20.2" serial_test = "3.2.0" serde = { version = "1.0.217", features = ["derive"] } +regex = "1.11.1" diff --git a/libs/css/src/lib.rs b/libs/css/src/lib.rs index 663550c4..a69eabe3 100644 --- a/libs/css/src/lib.rs +++ b/libs/css/src/lib.rs @@ -1,5 +1,6 @@ use crate::StyleSelector::{Dual, Postfix, Prefix}; use once_cell::sync::Lazy; +use regex::Regex; use serde::{Deserialize, Serialize}; use std::collections::{HashMap, HashSet}; use std::fmt; @@ -278,6 +279,7 @@ pub fn sort_to_long(property: &str) -> String { .unwrap_or_else(|| property.to_string()) } +static F_SPACE_RE: Lazy = Lazy::new(|| Regex::new(r"\s*,\s*").unwrap()); pub fn sheet_to_classname( property: &str, level: u8, @@ -286,10 +288,10 @@ pub fn sheet_to_classname( ) -> String { let key = format!( "{}-{}-{}-{}", - property, + property.trim(), level, - value.unwrap_or(""), - selector.unwrap_or("") + F_SPACE_RE.replace_all(value.unwrap_or(""), ",").trim(), + selector.unwrap_or("").trim() ); let mut map = GLOBAL_CLASS_MAP.lock().unwrap(); map.get(&key).map(|v| format!("d{}", v)).unwrap_or_else(|| { @@ -355,6 +357,30 @@ mod tests { sheet_to_classname("background", 1, Some("hover"), None), "d3" ); + + reset_class_map(); + assert_eq!(sheet_to_classname("background", 0, None, None), "d0"); + assert_eq!(sheet_to_classname("background", 0, None, None), "d0"); + assert_eq!(sheet_to_classname("background", 0, Some("red"), None), "d1"); + assert_eq!(sheet_to_classname("background", 0, Some("red"), None), "d1"); + assert_eq!( + sheet_to_classname(" background ", 0, Some(" red "), None), + "d1" + ); + + assert_eq!( + sheet_to_classname("background", 0, Some("rgba(255, 0, 0, 0.5)"), None), + "d2" + ); + assert_eq!( + sheet_to_classname("background", 0, Some("rgba(255,0,0,0.5)"), None), + "d2" + ); + + { + let map = GLOBAL_CLASS_MAP.lock().unwrap(); + assert_eq!(map.get("background-0-rgba(255,0,0,0.5)-"), Some(&2)); + } } #[test] diff --git a/libs/sheet/Cargo.toml b/libs/sheet/Cargo.toml index 58e79dac..c1f9a6f0 100644 --- a/libs/sheet/Cargo.toml +++ b/libs/sheet/Cargo.toml @@ -6,6 +6,8 @@ edition = "2021" [dependencies] css = { path = "../css" } serde = { version = "1.0.217", features = ["derive"] } +regex = "1.11.1" +once_cell = "1.20.2" [dev-dependencies] insta = "1.42.1" diff --git a/libs/sheet/src/lib.rs b/libs/sheet/src/lib.rs index 4998f4c7..1bc1df35 100644 --- a/libs/sheet/src/lib.rs +++ b/libs/sheet/src/lib.rs @@ -2,6 +2,8 @@ pub mod theme; use crate::theme::Theme; use css::{convert_property, merge_selector, PropertyType, StyleSelector}; +use once_cell::sync::Lazy; +use regex::Regex; use serde::de::Error; use serde::{Deserialize, Deserializer, Serialize}; use std::cmp::Ordering::{Equal, Greater, Less}; @@ -45,12 +47,14 @@ impl ExtractStyle for StyleSheetProperty { } } -fn convert_theme_variable_value(value: &String) -> String { - if let Some(value) = value.strip_prefix("$") { - format!("var(--{})", value) - } else { - value.to_string() - } +static VAR_RE: Lazy = Lazy::new(|| Regex::new(r"\$\w+").unwrap()); + +fn convert_theme_variable_value(value: &str) -> String { + VAR_RE + .replace_all(value, |caps: ®ex::Captures| { + format!("var(--{})", &caps[0][1..]) + }) + .to_string() } #[derive(Debug, Hash, Eq, PartialEq, Deserialize, Serialize)] @@ -198,6 +202,16 @@ mod tests { convert_theme_variable_value(&"$var".to_string()), "var(--var)" ); + + assert_eq!( + convert_theme_variable_value(&"$var $var".to_string()), + "var(--var) var(--var)" + ); + + assert_eq!( + convert_theme_variable_value(&"1px solid $red".to_string()), + "1px solid var(--red)" + ); } #[test]