Skip to content

Commit 32f6a2c

Browse files
authored
Merge pull request #285 from dev-five-git/improve-global-css
Improve global css
2 parents 85d46c2 + c81e2ac commit 32f6a2c

12 files changed

+299
-12
lines changed

.changeset/four-ideas-enjoy.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@devup-ui/wasm": patch
3+
---
4+
5+
Support auto wrapping for src in font faces

.changeset/hot-moose-count.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@devup-ui/react": patch
3+
"@devup-ui/wasm": patch
4+
---
5+
6+
Support \_ selector and typing in globalCss

libs/css/src/constant.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ pub(super) static ZERO_PERCENT_FUNCTION: phf::Set<&str> = phf_set! {
125125
};
126126

127127
pub(super) static F_SPACE_RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"\s*,\s*").unwrap());
128+
pub(super) static CSS_FUNCTION_RE: Lazy<Regex> =
129+
Lazy::new(|| Regex::new(r"^[a-zA-Z-]+(\(.*\))").unwrap());
130+
pub(super) static CHECK_QUOTES_RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"[()\s]").unwrap());
128131

129132
pub(super) static CSS_COMMENT_RE: Lazy<Regex> =
130133
Lazy::new(|| Regex::new(r"/\*[\s\S]*?\*/").unwrap());

libs/css/src/optimize_multi_css_value.rs

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::constant::OPTIMIZE_MULTI_CSS_VALUE_PROPERTY;
1+
use crate::constant::{CHECK_QUOTES_RE, CSS_FUNCTION_RE, OPTIMIZE_MULTI_CSS_VALUE_PROPERTY};
22

33
pub fn optimize_mutli_css_value(value: &str) -> String {
44
value
@@ -12,7 +12,7 @@ pub fn optimize_mutli_css_value(value: &str) -> String {
1212
} else {
1313
s.to_string()
1414
};
15-
if s.contains(" ") {
15+
if CHECK_QUOTES_RE.is_match(&s) && !CSS_FUNCTION_RE.is_match(&s) {
1616
format!("\"{s}\"")
1717
} else {
1818
s
@@ -22,6 +22,14 @@ pub fn optimize_mutli_css_value(value: &str) -> String {
2222
.join(",")
2323
}
2424

25+
pub fn wrap_url(s: &str) -> String {
26+
if CSS_FUNCTION_RE.is_match(s) {
27+
s.to_string()
28+
} else {
29+
format!("url({s})")
30+
}
31+
}
32+
2533
pub fn check_multi_css_optimize(property: &str) -> bool {
2634
OPTIMIZE_MULTI_CSS_VALUE_PROPERTY.contains(property)
2735
}
@@ -49,6 +57,8 @@ mod tests {
4957
#[case("'A B', 'C D', E", "\"A B\",\"C D\",E")]
5058
#[case("A,B,C", "A,B,C")]
5159
#[case("A, B, C", "A,B,C")]
60+
#[case("url(abc)", "url(abc)")]
61+
#[case("url(\"a bc\")", "url(\"a bc\")")]
5262
#[case("'A', 'B', 'C'", "A,B,C")]
5363
#[case("\"A\", \"B\", \"C\"", "A,B,C")]
5464
fn test_optimize_mutli_css_value(#[case] input: &str, #[case] expected: &str) {
@@ -66,4 +76,25 @@ mod tests {
6676
fn test_check_multi_css_optimize(#[case] property: &str, #[case] expected: bool) {
6777
assert_eq!(check_multi_css_optimize(property), expected);
6878
}
79+
80+
#[rstest]
81+
#[case("url('/fonts/Roboto-Regular.ttf')", "url('/fonts/Roboto-Regular.ttf')")]
82+
#[case(
83+
"url(\"/fonts/Roboto-Regular.ttf\")",
84+
"url(\"/fonts/Roboto-Regular.ttf\")"
85+
)]
86+
#[case("//fonts/Roboto-Regular.ttf", "url(//fonts/Roboto-Regular.ttf)")]
87+
#[case("fonts/Roboto-Regular.ttf", "url(fonts/Roboto-Regular.ttf)")]
88+
#[case(
89+
"local('fonts/Roboto Regular.ttf')",
90+
"local('fonts/Roboto Regular.ttf')"
91+
)]
92+
#[case("(hello)", "url(\"(hello)\")")]
93+
#[case("(hello world)", "url(\"(hello world)\")")]
94+
fn test_wrap_url(#[case] input: &str, #[case] expected: &str) {
95+
assert_eq!(
96+
super::wrap_url(&super::optimize_mutli_css_value(input)),
97+
expected
98+
);
99+
}
69100
}

libs/extractor/src/extractor/extract_global_style_from_expression.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::{
1414
};
1515
use css::{
1616
disassemble_property,
17-
optimize_multi_css_value::{check_multi_css_optimize, optimize_mutli_css_value},
17+
optimize_multi_css_value::{check_multi_css_optimize, optimize_mutli_css_value, wrap_url},
1818
style_selector::StyleSelector,
1919
};
2020
use oxc_ast::{
@@ -86,7 +86,15 @@ pub fn extract_global_style_from_expression<'a>(
8686
&& let PropertyKey::StaticIdentifier(ident) = &o.key
8787
&& let Some(s) = get_string_by_literal_expression(&o.value)
8888
{
89-
Some(disassemble_property(&ident.name).iter().map(|p| (p.to_string(), if check_multi_css_optimize(p) { optimize_mutli_css_value(&s) } else { s.clone() })).collect::<Vec<_>>())
89+
Some(disassemble_property(&ident.name).iter().map(|p| {
90+
let v= if check_multi_css_optimize(p) { optimize_mutli_css_value(&s) } else { s.clone() };
91+
if *p == "src" {
92+
(p.to_string(), wrap_url(&v))
93+
}
94+
else {
95+
(p.to_string(), v)
96+
}
97+
}).collect::<Vec<_>>())
9098
} else {
9199
None
92100
}
@@ -135,7 +143,14 @@ pub fn extract_global_style_from_expression<'a>(
135143
None,
136144
&mut o.value,
137145
0,
138-
&Some(StyleSelector::Global(name.clone(), file.to_string())),
146+
&Some(StyleSelector::Global(
147+
if let Some(name) = name.strip_prefix("_") {
148+
StyleSelector::from(name).to_string().replace("&", "*")
149+
} else {
150+
name.to_string()
151+
},
152+
file.to_string(),
153+
)),
139154
)
140155
.styles,
141156
);

