Skip to content

Commit 8a79d76

Browse files
committed
feat: 支持优化处理 border-radius 属性
1 parent fc5dec0 commit 8a79d76

File tree

4 files changed

+270
-110
lines changed

4 files changed

+270
-110
lines changed

__test__/index.spec.mjs.md

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,12 @@ Generated by [AVA](https://avajs.dev).
2424
"cnt_row": {␊
2525
alignItems: "center",␊
2626
backgroundColor: "rgba(0, 0, 0, .7)",␊
27-
borderRadius: "100px",␊
27+
borderRadius: {␊
28+
topLeft: "100px",␊
29+
topRight: "100px",␊
30+
bottomLeft: "100px",␊
31+
bottomRight: "100px"␊
32+
},␊
2833
display: "flex",␊
2934
flexShrink: "0px",␊
3035
gap: "4px",␊
@@ -35,7 +40,7 @@ Generated by [AVA](https://avajs.dev).
3540
paddingRight: "8px",␊
3641
paddingTop: "8px",␊
3742
textDecoration: {␊
38-
type: TextDecoration["LineThrough"],␊
43+
type: TextDecoration["line-through"],␊
3944
color: "black"␊
4045
},␊
4146
width: "176px"␊
@@ -52,7 +57,12 @@ Generated by [AVA](https://avajs.dev).
5257
"cnt_row2": {␊
5358
alignItems: "flex-start",␊
5459
borderColor: "#999",␊
55-
borderRadius: "12px",␊
60+
borderRadius: {␊
61+
topLeft: "12px",␊
62+
topRight: "12px",␊
63+
bottomLeft: "12px",␊
64+
bottomRight: "12px"␊
65+
},␊
5666
borderStyle: "solid",␊
5767
borderWidth: "1px",␊
5868
display: "flex",␊
@@ -81,7 +91,7 @@ Generated by [AVA](https://avajs.dev).
8191
"icon": {␊
8292
height: "18px",␊
8393
textDecoration: {␊
84-
type: TextDecoration["LineThrough"],␊
94+
type: TextDecoration["line-through"],␊
8595
color: "black"␊
8696
},␊
8797
width: "18px"␊
@@ -129,7 +139,12 @@ Generated by [AVA](https://avajs.dev).
129139
"mod": {␊
130140
alignItems: "flex-start",␊
131141
backgroundColor: "#fff6f0",␊
132-
borderRadius: "8px",␊
142+
borderRadius: {␊
143+
topLeft: "8px",␊
144+
topRight: "8px",␊
145+
bottomLeft: "8px",␊
146+
bottomRight: "8px"␊
147+
},␊
133148
display: "flex",␊
134149
flexDirection: "column",␊
135150
flexShrink: "0px",␊
@@ -222,22 +237,27 @@ Generated by [AVA](https://avajs.dev).
222237
}␊
223238
render() {␊
224239
return <div className='mod' style={{␊
225-
flexShrink: "0px",␊
226240
alignItems: "flex-start",␊
227241
backgroundColor: "#fff6f0",␊
242+
borderRadius: {␊
243+
topLeft: "8px",␊
244+
topRight: "8px",␊
245+
bottomLeft: "8px",␊
246+
bottomRight: "8px"␊
247+
},␊
248+
display: "flex",␊
249+
flexDirection: "column",␊
250+
flexShrink: "0px",␊
251+
fontFamily: "Source Han Sans CN",␊
228252
fontWeight: "500",␊
253+
gap: "8px",␊
254+
height: 800,␊
229255
justifyContent: "center",␊
230256
paddingBottom: "29px",␊
231-
paddingTop: "29px",␊
232-
display: "flex",␊
233257
paddingLeft: "16px",␊
234-
gap: "8px",␊
235-
fontFamily: "Source Han Sans CN",␊
236-
borderRadius: "8px",␊
237258
paddingRight: "16px",␊
238-
flexDirection: "column",␊
239-
width: '500px',␊
240-
height: 800␊
259+
paddingTop: "29px",␊
260+
width: '500px'␊
241261
}}>␊
242262
243263
<div className={classnames('cnt_row')} style style={calcDynamicStyle(__inner_style__, classnames('cnt_row'), null)}>␊
@@ -247,7 +267,7 @@ Generated by [AVA](https://avajs.dev).
247267
<img className='icon' src='//img20.360buyimg.com/img/jfs/t1/166410/12/38783/3147/64f58062Fd7737e2b/5aaf0205cd1ce175.png' style={{␊
248268
height: "18px",␊
249269
textDecoration: {␊
250-
type: TextDecoration["LineThrough"],␊
270+
type: TextDecoration["line-through"],␊
251271
color: "black"␊
252272
},␊
253273
width: "18px"␊
@@ -325,7 +345,12 @@ Generated by [AVA](https://avajs.dev).
325345
<div className='cnt_row2' style={{␊
326346
alignItems: "flex-start",␊
327347
borderColor: "#999",␊
328-
borderRadius: "12px",␊
348+
borderRadius: {␊
349+
topLeft: "12px",␊
350+
topRight: "12px",␊
351+
bottomLeft: "12px",␊
352+
bottomRight: "12px"␊
353+
},␊
329354
borderStyle: "solid",␊
330355
borderWidth: "1px",␊
331356
display: "flex",␊

__test__/index.spec.mjs.snap

86 Bytes
Binary file not shown.

src/style_parser.rs

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ use lightningcss::{
1212
visit_types,
1313
visitor::{Visit, VisitTypes, Visitor},
1414
};
15+
use swc_common::DUMMY_SP;
16+
use swc_ecma_ast::{
17+
ComputedPropName, Expr, Ident, KeyValueProp, Lit, MemberExpr, MemberProp, ObjectLit, Prop,
18+
PropName, PropOrSpread, Str,
19+
};
1520

1621
use crate::{document::JSXDocument, utils::to_camel_case, visitor::SpanKey};
1722

@@ -22,16 +27,138 @@ pub struct StyleData {
2227
pub all_style: Rc<RefCell<HashMap<String, StyleValue>>>,
2328
}
2429

30+
pub trait ToObjectExpr {
31+
fn to_object_expr(&self) -> Expr;
32+
}
33+
2534
#[derive(Debug, Clone)]
2635
pub struct TextDecoration {
2736
pub kind: String,
2837
pub color: String,
2938
}
3039

40+
impl TextDecoration {
41+
pub fn change_color(&mut self, color: &str) {
42+
self.color = color.to_string();
43+
}
44+
}
45+
46+
impl ToObjectExpr for TextDecoration {
47+
fn to_object_expr(&self) -> Expr {
48+
Expr::Object(ObjectLit {
49+
span: DUMMY_SP,
50+
props: vec![
51+
PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
52+
key: PropName::Ident(Ident::new("type".into(), DUMMY_SP)),
53+
value: Expr::Member(MemberExpr {
54+
span: DUMMY_SP,
55+
obj: Box::new(Expr::Ident(Ident::new("TextDecoration".into(), DUMMY_SP))),
56+
prop: MemberProp::Computed(ComputedPropName {
57+
span: DUMMY_SP,
58+
expr: Expr::Lit(Lit::Str(Str::from(self.kind.to_string()))).into(),
59+
}),
60+
})
61+
.into(),
62+
}))),
63+
PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
64+
key: PropName::Ident(Ident::new("color".into(), DUMMY_SP)),
65+
value: Expr::Lit(Lit::Str(Str::from(self.color.to_string()))).into(),
66+
}))),
67+
]
68+
.into(),
69+
})
70+
}
71+
}
72+
73+
impl From<&str> for TextDecoration {
74+
fn from(value: &str) -> Self {
75+
TextDecoration {
76+
kind: value.to_string(),
77+
color: "black".to_string(),
78+
}
79+
}
80+
}
81+
82+
#[derive(Debug, Clone)]
83+
pub struct BorderRadius {
84+
pub top_left: String,
85+
pub top_right: String,
86+
pub bottom_left: String,
87+
pub bottom_right: String,
88+
}
89+
90+
impl ToObjectExpr for BorderRadius {
91+
fn to_object_expr(&self) -> Expr {
92+
Expr::Object(ObjectLit {
93+
span: DUMMY_SP,
94+
props: vec![
95+
PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
96+
key: PropName::Ident(Ident::new("topLeft".into(), DUMMY_SP)),
97+
value: Expr::Lit(Lit::Str(Str::from(self.top_left.to_string()))).into(),
98+
}))),
99+
PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
100+
key: PropName::Ident(Ident::new("topRight".into(), DUMMY_SP)),
101+
value: Expr::Lit(Lit::Str(Str::from(self.top_right.to_string()))).into(),
102+
}))),
103+
PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
104+
key: PropName::Ident(Ident::new("bottomLeft".into(), DUMMY_SP)),
105+
value: Expr::Lit(Lit::Str(Str::from(self.bottom_left.to_string()))).into(),
106+
}))),
107+
PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
108+
key: PropName::Ident(Ident::new("bottomRight".into(), DUMMY_SP)),
109+
value: Expr::Lit(Lit::Str(Str::from(self.bottom_right.to_string()))).into(),
110+
}))),
111+
]
112+
.into(),
113+
})
114+
}
115+
}
116+
117+
impl From<&str> for BorderRadius {
118+
fn from(value: &str) -> Self {
119+
let border_radius = value.to_string();
120+
let border_radius = border_radius.split(" ").collect::<Vec<&str>>();
121+
let border_radius = match border_radius.len() {
122+
1 => BorderRadius {
123+
top_left: border_radius[0].to_string(),
124+
top_right: border_radius[0].to_string(),
125+
bottom_left: border_radius[0].to_string(),
126+
bottom_right: border_radius[0].to_string(),
127+
},
128+
2 => BorderRadius {
129+
top_left: border_radius[0].to_string(),
130+
top_right: border_radius[1].to_string(),
131+
bottom_left: border_radius[0].to_string(),
132+
bottom_right: border_radius[1].to_string(),
133+
},
134+
3 => BorderRadius {
135+
top_left: border_radius[0].to_string(),
136+
top_right: border_radius[1].to_string(),
137+
bottom_left: border_radius[2].to_string(),
138+
bottom_right: border_radius[1].to_string(),
139+
},
140+
4 => BorderRadius {
141+
top_left: border_radius[0].to_string(),
142+
top_right: border_radius[1].to_string(),
143+
bottom_left: border_radius[2].to_string(),
144+
bottom_right: border_radius[3].to_string(),
145+
},
146+
_ => BorderRadius {
147+
top_left: "0".to_string(),
148+
top_right: "0".to_string(),
149+
bottom_left: "0".to_string(),
150+
bottom_right: "0".to_string(),
151+
},
152+
};
153+
border_radius
154+
}
155+
}
156+
31157
#[derive(Debug, Clone)]
32158
pub enum StyleValueType {
33159
Normal(String),
34160
TextDecoration(TextDecoration),
161+
BorderRadius(BorderRadius),
35162
}
36163

