@@ -31,13 +31,13 @@ const updateMultipleClasses = (processor: Processor, classNames: string): string
31
31
} ;
32
32
33
33
/**
34
- * Parse and update classes of a js expression element
34
+ * Parse and update literal expression element
35
35
* @param processor: The CSS Module Processor
36
- * @param expression The expression node (consequent, alternate)
36
+ * @param expression The expression node
37
37
*/
38
- const parseExpression = (
38
+ const parseLiteralExpression = (
39
39
processor : Processor ,
40
- expression : AST . ExpressionTag [ 'expression' ]
40
+ expression : AST . ExpressionTag [ 'expression' ] | null
41
41
) : void => {
42
42
const exp = expression as typeof expression & AST . BaseNode ;
43
43
if ( exp . type === 'Literal' && typeof exp . value === 'string' ) {
@@ -46,6 +46,77 @@ const parseExpression = (
46
46
}
47
47
} ;
48
48
49
+ /**
50
+ * Parse and update conditional expression
51
+ * @param processor: The CSS Module Processor
52
+ * @param expression The expression node
53
+ */
54
+ const parseConditionalExpression = (
55
+ processor : Processor ,
56
+ expression : AST . ExpressionTag [ 'expression' ]
57
+ ) : void => {
58
+ if ( expression . type === 'ConditionalExpression' ) {
59
+ const { consequent, alternate } = expression ;
60
+ parseLiteralExpression ( processor , consequent ) ;
61
+ parseLiteralExpression ( processor , alternate ) ;
62
+ }
63
+ } ;
64
+
65
+ /**
66
+ * Parse and update object expression
67
+ * @param processor: The CSS Module Processor
68
+ * @param expression The expression node
69
+ */
70
+ const parseObjectExpression = (
71
+ processor : Processor ,
72
+ expression : AST . ExpressionTag [ 'expression' ]
73
+ ) : void => {
74
+ if ( expression . type === 'ObjectExpression' ) {
75
+ expression ?. properties . forEach ( ( property ) => {
76
+ if ( property . type === 'Property' ) {
77
+ const key = property . key as ( typeof property ) [ 'key' ] & AST . BaseNode ;
78
+
79
+ if ( property . shorthand ) {
80
+ if ( key . type === 'Identifier' ) {
81
+ processor . magicContent . overwrite (
82
+ key . start ,
83
+ key . end ,
84
+ `'${ processor . cssModuleList [ key . name ] } ': ${ key . name } `
85
+ ) ;
86
+ }
87
+ } else if ( key . type === 'Identifier' ) {
88
+ processor . magicContent . overwrite (
89
+ key . start ,
90
+ key . end ,
91
+ `'${ processor . cssModuleList [ key . name ] } '`
92
+ ) ;
93
+ } else if ( key . type !== 'PrivateIdentifier' ) {
94
+ parseLiteralExpression ( processor , key ) ;
95
+ }
96
+ }
97
+ } ) ;
98
+ }
99
+ } ;
100
+ /**
101
+ * Parse and update array expression
102
+ * @param processor: The CSS Module Processor
103
+ * @param expression The expression node
104
+ */
105
+ const parseArrayExpression = (
106
+ processor : Processor ,
107
+ expression : AST . ExpressionTag [ 'expression' ]
108
+ ) : void => {
109
+ if ( expression . type === 'ArrayExpression' ) {
110
+ expression . elements . forEach ( ( el ) => {
111
+ if ( el ?. type === 'LogicalExpression' ) {
112
+ parseLiteralExpression ( processor , el . right ) ;
113
+ } else if ( el ?. type !== 'SpreadElement' ) {
114
+ parseLiteralExpression ( processor , el ) ;
115
+ }
116
+ } ) ;
117
+ }
118
+ } ;
119
+
49
120
/**
50
121
* Add the dynamic variables to elements
51
122
* @param processor The CSS Module Processor
@@ -151,28 +222,25 @@ export default (processor: Processor): void => {
151
222
( node as AST . Component | AST . RegularElement ) . attributes . length > 0
152
223
) {
153
224
( node as AST . Component | AST . RegularElement ) . attributes . forEach ( ( item ) => {
154
- if (
155
- item . type === 'Attribute' &&
156
- allowedAttributes . includes ( item . name ) &&
157
- Array . isArray ( item . value )
158
- ) {
159
- item . value . forEach ( ( classItem ) => {
160
- if ( classItem . type === 'Text' && classItem . data . length > 0 ) {
161
- const generatedClassNames = updateMultipleClasses ( processor , classItem . data ) ;
162
- processor . magicContent . overwrite (
163
- classItem . start ,
164
- classItem . start + classItem . data . length ,
165
- generatedClassNames
166
- ) ;
167
- } else if (
168
- classItem . type === 'ExpressionTag' &&
169
- classItem ?. expression ?. type === 'ConditionalExpression'
170
- ) {
171
- const { consequent, alternate } = classItem . expression ;
172
- parseExpression ( processor , consequent ) ;
173
- parseExpression ( processor , alternate ) ;
174
- }
175
- } ) ;
225
+ if ( item . type === 'Attribute' && allowedAttributes . includes ( item . name ) ) {
226
+ if ( Array . isArray ( item . value ) ) {
227
+ item . value . forEach ( ( classItem ) => {
228
+ if ( classItem . type === 'Text' && classItem . data . length > 0 ) {
229
+ const generatedClassNames = updateMultipleClasses ( processor , classItem . data ) ;
230
+ processor . magicContent . overwrite (
231
+ classItem . start ,
232
+ classItem . start + classItem . data . length ,
233
+ generatedClassNames
234
+ ) ;
235
+ } else if ( classItem . type === 'ExpressionTag' ) {
236
+ parseConditionalExpression ( processor , classItem . expression ) ;
237
+ }
238
+ } ) ;
239
+ } else if ( typeof item . value === 'object' && item . value . type === 'ExpressionTag' ) {
240
+ parseObjectExpression ( processor , item . value . expression ) ;
241
+ parseArrayExpression ( processor , item . value . expression ) ;
242
+ parseConditionalExpression ( processor , item . value . expression ) ;
243
+ }
176
244
}
177
245
if ( item . type === 'ClassDirective' ) {
178
246
const classNames = item . name . split ( '.' ) ;
0 commit comments