libs/extractor/src/lib.rs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4684,6 +4684,63 @@ globalCss({
46844684
bg: "green"
46854685
}
46864686
})
4687+
"#,
4688+
ExtractOption {
4689+
package: "@devup-ui/core".to_string(),
4690+
css_file: None
4691+
}
4692+
)
4693+
.unwrap()
4694+
));
4695+
4696+
reset_class_map();
4697+
assert_debug_snapshot!(ToBTreeSet::from(
4698+
extract(
4699+
"test.tsx",
4700+
r#"import { globalCss } from "@devup-ui/core";
4701+
globalCss({
4702+
_hover: {
4703+
bg: "red"
4704+
}
4705+
})
4706+
"#,
4707+
ExtractOption {
4708+
package: "@devup-ui/core".to_string(),
4709+
css_file: None
4710+
}
4711+
)
4712+
.unwrap()
4713+
));
4714+
4715+
reset_class_map();
4716+
assert_debug_snapshot!(ToBTreeSet::from(
4717+
extract(
4718+
"test.tsx",
4719+
r#"import { globalCss } from "@devup-ui/core";
4720+
globalCss({
4721+
_placeholder: {
4722+
bg: "red"
4723+
}
4724+
})
4725+
"#,
4726+
ExtractOption {
4727+
package: "@devup-ui/core".to_string(),
4728+
css_file: None
4729+
}
4730+
)
4731+
.unwrap()
4732+
));
4733+
4734+
reset_class_map();
4735+
assert_debug_snapshot!(ToBTreeSet::from(
4736+
extract(
4737+
"test.tsx",
4738+
r#"import { globalCss } from "@devup-ui/core";
4739+
globalCss({
4740+
_nthLastChild: {
4741+
bg: "red"
4742+
}
4743+
})
46874744
"#,
46884745
ExtractOption {
46894746
package: "@devup-ui/core".to_string(),
@@ -5209,6 +5266,44 @@ globalCss({
52095266
}
52105267
]
52115268
})
5269+
"#,
5270+
ExtractOption {
5271+
package: "@devup-ui/core".to_string(),
5272+
css_file: None
5273+
}
5274+
)
5275+
.unwrap()
5276+
));
5277+
5278+
reset_class_map();
5279+
assert_debug_snapshot!(ToBTreeSet::from(
5280+
extract(
5281+
"test.tsx",
5282+
r#"import { globalCss } from "@devup-ui/core";
5283+
globalCss({
5284+
fontFaces: [
5285+
{
5286+
fontFamily: "Roboto Regular2",
5287+
src: "//fonts/Roboto-Regular.ttf",
5288+
fontWeight: 400,
5289+
},
5290+
{
5291+
fontFamily: "Roboto Regular",
5292+
src: "//fonts/Roboto Regular.ttf",
5293+
fontWeight: 400,
5294+
},
5295+
{
5296+
fontFamily: "Roboto Regular3",
5297+
src: "fonts/Roboto Regular.ttf",
5298+
fontWeight: 400,
5299+
},
5300+
{
5301+
fontFamily: "Roboto Regular4",
5302+
src: "local('fonts/Roboto Regular.ttf')",
5303+
fontWeight: 400,
5304+
},
5305+
]
5306+
})
52125307
"#,
52135308
ExtractOption {
52145309
package: "@devup-ui/core".to_string(),
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
source: libs/extractor/src/lib.rs
3+
expression: "ToBTreeSet::from(extract(\"test.tsx\",\nr#\"import { globalCss } from \"@devup-ui/core\";\nglobalCss({\n _hover: {\n bg: \"red\"\n }\n})\n\"#,\nExtractOption\n{ package: \"@devup-ui/core\".to_string(), css_file: None }).unwrap())"
4+
---
5+
ToBTreeSet {
6+
styles: {
7+
Static(
8+
ExtractStaticStyle {
9+
property: "background",
10+
value: "red",
11+
level: 0,
12+
selector: Some(
13+
Global(
14+
"*:hover",
15+
"test.tsx",
16+
),
17+
),
18+
style_order: Some(
19+
0,
20+
),
21+
},
22+
),
23+
},
24+
code: "import \"@devup-ui/core/devup-ui.css\";\n;\n",
25+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
source: libs/extractor/src/lib.rs
3+
expression: "ToBTreeSet::from(extract(\"test.tsx\",\nr#\"import { globalCss } from \"@devup-ui/core\";\nglobalCss({\n _placeholder: {\n bg: \"red\"\n }\n})\n\"#,\nExtractOption\n{ package: \"@devup-ui/core\".to_string(), css_file: None }).unwrap())"
4+
---
5+
ToBTreeSet {
6+
styles: {
7+
Static(
8+
ExtractStaticStyle {
9+
property: "background",
10+
value: "red",
11+
level: 0,
12+
selector: Some(
13+
Global(
14+
"*::placeholder",
15+
"test.tsx",
16+
),
17+
),
18+
style_order: Some(
19+
0,
20+
),
21+
},
22+
),
23+
},
24+
code: "import \"@devup-ui/core/devup-ui.css\";\n;\n",
25+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
source: libs/extractor/src/lib.rs
3+
expression: "ToBTreeSet::from(extract(\"test.tsx\",\nr#\"import { globalCss } from \"@devup-ui/core\";\nglobalCss({\n _nthLastChild: {\n bg: \"red\"\n }\n})\n\"#,\nExtractOption\n{ package: \"@devup-ui/core\".to_string(), css_file: None }).unwrap())"
4+
---
5+
ToBTreeSet {
6+
styles: {
7+
Static(
8+
ExtractStaticStyle {
9+
property: "background",
10+
value: "red",
11+
level: 0,
12+
selector: Some(
13+
Global(
14+
"*:nth-last-child",
15+
"test.tsx",
16+
),
17+
),
18+
style_order: Some(
19+
0,
20+
),
21+
},
22+
),
23+
},
24+
code: "import \"@devup-ui/core/devup-ui.css\";\n;\n",
25+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
---
2+
source: libs/extractor/src/lib.rs
3+
expression: "ToBTreeSet::from(extract(\"test.tsx\",\nr#\"import { globalCss } from \"@devup-ui/core\";\nglobalCss({\n fontFaces: [\n {\n fontFamily: \"Roboto Regular2\",\n src: \"//fonts/Roboto-Regular.ttf\",\n fontWeight: 400,\n },\n {\n fontFamily: \"Roboto Regular\",\n src: \"//fonts/Roboto Regular.ttf\",\n fontWeight: 400,\n },\n {\n fontFamily: \"Roboto Regular3\",\n src: \"fonts/Roboto Regular.ttf\",\n fontWeight: 400,\n },\n {\n fontFamily: \"Roboto Regular4\",\n src: \"local('fonts/Roboto Regular.ttf')\",\n fontWeight: 400,\n },\n ]\n})\n\"#,\nExtractOption\n{ package: \"@devup-ui/core\".to_string(), css_file: None }).unwrap())"
4+
---
5+
ToBTreeSet {
6+
styles: {
7+
FontFace(
8+
ExtractFontFace {
9+
file: "test.tsx",
10+
properties: {
11+
"font-family": "\"Roboto Regular\"",
12+
"font-weight": "400",
13+
"src": "url(\"//fonts/Roboto Regular.ttf\")",
14+
},
15+
},
16+
),
17+
FontFace(
18+
ExtractFontFace {
19+
file: "test.tsx",
20+
properties: {
21+
"font-family": "\"Roboto Regular2\"",
22+
"font-weight": "400",
23+
"src": "url(//fonts/Roboto-Regular.ttf)",
24+
},
25+
},
26+
),
27+
FontFace(
28+
ExtractFontFace {
29+
file: "test.tsx",
30+
properties: {
31+
"font-family": "\"Roboto Regular3\"",
32+
"font-weight": "400",
33+
"src": "url(\"fonts/Roboto Regular.ttf\")",
34+
},
35+
},
36+
),
37+
FontFace(
38+
ExtractFontFace {
39+
file: "test.tsx",
40+
properties: {
41+
"font-family": "\"Roboto Regular4\"",
42+
"font-weight": "400",
43+
"src": "local('fonts/Roboto Regular.ttf')",
44+
},
45+
},
46+
),
47+
},
48+
code: "import \"@devup-ui/core/devup-ui.css\";\n;\n",
49+
}

0 commit comments

Comments
 (0)