37164
impl Display for StyleValueType {
@@ -41,6 +168,13 @@ impl Display for StyleValueType {
41168
StyleValueType::TextDecoration(value) => {
42169
write!(f, "{}", to_camel_case(value.kind.as_str(), true))
43170
}
171+
StyleValueType::BorderRadius(value) => {
172+
write!(
173+
f,
174+
"{} {} {} {}",
175+
value.top_left, value.top_right, value.bottom_left, value.bottom_right
176+
)
177+
}
44178
}
45179
}
46180
}
@@ -165,11 +299,14 @@ impl<'i> StyleParser<'i> {
165299
fn parse_style_value(&self, style_value: &mut StyleValue) {
166300
let mut text_decoration = None;
167301
let mut color = None;
302+
let mut border_radius = None;
168303
for property in style_value.iter_mut() {
169304
if property.0 == "textDecoration" {
170305
text_decoration = Some(property.1.clone());
171306
} else if property.0 == "color" {
172307
color = Some(property.1.clone());
308+
} else if property.0 == "borderRadius" {
309+
border_radius = Some(property.1.clone());
173310
}
174311
}
175312

@@ -185,6 +322,13 @@ impl<'i> StyleParser<'i> {
185322
}),
186323
);
187324
}
325+
326+
if let Some(border_radius) = border_radius {
327+
style_value.insert(
328+
"borderRadius".to_string(),
329+
StyleValueType::BorderRadius(BorderRadius::from(border_radius.to_string().as_str())),
330+
);
331+
}
188332
}
189333

190334
pub fn calc(&self) -> StyleData {

0 commit comments

Comments
 (0)