Skip to content

Commit

Permalink
Exclude non-relevant selectors when generating rules with the importa…
Browse files Browse the repository at this point in the history
…nt modifier. Fixes tailwindlabs#9677.
  • Loading branch information
cjpearson committed Nov 1, 2022
1 parent c936989 commit c024006
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Escape special characters in resolved content base paths ([#9650](https://github.com/tailwindlabs/tailwindcss/pull/9650))
- Don't reuse container for array returning variant functions ([#9644](https://github.com/tailwindlabs/tailwindcss/pull/9644))
- Exclude non-relevant selectors when generating rules with the important modifier ([#9677](https://github.com/tailwindlabs/tailwindcss/issues/9677))

## [3.2.1] - 2022-10-21

Expand Down
15 changes: 9 additions & 6 deletions src/lib/generateRules.js
Expand Up @@ -3,7 +3,7 @@ import selectorParser from 'postcss-selector-parser'
import parseObjectStyles from '../util/parseObjectStyles'
import isPlainObject from '../util/isPlainObject'
import prefixSelector from '../util/prefixSelector'
import { updateAllClasses, getMatchingTypes } from '../util/pluginUtils'
import { updateAllClasses, filterSelectorsForClass, getMatchingTypes } from '../util/pluginUtils'
import log from '../util/log'
import * as sharedState from './sharedState'
import { formatVariantSelector, finalizeSelector } from '../util/formatVariantSelector'
Expand Down Expand Up @@ -116,12 +116,15 @@ function applyImportant(matches, classCandidate) {
for (let [meta, rule] of matches) {
let container = postcss.root({ nodes: [rule.clone()] })
container.walkRules((r) => {
r.selector = updateAllClasses(r.selector, (className) => {
if (className === classCandidate) {
return `!${className}`
r.selector = updateAllClasses(
filterSelectorsForClass(r.selector, classCandidate),
(className) => {
if (className === classCandidate) {
return `!${className}`
}
return className
}
return className
})
)
r.walkDecls((d) => (d.important = true))
})
result.push([{ ...meta, important: true }, container.nodes[0]])
Expand Down
17 changes: 17 additions & 0 deletions src/util/pluginUtils.js
Expand Up @@ -37,6 +37,23 @@ export function updateAllClasses(selectors, updateClass) {
return result
}

export function filterSelectorsForClass(selectors, classCandidate) {
let parser = selectorParser((selectors) => {
selectors.each((sel) => {
const containsClass = sel.nodes.some(
(node) => node.type === 'class' && node.value === classCandidate
)
if (!containsClass) {
sel.remove()
}
})
})

let result = parser.processSync(selectors)

return result
}

function resolveArbitraryValue(modifier, validate) {
if (!isArbitraryValue(modifier)) {
return undefined
Expand Down
17 changes: 16 additions & 1 deletion tests/important-modifier.test.js
Expand Up @@ -13,12 +13,13 @@ test('important modifier', () => {
<div class="lg:!opacity-50"></div>
<div class="xl:focus:disabled:!float-right"></div>
<div class="!custom-parent-5"></div>
<div class="btn !disabled"></div>
`,
},
],
corePlugins: { preflight: false },
plugins: [
function ({ theme, matchUtilities }) {
function ({ theme, matchUtilities, addComponents }) {
matchUtilities(
{
'custom-parent': (value) => {
Expand All @@ -31,6 +32,13 @@ test('important modifier', () => {
},
{ values: theme('spacing') }
)
addComponents({
'.btn': {
'&.disabled, &:disabled': {
color: 'gray',
},
},
})
},
],
}
Expand Down Expand Up @@ -70,6 +78,13 @@ test('important modifier', () => {
max-width: 1536px !important;
}
}
.btn.disabled,
.btn:disabled {
color: gray;
}
.btn.\!disabled {
color: gray !important;
}
.\!font-bold {
font-weight: 700 !important;
}
Expand Down

0 comments on commit c024006

Please sign in to comment.