diff --git a/src/lib/expandApplyAtRules.js b/src/lib/expandApplyAtRules.js index fa87052..0c1be5f 100644 --- a/src/lib/expandApplyAtRules.js +++ b/src/lib/expandApplyAtRules.js @@ -27,7 +27,6 @@ function buildApplyCache(applyCandidates, context) { return context.applyClassCache } -// TODO: Apply `!important` stuff correctly instead of just skipping it function extractApplyCandidates(params) { let candidates = params.split(/[\s\t\n]+/g) diff --git a/src/lib/generateRules.js b/src/lib/generateRules.js index e1d4950..ab013af 100644 --- a/src/lib/generateRules.js +++ b/src/lib/generateRules.js @@ -217,10 +217,19 @@ function generateRules(candidates, context) { } return allRules.flat(1).map(([{ sort, layer, options }, rule]) => { - if (context.tailwindConfig.important === true && options.respectImportant) { - rule.walkDecls((d) => { - d.important = true - }) + if (options.respectImportant) { + if (context.tailwindConfig.important === true && options.respectImportant) { + rule.walkDecls((d) => { + d.important = true + }) + } else if (typeof context.tailwindConfig.important === 'string') { + if (rule.type === 'rule') { + rule.selectors = rule.selectors.map((s) => `${context.tailwindConfig.important} ${s}`) + } + rule.walkRules((r) => { + r.selectors = r.selectors.map((s) => `${context.tailwindConfig.important} ${s}`) + }) + } } return [sort | context.layerOrder[layer], rule] }) diff --git a/tests/04-important-selector.test.css b/tests/04-important-selector.test.css new file mode 100644 index 0000000..122f0b2 --- /dev/null +++ b/tests/04-important-selector.test.css @@ -0,0 +1,71 @@ +* { + --tw-shadow: 0 0 #0000; + --tw-ring-inset: var(--tw-empty, /*!*/ /*!*/); + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgba(59, 130, 246, 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; +} +.container { + width: 100%; +} +@media (min-width: 640px) { + .container { + max-width: 640px; + } +} +@media (min-width: 768px) { + .container { + max-width: 768px; + } +} +@media (min-width: 1024px) { + .container { + max-width: 1024px; + } +} +@media (min-width: 1280px) { + .container { + max-width: 1280px; + } +} +@media (min-width: 1536px) { + .container { + max-width: 1536px; + } +} +#app .btn { + button: yes; +} +.custom-component { + font-weight: 700; +} +#app .custom-important-component { + text-align: center; +} +#app .font-bold { + font-weight: 700; +} +.custom-util { + button: no; +} +#app .group:hover .group-hover\:focus-within\:text-left:focus-within { + text-align: left; +} +#app [dir='rtl'] .rtl\:active\:text-center:active { + text-align: center; +} +@media (prefers-reduced-motion: no-preference) { + #app .motion-safe\:hover\:text-center:hover { + text-align: center; + } +} +#app .dark .dark\:focus\:text-left:focus { + text-align: left; +} +@media (min-width: 768px) { + #app .md\:hover\:text-right:hover { + text-align: right; + } +} diff --git a/tests/04-important-selector.test.html b/tests/04-important-selector.test.html new file mode 100644 index 0000000..5dfa917 --- /dev/null +++ b/tests/04-important-selector.test.html @@ -0,0 +1,11 @@ +
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/04-important-selector.test.js b/tests/04-important-selector.test.js new file mode 100644 index 0000000..a36291c --- /dev/null +++ b/tests/04-important-selector.test.js @@ -0,0 +1,59 @@ +const postcss = require('postcss') +const tailwind = require('../src/index.js') +const fs = require('fs') +const path = require('path') + +function run(input, config = {}) { + return postcss([tailwind(config)]).process(input, { from: path.resolve(__filename) }) +} + +test('important boolean', () => { + let config = { + important: '#app', + darkMode: 'class', + purge: [path.resolve(__dirname, './04-important-selector.test.html')], + corePlugins: { preflight: false }, + theme: {}, + plugins: [ + function ({ addComponents, addUtilities }) { + addComponents( + { + '.btn': { + button: 'yes', + }, + }, + { respectImportant: true } + ) + addUtilities( + { + '.custom-util': { + button: 'no', + }, + }, + { respectImportant: false } + ) + }, + ], + } + + let css = ` + @tailwind base; + @tailwind components; + @layer components { + .custom-component { + @apply font-bold; + } + .custom-important-component { + @apply text-center !important; + } + } + @tailwind utilities; + ` + + return run(css, config).then((result) => { + let expectedPath = path.resolve(__dirname, './04-important-selector.test.css') + let expected = fs.readFileSync(expectedPath, 'utf8') + + expect(result.css).toMatchCss(expected) + }) +})