diff --git a/__tests__/fixtures/tailwind-input.css b/__tests__/fixtures/tailwind-input.css index ac3999689618..6aa8012f6399 100644 --- a/__tests__/fixtures/tailwind-input.css +++ b/__tests__/fixtures/tailwind-input.css @@ -5,6 +5,13 @@ @responsive { .example { @apply .font-bold; + @apply .delete-me; color: config('colors.red'); } } + +@silent { + .delete-me { + background-color: blue; + } +} diff --git a/__tests__/fixtures/tailwind-output.css b/__tests__/fixtures/tailwind-output.css index 80f04b802cf6..44dda9d616fa 100644 --- a/__tests__/fixtures/tailwind-output.css +++ b/__tests__/fixtures/tailwind-output.css @@ -3547,6 +3547,7 @@ button, .example { font-weight: 700; + background-color: blue; color: #e3342f; } @@ -6511,6 +6512,7 @@ button, .sm\:example { font-weight: 700; + background-color: blue; color: #e3342f; } } @@ -9476,6 +9478,7 @@ button, .md\:example { font-weight: 700; + background-color: blue; color: #e3342f; } } @@ -12441,6 +12444,7 @@ button, .lg\:example { font-weight: 700; + background-color: blue; color: #e3342f; } } @@ -15406,6 +15410,7 @@ button, .xl\:example { font-weight: 700; + background-color: blue; color: #e3342f; } } diff --git a/__tests__/silentAtRule.test.js b/__tests__/silentAtRule.test.js new file mode 100644 index 000000000000..734719802ac4 --- /dev/null +++ b/__tests__/silentAtRule.test.js @@ -0,0 +1,55 @@ +import _ from 'lodash' +import postcss from 'postcss' +import tailwind from '../src/index' + +it('removes silenced rules while still making them available to @apply', () => { + const input = _.trim(` +@silent { + @responsive { + .foo { + color: red; + } + } + @tailwind screens; +} + + +.bar { + @apply .foo; +} + `) + + const expected = _.trim(` +.bar { + color: red; +} + `) + + return postcss([tailwind()]) + .process(input) + .then(result => { + expect(result.css).toBe(expected) + }) +}) + +it('throws an error if @silent is used anywhere but the root of the tree', () => { + const input = _.trim(` +@media (min-width: 100px) { + @silent { + .foo { + color: red; + } + } + .bar { + @apply .foo; + } +} + `) + + expect.assertions(1) + return postcss([tailwind()]) + .process(input) + .catch(e => { + expect(e).toMatchObject({ name: 'CssSyntaxError' }) + }) +}) diff --git a/src/index.js b/src/index.js index bf8fb76aa290..719a96e0ba13 100644 --- a/src/index.js +++ b/src/index.js @@ -13,6 +13,7 @@ import substituteFocusableAtRules from './lib/substituteFocusableAtRules' import substituteResponsiveAtRules from './lib/substituteResponsiveAtRules' import substituteScreenAtRules from './lib/substituteScreenAtRules' import substituteClassApplyAtRules from './lib/substituteClassApplyAtRules' +import substituteSilentAtRules from './lib/substituteSilentAtRules' const plugin = postcss.plugin('tailwind', config => { const plugins = [] @@ -41,6 +42,7 @@ const plugin = postcss.plugin('tailwind', config => { substituteResponsiveAtRules(lazyConfig), substituteScreenAtRules(lazyConfig), substituteClassApplyAtRules(lazyConfig), + substituteSilentAtRules(lazyConfig), stylefmt, ] ) diff --git a/src/lib/substituteSilentAtRules.js b/src/lib/substituteSilentAtRules.js new file mode 100644 index 000000000000..a68919450e99 --- /dev/null +++ b/src/lib/substituteSilentAtRules.js @@ -0,0 +1,11 @@ +export default function() { + return function(css) { + css.walkAtRules('silent', atRule => { + if (atRule.parent.type !== 'root') { + throw atRule.error(`@silent at-rules cannot be nested.`) + } + + atRule.remove() + }) + } +} diff --git a/src/util/findMixin.js b/src/util/findMixin.js index 1460ea81204e..5b21b36af63d 100644 --- a/src/util/findMixin.js +++ b/src/util/findMixin.js @@ -1,10 +1,18 @@ import _ from 'lodash' +function ruleIsValidMixin(rule) { + if (rule.parent.type === 'root') { + return true + } + + return rule.parent.type === 'atrule' && ['silent'].includes(rule.parent.name) +} + export default function findMixin(css, mixin, onError) { const matches = [] css.walkRules(rule => { - if (rule.selectors.includes(mixin) && rule.parent.type === 'root') { + if (rule.selectors.includes(mixin) && ruleIsValidMixin(rule)) { matches.push(rule) } })