Skip to content

Commit eb77e90

Browse files
committed
Feat Selector
1 parent 3249963 commit eb77e90

File tree

42 files changed

+360
-23
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+360
-23
lines changed

apps/next/src/app/page.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ export default function HomePage() {
1212
<a />
1313
<Box
1414
_hover={{
15-
bg: 'red',
15+
bg: ['yellow', 'red'],
16+
cursor: 'cell',
1617
}}
1718
as="span"
1819
bg="blue"

bindings/devup-ui-wasm/src/lib.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,13 @@ impl Output {
4141
};
4242
match style {
4343
ExtractStyleValue::Static(st) => {
44-
if let Some(css) =
45-
sheet.add_property(cls, st.property.clone(), st.level, st.value.clone())
46-
{
44+
if let Some(css) = sheet.add_property(
45+
cls,
46+
st.property.clone(),
47+
st.level,
48+
st.value.clone(),
49+
st.selector.clone(),
50+
) {
4751
collected = true;
4852
}
4953
}
@@ -53,6 +57,7 @@ impl Output {
5357
dy.property.clone(),
5458
dy.level,
5559
format!("var({})", variable.unwrap()),
60+
dy.selector.clone(),
5661
) {
5762
collected = true;
5863
}

libs/extractor/src/component.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,21 @@ impl ExportVariableKind {
4343
value: "flex".to_string(),
4444
property: "display".to_string(),
4545
level: 0,
46+
selector: None,
4647
})],
4748
ExportVariableKind::VStack => {
4849
vec![
4950
Static(ExtractStaticStyle {
5051
value: "flex".to_string(),
5152
property: "display".to_string(),
5253
level: 0,
54+
selector: None,
5355
}),
5456
Static(ExtractStaticStyle {
5557
value: "column".to_string(),
5658
property: "flexDirection".to_string(),
5759
level: 0,
60+
selector: None,
5861
}),
5962
]
6063
}
@@ -64,16 +67,19 @@ impl ExportVariableKind {
6467
value: "flex".to_string(),
6568
property: "display".to_string(),
6669
level: 0,
70+
selector: None,
6771
}),
6872
Static(ExtractStaticStyle {
6973
value: "center".to_string(),
7074
property: "justifyContent".to_string(),
7175
level: 0,
76+
selector: None,
7277
}),
7378
Static(ExtractStaticStyle {
7479
value: "center".to_string(),
7580
property: "alignItems".to_string(),
7681
level: 0,
82+
selector: None,
7783
}),
7884
]
7985
}

libs/extractor/src/lib.rs

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
mod component;
22
mod gen_class_name;
33
mod gen_style;
4+
mod media_prop_extract_utils;
45
mod prop_extract_utils;
56
mod prop_modify_utils;
67
mod utils;
@@ -45,10 +46,10 @@ impl ExtractStyleProp<'_> {
4546
} => {
4647
let mut styles = vec![];
4748
if let Some(consequent) = consequent {
48-
styles.extend(consequent.extract());
49+
styles.append(&mut consequent.extract());
4950
}
5051
if let Some(alternate) = alternate {
51-
styles.extend(alternate.extract());
52+
styles.append(&mut alternate.extract());
5253
}
5354
styles
5455
}
@@ -80,6 +81,8 @@ pub struct ExtractStaticStyle {
8081
pub value: String,
8182
/// responsive level
8283
pub level: u8,
84+
/// selector
85+
pub selector: Option<String>,
8386
}
8487

