v3: Remove irrelevant utility rules when matching important classes (#19030)
Fixes #18678 When given a simple plugin like this: ```js export default { content: [{ raw: '!a' },], plugins: [ ({ addBase }) => addBase({ '@media (min-width: 1728px)': { '.a': { 'padding-top': '1rem !important' }, '.b': { 'padding-right': '1rem !important' }, } }), ], } ``` If this plugin saw the utility `!a` it would correctly modify both rules to eliminate any irrelevant classes. Unfortunately, in the case of the 2nd rule this meant it's left with an empty selector which is invalid. We now detect this case and remove the rule if that happens.
This commit is contained in:
parent
ba55a445cd
commit
aecc8521dc
3 changed files with 158 additions and 1 deletions
|
|
@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Fix `require.cache` error when loaded through a TypeScript file in Node 22.18+ ([#18665](https://github.com/tailwindlabs/tailwindcss/pull/18665))
|
||||
- Support `import.meta.resolve(…)` in configs for new enough Node.js versions ([#18938](https://github.com/tailwindlabs/tailwindcss/pull/18938))
|
||||
- Allow using newer versions of `postcss-load-config` for better ESM and TypeScript PostCSS config support with the CLI ([#18938](https://github.com/tailwindlabs/tailwindcss/pull/18938))
|
||||
- Remove irrelevant utility rules when matching important classes ([#19030](https://github.com/tailwindlabs/tailwindcss/pull/19030))
|
||||
|
||||
## [3.4.17] - 2024-12-17
|
||||
|
||||
|
|
|
|||
|
|
@ -143,7 +143,14 @@ function applyImportant(matches, classCandidate) {
|
|||
className === classCandidate ? `!${className}` : className
|
||||
)
|
||||
|
||||
r.selector = ast.toString()
|
||||
let newSelector = ast.toString()
|
||||
|
||||
if (newSelector.trim() === '') {
|
||||
r.remove()
|
||||
return
|
||||
}
|
||||
|
||||
r.selector = newSelector
|
||||
|
||||
r.walkDecls((d) => (d.important = true))
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1914,3 +1914,152 @@ test('custom properties are not converted to kebab-case when added to base layer
|
|||
expect(result.css).toContain(`--colors-primaryThing-500: 0, 0, 255;`)
|
||||
})
|
||||
})
|
||||
|
||||
test('important candidates discard rules with irrelevant selectors', async () => {
|
||||
let config = {
|
||||
content: [{ raw: '!a1 !b1 !c1' }],
|
||||
corePlugins: { preflight: false },
|
||||
plugins: [
|
||||
({ addBase }) => {
|
||||
addBase({
|
||||
'@media (min-width: 1728px)': {
|
||||
'.a1': { 'padding-top': '1rem !important' },
|
||||
'.a2': { 'padding-right': '1rem !important' },
|
||||
},
|
||||
})
|
||||
|
||||
addBase({
|
||||
'@media (min-width: 1728px)': { '.b1': { 'padding-top': '1rem !important' } },
|
||||
'@media (min-width: 1729px)': { '.b2': { 'padding-right': '1rem !important' } },
|
||||
})
|
||||
|
||||
addBase({
|
||||
'.c1': { '@media (min-width: 1728px)': { 'padding-top': '1rem !important' } },
|
||||
'.c2': { '@media (min-width: 1728px)': { 'padding-right': '1rem !important' } },
|
||||
})
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
let result = await run('@tailwind base', config)
|
||||
|
||||
expect(result.css).toMatchInlineSnapshot(`
|
||||
"*, ::before, ::after {
|
||||
--tw-border-spacing-x: 0;
|
||||
--tw-border-spacing-y: 0;
|
||||
--tw-translate-x: 0;
|
||||
--tw-translate-y: 0;
|
||||
--tw-rotate: 0;
|
||||
--tw-skew-x: 0;
|
||||
--tw-skew-y: 0;
|
||||
--tw-scale-x: 1;
|
||||
--tw-scale-y: 1;
|
||||
--tw-pan-x: ;
|
||||
--tw-pan-y: ;
|
||||
--tw-pinch-zoom: ;
|
||||
--tw-scroll-snap-strictness: proximity;
|
||||
--tw-gradient-from-position: ;
|
||||
--tw-gradient-via-position: ;
|
||||
--tw-gradient-to-position: ;
|
||||
--tw-ordinal: ;
|
||||
--tw-slashed-zero: ;
|
||||
--tw-numeric-figure: ;
|
||||
--tw-numeric-spacing: ;
|
||||
--tw-numeric-fraction: ;
|
||||
--tw-ring-inset: ;
|
||||
--tw-ring-offset-width: 0px;
|
||||
--tw-ring-offset-color: #fff;
|
||||
--tw-ring-color: rgb(59 130 246 / 0.5);
|
||||
--tw-ring-offset-shadow: 0 0 #0000;
|
||||
--tw-ring-shadow: 0 0 #0000;
|
||||
--tw-shadow: 0 0 #0000;
|
||||
--tw-shadow-colored: 0 0 #0000;
|
||||
--tw-blur: ;
|
||||
--tw-brightness: ;
|
||||
--tw-contrast: ;
|
||||
--tw-grayscale: ;
|
||||
--tw-hue-rotate: ;
|
||||
--tw-invert: ;
|
||||
--tw-saturate: ;
|
||||
--tw-sepia: ;
|
||||
--tw-drop-shadow: ;
|
||||
--tw-backdrop-blur: ;
|
||||
--tw-backdrop-brightness: ;
|
||||
--tw-backdrop-contrast: ;
|
||||
--tw-backdrop-grayscale: ;
|
||||
--tw-backdrop-hue-rotate: ;
|
||||
--tw-backdrop-invert: ;
|
||||
--tw-backdrop-opacity: ;
|
||||
--tw-backdrop-saturate: ;
|
||||
--tw-backdrop-sepia: ;
|
||||
--tw-contain-size: ;
|
||||
--tw-contain-layout: ;
|
||||
--tw-contain-paint: ;
|
||||
--tw-contain-style:
|
||||
}
|
||||
::backdrop {
|
||||
--tw-border-spacing-x: 0;
|
||||
--tw-border-spacing-y: 0;
|
||||
--tw-translate-x: 0;
|
||||
--tw-translate-y: 0;
|
||||
--tw-rotate: 0;
|
||||
--tw-skew-x: 0;
|
||||
--tw-skew-y: 0;
|
||||
--tw-scale-x: 1;
|
||||
--tw-scale-y: 1;
|
||||
--tw-pan-x: ;
|
||||
--tw-pan-y: ;
|
||||
--tw-pinch-zoom: ;
|
||||
--tw-scroll-snap-strictness: proximity;
|
||||
--tw-gradient-from-position: ;
|
||||
--tw-gradient-via-position: ;
|
||||
--tw-gradient-to-position: ;
|
||||
--tw-ordinal: ;
|
||||
--tw-slashed-zero: ;
|
||||
--tw-numeric-figure: ;
|
||||
--tw-numeric-spacing: ;
|
||||
--tw-numeric-fraction: ;
|
||||
--tw-ring-inset: ;
|
||||
--tw-ring-offset-width: 0px;
|
||||
--tw-ring-offset-color: #fff;
|
||||
--tw-ring-color: rgb(59 130 246 / 0.5);
|
||||
--tw-ring-offset-shadow: 0 0 #0000;
|
||||
--tw-ring-shadow: 0 0 #0000;
|
||||
--tw-shadow: 0 0 #0000;
|
||||
--tw-shadow-colored: 0 0 #0000;
|
||||
--tw-blur: ;
|
||||
--tw-brightness: ;
|
||||
--tw-contrast: ;
|
||||
--tw-grayscale: ;
|
||||
--tw-hue-rotate: ;
|
||||
--tw-invert: ;
|
||||
--tw-saturate: ;
|
||||
--tw-sepia: ;
|
||||
--tw-drop-shadow: ;
|
||||
--tw-backdrop-blur: ;
|
||||
--tw-backdrop-brightness: ;
|
||||
--tw-backdrop-contrast: ;
|
||||
--tw-backdrop-grayscale: ;
|
||||
--tw-backdrop-hue-rotate: ;
|
||||
--tw-backdrop-invert: ;
|
||||
--tw-backdrop-opacity: ;
|
||||
--tw-backdrop-saturate: ;
|
||||
--tw-backdrop-sepia: ;
|
||||
--tw-contain-size: ;
|
||||
--tw-contain-layout: ;
|
||||
--tw-contain-paint: ;
|
||||
--tw-contain-style:
|
||||
}
|
||||
@media (min-width: 1728px) {
|
||||
.\\!a1 {
|
||||
padding-top: 1rem !important
|
||||
}
|
||||
.\\!b1 {
|
||||
padding-top: 1rem !important
|
||||
}
|
||||
.\\!c1 {
|
||||
padding-top: 1rem !important
|
||||
}
|
||||
}"
|
||||
`)
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue