From 1e0fc09e0a634868398d1f303ba13f4fa37a5c02 Mon Sep 17 00:00:00 2001 From: Stefan Fisk Date: Thu, 26 Nov 2020 14:53:58 +0100 Subject: [PATCH] Fix !important on multiple selectors #2823 (#2824) * Add failing test for #2823 * cleanup string literals * use prettier for toMatchCSS diffs * make sure that importants are applied correctly Co-authored-by: Robin Malfait --- __tests__/applyAtRule.test.js | 74 +++++++++++++++++++------- jest/customMatchers.js | 1 - src/lib/substituteClassApplyAtRules.js | 14 ++++- 3 files changed, 68 insertions(+), 21 deletions(-) diff --git a/__tests__/applyAtRule.test.js b/__tests__/applyAtRule.test.js index 4cab89e1f36a..36a8629312a3 100644 --- a/__tests__/applyAtRule.test.js +++ b/__tests__/applyAtRule.test.js @@ -1002,14 +1002,10 @@ describe('using apply with the prefix option', () => { test('a "Did You Mean" suggestion is omitted if a similar class cannot be identified.', () => { const input = ` - .foo { @apply anteater; } - ` + .foo { @apply anteater; } + ` - const config = resolveConfig([ - { - ...defaultConfig, - }, - ]) + const config = resolveConfig([{ ...defaultConfig }]) expect.assertions(1) @@ -1109,7 +1105,7 @@ test('you can apply classes to a rule with multiple selectors', () => { @apply float-left opacity-50 hover:opacity-100 md:float-right; } } - ` + ` const expected = ` @supports (display: grid) { @@ -1134,6 +1130,48 @@ test('you can apply classes to a rule with multiple selectors', () => { }) }) +test('you can apply classes to a rule with multiple selectors with important and a prefix enabled', () => { + const input = ` + @supports (display: grid) { + .foo, h1 > .bar * { + @apply tw-float-left tw-opacity-50 hover:tw-opacity-100 md:tw-float-right; + } + } + ` + + const expected = ` + @supports (display: grid) { + .foo, h1 > .bar * { + float: left; + opacity: 0.5; + } + + .foo:hover, h1 > .bar *:hover { + opacity: 1; + } + + @media (min-width: 768px) { + .foo, h1 > .bar * { + float: right; + } + } + } + ` + + const config = resolveConfig([ + { + ...defaultConfig, + prefix: 'tw-', + important: true, + }, + ]) + + return run(input, config).then((result) => { + expect(result.css).toMatchCss(expected) + expect(result.warnings().length).toBe(0) + }) +}) + test('you can apply classes in a nested rule', () => { const input = ` .selector { @@ -1241,11 +1279,11 @@ test('declarations within a rule that uses @apply can be !important', () => { ` const expected = ` - .foo { - text-align: center; - float: left; - display: block !important; - } + .foo { + text-align: center; + float: left; + display: block !important; + } ` expect.assertions(2) @@ -1266,11 +1304,11 @@ test('declarations within a rule that uses @apply with !important remain not !im ` const expected = ` - .foo { - text-align: center !important; - float: left; - display: block !important; - } + .foo { + text-align: center !important; + float: left; + display: block !important; + } ` expect.assertions(2) diff --git a/jest/customMatchers.js b/jest/customMatchers.js index 32fbd588674f..e5e5b4348566 100644 --- a/jest/customMatchers.js +++ b/jest/customMatchers.js @@ -2,7 +2,6 @@ import prettier from 'prettier' import diff from 'jest-diff' function format(input) { - return input return prettier.format(input, { parser: 'css', printWidth: 100, diff --git a/src/lib/substituteClassApplyAtRules.js b/src/lib/substituteClassApplyAtRules.js index 9763118c4fa7..95e4bce3165e 100644 --- a/src/lib/substituteClassApplyAtRules.js +++ b/src/lib/substituteClassApplyAtRules.js @@ -242,11 +242,21 @@ function processApplyAtRules(css, lookupTree, config) { : (util) => util.rule.nodes.forEach((n) => afterRule.append(n.clone())) ) - const { nodes } = _.tap(postcss.root({ nodes: rulesToInsert }), (root) => + rulesToInsert.forEach((rule) => { + if (rule.type === 'atrule') { + rule.walkRules((rule) => { + rule.__tailwind = { ...rule.__tailwind, important } + }) + } else { + rule.__tailwind = { ...rule.__tailwind, important } + } + }) + + const { nodes } = _.tap(postcss.root({ nodes: rulesToInsert }), (root) => { root.walkDecls((d) => { d.important = important }) - ) + }) const mergedRules = mergeAdjacentRules(nearestParentRule, [...nodes, afterRule])