diff --git a/__tests__/applyComplexClasses.test.js b/__tests__/applyComplexClasses.test.js index f2de66800..9037e1a8c 100644 --- a/__tests__/applyComplexClasses.test.js +++ b/__tests__/applyComplexClasses.test.js @@ -848,3 +848,35 @@ test('you can apply utility classes when a selector is used for the important op expect(result.warnings().length).toBe(0) }) }) + +test('you can apply classes to a rule with multiple selectors', () => { + const input = ` + @supports (display: grid) { + .foo, h1 > .bar * { + @apply float-left opacity-50 hover:opacity-100 md:float-right; + } + } + ` + + const expected = ` + @supports (display: grid) { + .foo, h1 > .bar * { + float: left; + opacity: 0.5; + } + .foo:hover, h1 > .bar *:hover { + opacity: 1; + } + @media (min-width: 768px) { + .foo, h1 > .bar * { + float: right; + } + } + } + ` + + return run(input).then(result => { + expect(result.css).toMatchCss(expected) + expect(result.warnings().length).toBe(0) + }) +}) diff --git a/src/flagged/applyComplexClasses.js b/src/flagged/applyComplexClasses.js index 820f2422f..54274d480 100644 --- a/src/flagged/applyComplexClasses.js +++ b/src/flagged/applyComplexClasses.js @@ -1,4 +1,4 @@ -import _ from 'lodash' +import _, { replace } from 'lodash' import selectorParser from 'postcss-selector-parser' import postcss from 'postcss' import substituteTailwindAtRules from '../lib/substituteTailwindAtRules' @@ -39,7 +39,7 @@ const tailwindApplyPlaceholder = selectorParser.attribute({ attribute: '__TAILWIND-APPLY-PLACEHOLDER__', }) -function generateRulesFromApply({ rule, utilityName: className, classPosition }, replaceWith) { +function generateRulesFromApply({ rule, utilityName: className, classPosition }, replaceWiths) { const parser = selectorParser(selectors => { let i = 0 selectors.walkClasses(c => { @@ -49,11 +49,13 @@ function generateRulesFromApply({ rule, utilityName: className, classPosition }, }) }) - const processedSelectors = rule.selectors.map(selector => { + const processedSelectors = _.flatMap(rule.selectors, selector => { // You could argue we should make this replacement at the AST level, but if we believe // the placeholder string is safe from collisions then it is safe to do this is a simple // string replacement, and much, much faster. - return parser.processSync(selector).replace('[__TAILWIND-APPLY-PLACEHOLDER__]', replaceWith) + return replaceWiths.map(replaceWith => + parser.processSync(selector).replace('[__TAILWIND-APPLY-PLACEHOLDER__]', replaceWith) + ) }) const cloned = rule.clone() @@ -242,7 +244,7 @@ function processApplyAtRules(css, lookupTree, config) { // Get new rules with the utility portion of the selector replaced with the new selector const rulesToInsert = [ ...applys.map(applyUtility => { - return generateRulesFromApply(applyUtility, rule.selector) + return generateRulesFromApply(applyUtility, rule.selectors) }), afterRule, ]