From f7a9d370c87f0d804c8b5924e1f04eb7ad82cd33 Mon Sep 17 00:00:00 2001 From: Adam Wathan Date: Fri, 25 Feb 2022 13:17:44 -0500 Subject: [PATCH] Only add `!` to selector class matching template candidate (#7664) * Only add `!` to selector class matching template candidate Fixes #7226. Before this PR, if you had a class like: ```css .one .two { background: black } ``` ...and then used `!one` in your template, the generated CSS would be this: ```css .\!one .\!two { background: black !important } ``` This would cause the styles to not be applied unless you also added `!` to the beginning of other classes in the template that are part of this selector. This PR makes sure that other classes in the selector aren't mistakenly prefixed with `!`, so that you can add `!` to only one of the classes in your template and get the expected result. * Update CHANGELOG --- CHANGELOG.md | 1 + src/lib/generateRules.js | 9 ++++++--- tests/important-modifier.test.js | 19 +++++++++++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d1b7c61d2293..104e4324bdfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Split box shadows on top-level commas only ([#7479](https://github.com/tailwindlabs/tailwindcss/pull/7479)) - Use local user CSS cache for `@apply` ([#7524](https://github.com/tailwindlabs/tailwindcss/pull/7524)) - Invalidate context when main CSS changes ([#7626](https://github.com/tailwindlabs/tailwindcss/pull/7626)) +- Only add `!` to selector class matching template candidate when using important modifier with mutli-class selectors ([#7664](https://github.com/tailwindlabs/tailwindcss/pull/7664)) ### Changed diff --git a/src/lib/generateRules.js b/src/lib/generateRules.js index 40322cd15d53..1ff2800cf562 100644 --- a/src/lib/generateRules.js +++ b/src/lib/generateRules.js @@ -88,7 +88,7 @@ function applyPrefix(matches, context) { return matches } -function applyImportant(matches) { +function applyImportant(matches, classCandidate) { if (matches.length === 0) { return matches } @@ -98,7 +98,10 @@ function applyImportant(matches) { let container = postcss.root({ nodes: [rule.clone()] }) container.walkRules((r) => { r.selector = updateAllClasses(r.selector, (className) => { - return `!${className}` + if (className === classCandidate) { + return `!${className}` + } + return className }) r.walkDecls((d) => (d.important = true)) }) @@ -514,7 +517,7 @@ function* resolveMatches(candidate, context) { matches = applyPrefix(matches, context) if (important) { - matches = applyImportant(matches, context) + matches = applyImportant(matches, classCandidate) } for (let variant of variants) { diff --git a/tests/important-modifier.test.js b/tests/important-modifier.test.js index d25d66190c46..e57c81340575 100644 --- a/tests/important-modifier.test.js +++ b/tests/important-modifier.test.js @@ -17,6 +17,22 @@ test('important modifier', () => { }, ], corePlugins: { preflight: false }, + plugins: [ + function ({ theme, matchUtilities }) { + matchUtilities( + { + 'custom-parent': (value) => { + return { + '.custom-child': { + margin: value, + }, + } + }, + }, + { values: theme('spacing') } + ) + }, + ], } let input = css` @@ -57,6 +73,9 @@ test('important modifier', () => { .\!font-bold { font-weight: 700 !important; } + .\!custom-parent-5 .custom-child { + margin: 1.25rem !important; + } .hover\:\!text-center:hover { text-align: center !important; }