diff --git a/__tests__/variantsAtRule.test.js b/__tests__/variantsAtRule.test.js index af81375e5..71831d240 100644 --- a/__tests__/variantsAtRule.test.js +++ b/__tests__/variantsAtRule.test.js @@ -218,6 +218,27 @@ test('variants are generated in the order specified', () => { }) }) +test('the built-in variant pseudo-selectors are appended before any pseudo-elements', () => { + const input = ` + @variants hover, focus-within, focus, active { + .placeholder-yellow::placeholder { color: yellow; } + } + ` + + const output = ` + .placeholder-yellow::placeholder { color: yellow; } + .hover\\:placeholder-yellow:hover::placeholder { color: yellow; } + .focus-within\\:placeholder-yellow:focus-within::placeholder { color: yellow; } + .focus\\:placeholder-yellow:focus::placeholder { color: yellow; } + .active\\:placeholder-yellow:active::placeholder { color: yellow; } + ` + + return run(input).then(result => { + expect(result.css).toMatchCss(output) + expect(result.warnings().length).toBe(0) + }) +}) + test('the default variant can be generated in a specified position', () => { const input = ` @variants focus, active, default, hover { diff --git a/src/lib/substituteVariantsAtRules.js b/src/lib/substituteVariantsAtRules.js index 73981d6c3..3de1cb70b 100644 --- a/src/lib/substituteVariantsAtRules.js +++ b/src/lib/substituteVariantsAtRules.js @@ -1,12 +1,18 @@ import _ from 'lodash' import postcss from 'postcss' +import selectorParser from 'postcss-selector-parser' import generateVariantFunction from '../util/generateVariantFunction' import e from '../util/escapeClassName' function generatePseudoClassVariant(pseudoClass) { return generateVariantFunction(({ modifySelectors, separator }) => { - return modifySelectors(({ className }) => { - return `.${e(`${pseudoClass}${separator}${className}`)}:${pseudoClass}` + return modifySelectors(({ selector }) => { + return selectorParser(selectors => { + selectors.walkClasses(sel => { + sel.value = `${pseudoClass}${separator}${sel.value}` + sel.parent.insertAfter(sel, selectorParser.pseudo({ value: `:${pseudoClass}` })) + }) + }).processSync(selector) }) }) }