@@ -237,42 +237,44 @@ const callbackIfFileIncluded = (meta: Metadata, next: Metadata) => {
237
237
* @param meta {Metadata} Useful metadata that can be used during the transformation
238
238
*/
239
239
const extractConditionalExpression = ( node : t . ConditionalExpression , meta : Metadata ) : CSSOutput => {
240
- const variables : CSSOutput [ 'variables' ] = [ ] ;
241
- const css : CSSOutput [ 'css' ] = [ ] ;
242
- let logicalItem : LogicalCssItem [ ] = [ ] ;
243
-
244
- if ( t . isObjectExpression ( node . consequent ) ) {
245
- const consequent = buildCss ( node . consequent , meta ) ;
246
- logicalItem = getLogicalItemFromConditionalExpression ( consequent . css , node , 'consequent' ) ;
240
+ const conditionalPaths : [ 'consequent' , 'alternate' ] = [ 'consequent' , 'alternate' ] ;
241
+ const css = [ ] ;
242
+ const variables = [ ] ;
247
243
248
- css . push ( ... logicalItem ) ;
249
- variables . push ( ... consequent . variables ) ;
250
- } else if ( t . isIdentifier ( node . consequent ) ) {
251
- const { value : interpolation , meta : updatedMeta } = evaluateExpression ( node . consequent , meta ) ;
244
+ for ( const path of conditionalPaths ) {
245
+ const pathNode = node [ path ] ;
246
+ let buildOutput ;
247
+ let newCssItems ;
252
248
253
- if ( isCompiledCSSTemplateLiteral ( interpolation , updatedMeta ) ) {
254
- const consequent = buildCss ( interpolation , updatedMeta ) ;
255
- logicalItem = getLogicalItemFromConditionalExpression ( consequent . css , node , 'consequent' ) ;
256
-
257
- css . push ( ...logicalItem ) ;
258
- variables . push ( ...consequent . variables ) ;
249
+ if (
250
+ t . isObjectExpression ( pathNode ) ||
251
+ // Check if string resembles CSS `property: value`
252
+ ( t . isStringLiteral ( pathNode ) && pathNode . value . includes ( ':' ) ) ||
253
+ t . isTemplateLiteral ( pathNode ) ||
254
+ isCompiledCSSTemplateLiteral ( pathNode , meta ) ||
255
+ isCompiledCSSCallExpression ( pathNode , meta )
256
+ ) {
257
+ buildOutput = buildCss ( pathNode , meta ) ;
258
+ newCssItems =
259
+ // Only mark truthy(consequent) condition as conditional CSS.
260
+ // Falsey(alternate) will always be added to serve as default values
261
+ path === 'consequent'
262
+ ? getLogicalItemFromConditionalExpression ( buildOutput . css , node , path )
263
+ : buildOutput . css ;
264
+ } else if ( t . isIdentifier ( pathNode ) ) {
265
+ const { value : interpolation , meta : updatedMeta } = evaluateExpression ( pathNode , meta ) ;
266
+
267
+ if (
268
+ isCompiledCSSTemplateLiteral ( interpolation , updatedMeta ) ||
269
+ isCompiledCSSCallExpression ( interpolation , updatedMeta )
270
+ ) {
271
+ buildOutput = buildCss ( interpolation , updatedMeta ) ;
272
+ newCssItems = getLogicalItemFromConditionalExpression ( buildOutput . css , node , path ) ;
273
+ }
259
274
}
260
- }
261
-
262
- if ( t . isObjectExpression ( node . alternate ) ) {
263
- const alternate = extractObjectExpression ( node . alternate , meta ) ;
264
275
265
- css . push ( ...alternate . css ) ;
266
- variables . push ( ...alternate . variables ) ;
267
- } else if ( t . isIdentifier ( node . alternate ) ) {
268
- const { value : interpolation , meta : updatedMeta } = evaluateExpression ( node . alternate , meta ) ;
269
- if ( isCompiledCSSTemplateLiteral ( interpolation , updatedMeta ) ) {
270
- const alternate = buildCss ( interpolation , updatedMeta ) ;
271
- logicalItem = getLogicalItemFromConditionalExpression ( alternate . css , node , 'alternate' ) ;
272
-
273
- css . push ( ...logicalItem ) ;
274
- variables . push ( ...alternate . variables ) ;
275
- }
276
+ css . push ( ...( newCssItems || [ ] ) ) ;
277
+ variables . push ( ...( buildOutput ?. variables ?? [ ] ) ) ;
276
278
}
277
279
278
280
return { css : mergeSubsequentUnconditionalCssItems ( css ) , variables } ;
@@ -485,36 +487,38 @@ const extractTemplateLiteral = (node: t.TemplateLiteral, meta: Metadata): CSSOut
485
487
if (
486
488
t . isObjectExpression ( interpolation ) ||
487
489
isCompiledCSSTemplateLiteral ( interpolation , meta ) ||
490
+ isCompiledCSSCallExpression ( interpolation , meta ) ||
488
491
( t . isArrowFunctionExpression ( nodeExpression ) &&
489
492
t . isConditionalExpression ( nodeExpression . body ) )
490
493
) {
491
494
// We found something that looks like CSS.
492
495
const result = buildCss ( interpolation , updatedMeta ) ;
493
- css . push ( ...result . css ) ;
494
- variables . push ( ...result . variables ) ;
495
-
496
- if ( ! t . isArrowFunctionExpression ( nodeExpression ) && quasi . hasOwnProperty ( 'value' ) ) {
497
- // To ensure that CSS is generated for declaration before a mixin
498
- return acc + quasi . value . raw ;
499
- }
500
496
501
- if ( result . css . length > 0 ) {
502
- return acc ;
497
+ if ( result . css . length ) {
498
+ // Add previous accumulative CSS first before CSS from expressions
499
+ css . push ( { type : 'unconditional' , css : acc + quasi . value . raw } , ...result . css ) ;
500
+ variables . push ( ...result . variables ) ;
501
+ // Reset acc as we just added them
502
+ return '' ;
503
503
}
504
504
}
505
505
506
506
if (
507
507
isCompiledKeyframesCallExpression ( interpolation , updatedMeta ) ||
508
508
isCompiledKeyframesTaggedTemplateExpression ( interpolation , updatedMeta )
509
509
) {
510
- const result = extractKeyframes ( interpolation , {
510
+ const {
511
+ css : [ keyframesSheet , unconditionalKeyframesItem ] ,
512
+ variables : keyframeVariables ,
513
+ } = extractKeyframes ( interpolation , {
511
514
...updatedMeta ,
512
515
prefix : quasi . value . raw ,
513
516
suffix : '' ,
514
517
} ) ;
515
- css . push ( ...result . css ) ;
516
- variables . push ( ...result . variables ) ;
517
- return acc ;
518
+
519
+ css . push ( keyframesSheet ) ;
520
+ variables . push ( ...keyframeVariables ) ;
521
+ return acc + unconditionalKeyframesItem . css ;
518
522
}
519
523
520
524
const { expression, variableName } = getVariableDeclaratorValueForOwnPath ( nodeExpression , meta ) ;
0 commit comments