8588
impl ExtractStyleProperty for ExtractStaticStyle {
@@ -114,6 +117,9 @@ pub struct ExtractDynamicStyle {
114117
/// responsive
115118
pub level: u8,
116119
identifier: String,
120+
121+
/// selector
122+
pub selector: Option<String>,
117123
}
118124

119125
impl ExtractStyleProperty for ExtractDynamicStyle {
@@ -652,6 +658,57 @@ mod tests {
652658
)
653659
.unwrap());
654660
}
661+
662+
#[test]
663+
fn extract_selector() {
664+
assert_debug_snapshot!(extract(
665+
"test.tsx",
666+
r"import {Box} from '@devup-ui/core'
667+
<Box _hover={{
668+
mx: 1
669+
}} />
670+
",
671+
ExtractOption {
672+
package: "@devup-ui/core".to_string(),
673+
css_file: None
674+
}
675+
)
676+
.unwrap());
677+
}
678+
679+
#[test]
680+
fn extract_selector_with_responsive() {
681+
assert_debug_snapshot!(extract(
682+
"test.tsx",
683+
r"import {Box} from '@devup-ui/core'
684+
<Box _hover={{
685+
mx: [1, 2]
686+
}} />
687+
",
688+
ExtractOption {
689+
package: "@devup-ui/core".to_string(),
690+
css_file: None
691+
}
692+
)
693+
.unwrap());
694+
695+
assert_debug_snapshot!(extract(
696+
"test.tsx",
697+
r"import {Box} from '@devup-ui/core'
698+
<Box _hover={[{
699+
mx: 10
700+
},{
701+
mx: 20
702+
}]} />
703+
",
704+
ExtractOption {
705+
package: "@devup-ui/core".to_string(),
706+
css_file: None
707+
}
708+
)
709+
.unwrap());
710+
}
711+
655712
#[test]
656713
fn extract_static_css_class_name_props() {
657714
let mut hasher = DefaultHasher::new();
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
use crate::prop_extract_utils::extract_style_prop_from_express;
2+
use crate::ExtractStyleProp;
3+
use oxc_ast::ast::{
4+
ArrayExpressionElement, JSXAttributeValue, JSXExpression, ObjectExpression, ObjectPropertyKind,
5+
};
6+
use oxc_ast::AstBuilder;
7+
8+
pub fn extract_media_prop<'a>(
9+
ast_builder: &AstBuilder<'a>,
10+
value: &JSXAttributeValue<'a>,
11+
media: &str,
12+
) -> Option<Vec<ExtractStyleProp<'a>>> {
13+
match value {
14+
JSXAttributeValue::ExpressionContainer(expression) => match &expression.expression {
15+
JSXExpression::ObjectExpression(obj) => {
16+
let mut props = vec![];
17+
props.append(&mut extract_props_from_object_expression(
18+
ast_builder,
19+
obj,
20+
0,
21+
media,
22+
));
23+
Some(props)
24+
}
25+
JSXExpression::ArrayExpression(arr) => {
26+
let mut props = vec![];
27+
for (idx, e) in arr.elements.iter().enumerate() {
28+
if let ArrayExpressionElement::ObjectExpression(oo) = e {
29+
props.append(&mut extract_props_from_object_expression(
30+
ast_builder,
31+
oo,
32+
idx as u8,
33+
media,
34+
));
35+
}
36+
}
37+
Some(props)
38+
}
39+
_ => None,
40+
},
41+
_ => None,
42+
}
43+
}
44+
45+
fn extract_props_from_object_expression<'a>(
46+
ast_builder: &AstBuilder<'a>,
47+
obj: &ObjectExpression<'a>,
48+
level: u8,
49+
media: &str,
50+
) -> Vec<ExtractStyleProp<'a>> {
51+
let mut props = vec![];
52+
for p in obj.properties.iter() {
53+
if let ObjectPropertyKind::ObjectProperty(o) = p {
54+
if let Some(ret) = extract_style_prop_from_express(
55+
ast_builder,
56+
o.key.name().unwrap().to_string().as_str(),
57+
&o.value,
58+
level,
59+
Some(media),
60+
) {
61+
props.push(ret);
62+
}
63+
};
64+
}
65+
props
66+
}

libs/extractor/src/prop_extract_utils.rs

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub fn extract_style_prop<'a>(
2323
value: convert_value(str.value.as_str()),
2424
level: 0,
2525
property: name,
26+
selector: None,
2627
})))
2728
}
2829
JSXAttributeValue::ExpressionContainer(expression) => {
@@ -34,31 +35,35 @@ pub fn extract_style_prop<'a>(
3435
name.as_str(),
3536
expression.expression.to_expression(),
3637
0,
38+
None,
3739
)
3840
}
3941
}
4042
_ => None,
4143
}
4244
}
43-
fn extract_style_prop_from_express<'a>(
45+
pub fn extract_style_prop_from_express<'a>(
4446
ast_builder: &AstBuilder<'a>,
4547
name: &str,
4648
expression: &Expression<'a>,
4749
level: u8,
50+
selector: Option<&str>,
4851
) -> Option<ExtractStyleProp<'a>> {
4952
match &expression {
5053
Expression::NumericLiteral(num) => {
5154
Some(ExtractStyleProp::Static(Static(ExtractStaticStyle {
5255
value: convert_value(num.value.to_string().as_str()),
5356
level,
5457
property: name.to_string(),
58+
selector: selector.map(|s| s.to_string()),
5559
})))
5660
}
5761
Expression::StringLiteral(str) => {
5862
Some(ExtractStyleProp::Static(Static(ExtractStaticStyle {
5963
value: convert_value(str.value.as_str()),
6064
level,
6165
property: name.to_string(),
66+
selector: selector.map(|s| s.to_string()),
6267
})))
6368
}
6469
Expression::Identifier(identifier) => {
@@ -69,6 +74,7 @@ fn extract_style_prop_from_express<'a>(
6974
level,
7075
property: name.to_string(),
7176
identifier: identifier.name.to_string(),
77+
selector: selector.map(|s| s.to_string()),
7278
})))
7379
}
7480
}
@@ -81,6 +87,7 @@ fn extract_style_prop_from_express<'a>(
8187
name,
8288
&logical.right,
8389
level,
90+
selector,
8491
)
8592
.map(Box::new),
8693
}),
@@ -91,6 +98,7 @@ fn extract_style_prop_from_express<'a>(
9198
name,
9299
&logical.right,
93100
level,
101+
selector,
94102
)
95103
.map(Box::new),
96104
alternate: None,
@@ -120,18 +128,29 @@ fn extract_style_prop_from_express<'a>(
120128
name,
121129
&logical.right,
122130
level,
131+
selector,
123132
)
124133
.map(Box::new),
125134
}),
126135
},
127-
Expression::ParenthesizedExpression(parenthesized) => {
128-
extract_style_prop_from_express(ast_builder, name, &parenthesized.expression, level)
129-
}
136+
Expression::ParenthesizedExpression(parenthesized) => extract_style_prop_from_express(
137+
ast_builder,
138+
name,
139+
&parenthesized.expression,
140+
level,
141+
selector,
142+
),
130143
Expression::ArrayExpression(array) => {
131-
extract_style_prop_from_array_express(ast_builder, name, array)
144+
extract_style_prop_from_array_express(ast_builder, name, array, selector)
132145
}
133146
Expression::ConditionalExpression(conditional) => {
134-
extract_style_prop_from_conditional_express(ast_builder, name, conditional, level)
147+
extract_style_prop_from_conditional_express(
148+
ast_builder,
149+
name,
150+
conditional,
151+
level,
152+
selector,
153+
)
135154
}
136155
_ => None,
137156
}
@@ -142,6 +161,7 @@ fn extract_style_prop_from_conditional_express<'a>(
142161
name: &str,
143162
conditional: &ConditionalExpression<'a>,
144163
level: u8,
164+
media: Option<&str>,
145165
) -> Option<ExtractStyleProp<'a>> {
146166
Some(ExtractStyleProp::Conditional {
147167
condition: conditional.test.clone_in(ast_builder.allocator),
@@ -150,13 +170,15 @@ fn extract_style_prop_from_conditional_express<'a>(
150170
name,
151171
&conditional.consequent,
152172
level,
173+
media,
153174
)
154175
.map(Box::new),
155176
alternate: extract_style_prop_from_express(
156177
ast_builder,
157178
name,
158179
&conditional.alternate,
159180
level,
181+
media,
160182
)
161183
.map(Box::new),
162184
})
@@ -166,13 +188,20 @@ fn extract_style_prop_from_array_express<'a>(
166188
ast_builder: &AstBuilder<'a>,
167189
name: &str,
168190
array: &ArrayExpression<'a>,
191+
selector: Option<&str>,
169192
) -> Option<ExtractStyleProp<'a>> {
170193
let ret = array
171194
.elements
172195
.iter()
173196
.enumerate()
174197
.filter_map(|(idx, element)| {
175-
extract_style_prop_from_express(ast_builder, name, element.to_expression(), idx as u8)
198+
extract_style_prop_from_express(
199+
ast_builder,
200+
name,
201+
element.to_expression(),
202+
idx as u8,
203+
selector,
204+
)
176205
})
177206
.collect::<Vec<ExtractStyleProp>>();
178207
if ret.is_empty() {

0 commit comments

Comments
 (0)