From 2fdbe108cb39831a28295db01f4337badb3d2387 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Fri, 17 Dec 2021 14:49:07 +0100 Subject: [PATCH] Only generate variants for non-`user` layers (#6589) * only generate variants for non-user layers If you have the following css: ```css @tailwind utilities; .foo { color: red; } ``` And you HTML looks like this: ```html
``` Then the output should _not_ generate a `.hover\:foo {}` class. * ensure that you can apply user csss (without variants) * update changelog --- CHANGELOG.md | 1 + src/lib/generateRules.js | 5 ++++ tests/apply.test.js | 58 ++++++++++++++++++++++++++++++++++++++++ tests/variants.test.js | 24 +++++++++++++++++ 4 files changed, 88 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9e349b8e5e4..b051bbf9dc9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Don't mutate custom color palette when overriding per-plugin colors ([#6546](https://github.com/tailwindlabs/tailwindcss/pull/6546)) - Improve circular dependency detection when using `@apply` ([#6588](https://github.com/tailwindlabs/tailwindcss/pull/6588)) +- Only generate variants for non-`user` layers ([#6589](https://github.com/tailwindlabs/tailwindcss/pull/6589)) ## [3.0.6] - 2021-12-16 diff --git a/src/lib/generateRules.js b/src/lib/generateRules.js index be479c4b6487..150bf6851732 100644 --- a/src/lib/generateRules.js +++ b/src/lib/generateRules.js @@ -112,6 +112,11 @@ function applyVariant(variant, matches, context) { let result = [] for (let [meta, rule] of matches) { + // Don't generate variants for user css + if (meta.layer === 'user') { + continue + } + let container = postcss.root({ nodes: [rule.clone()] }) for (let [variantSort, variantFunction] of variantFunctionTuples) { diff --git a/tests/apply.test.js b/tests/apply.test.js index 7b74286b4783..613e2af04a0c 100644 --- a/tests/apply.test.js +++ b/tests/apply.test.js @@ -654,3 +654,61 @@ it('rules with vendor prefixes are still separate when optimizing defaults rules `) }) }) + +it('should be possible to apply user css', () => { + let config = { + content: [{ raw: html`
` }], + plugins: [], + } + + let input = css` + @tailwind components; + @tailwind utilities; + + .foo { + color: red; + } + + .bar { + @apply foo; + } + ` + + return run(input, config).then((result) => { + return expect(result.css).toMatchFormattedCss(css` + .foo { + color: red; + } + + .bar { + color: red; + } + `) + }) +}) + +it('should not be possible to apply user css with variants', () => { + let config = { + content: [{ raw: html`
` }], + plugins: [], + } + + let input = css` + @tailwind components; + @tailwind utilities; + + .foo { + color: red; + } + + .bar { + @apply hover:foo; + } + ` + + return run(input, config).catch((err) => { + expect(err.reason).toBe( + 'The `hover:foo` class does not exist. If `hover:foo` is a custom class, make sure it is defined within a `@layer` directive.' + ) + }) +}) diff --git a/tests/variants.test.js b/tests/variants.test.js index 16f3c566fda4..a3bd43e44d68 100644 --- a/tests/variants.test.js +++ b/tests/variants.test.js @@ -421,3 +421,27 @@ test('before and after variants are a bit special, and forced to the end (2)', ( `) }) }) + +it('should not generate variants of user css if it is not inside a layer', () => { + let config = { + content: [{ raw: html`
` }], + plugins: [], + } + + let input = css` + @tailwind components; + @tailwind utilities; + + .foo { + color: red; + } + ` + + return run(input, config).then((result) => { + return expect(result.css).toMatchFormattedCss(css` + .foo { + color: red; + } + `) + }) +})