From 94a88e624a6c239e24efea0bc678f644571788ca Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Sun, 28 Mar 2021 09:54:44 -0400 Subject: [PATCH 1/2] Refactor --- src/lib/generateRules.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/lib/generateRules.js b/src/lib/generateRules.js index 046be38..865ce01 100644 --- a/src/lib/generateRules.js +++ b/src/lib/generateRules.js @@ -184,8 +184,15 @@ function* resolveMatchedPlugins(classCandidate, context) { } for (let [prefix, modifier] of candidatePermutations(candidatePrefix)) { + let modifiers = [modifier] + if (context.candidateRuleMap.has(prefix)) { - yield [context.candidateRuleMap.get(prefix), negative ? `-${modifier}` : modifier] + let rules = context.candidateRuleMap.get(prefix) + + for (const modifier of modifiers) { + yield [rules, negative ? `-${modifier}` : modifier] + } + return } } From ba366add6fb9b9919dadbaca09884abd7d400be6 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Sun, 28 Mar 2021 09:55:07 -0400 Subject: [PATCH 2/2] Add support for wildcards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We can now support class tokens like p-{*} to include all p- utilities classes automatically. This requires explicit plugin support because we don’t know what theme config goes with what plugin. Only the plugin does. --- src/corePlugins/padding.js | 12 ++++- src/lib/generateRules.js | 5 ++ src/lib/setupContext.js | 8 +++ tests/wildcards.test.css | 108 +++++++++++++++++++++++++++++++++++++ tests/wildcards.test.html | 14 +++++ tests/wildcards.test.js | 29 ++++++++++ 6 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 tests/wildcards.test.css create mode 100644 tests/wildcards.test.html create mode 100644 tests/wildcards.test.js diff --git a/src/corePlugins/padding.js b/src/corePlugins/padding.js index 2b1e7e1..cf2a78e 100644 --- a/src/corePlugins/padding.js +++ b/src/corePlugins/padding.js @@ -1,6 +1,16 @@ const { asValue, nameClass } = require('../pluginUtils') -module.exports = function ({ matchUtilities, jit: { theme } }) { +module.exports = function ({ matchUtilities, matchWildcards, jit: { theme } }) { + matchWildcards({ + p: Object.keys(theme['padding']), + px: Object.keys(theme['padding']), + py: Object.keys(theme['padding']), + pt: Object.keys(theme['padding']), + pr: Object.keys(theme['padding']), + pb: Object.keys(theme['padding']), + pl: Object.keys(theme['padding']), + }) + matchUtilities({ p: (modifier, { theme }) => { let value = asValue(modifier, theme['padding']) diff --git a/src/lib/generateRules.js b/src/lib/generateRules.js index 865ce01..f543786 100644 --- a/src/lib/generateRules.js +++ b/src/lib/generateRules.js @@ -173,6 +173,7 @@ function* resolveMatchedPlugins(classCandidate, context) { yield [context.candidateRuleMap.get(classCandidate), 'DEFAULT'] } + let wildcards = /^\{\*\}$/g let candidatePrefix = classCandidate let negative = false @@ -189,6 +190,10 @@ function* resolveMatchedPlugins(classCandidate, context) { if (context.candidateRuleMap.has(prefix)) { let rules = context.candidateRuleMap.get(prefix) + if (wildcards.test(modifier) && context.wildcardModifierList.has(prefix)) { + modifiers = context.wildcardModifierList.get(prefix) + } + for (const modifier of modifiers) { yield [rules, negative ? `-${modifier}` : modifier] } diff --git a/src/lib/setupContext.js b/src/lib/setupContext.js index 49a354d..c30f253 100644 --- a/src/lib/setupContext.js +++ b/src/lib/setupContext.js @@ -516,6 +516,13 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs context.candidateRuleMap.get(prefixedIdentifier).push(...withOffsets) } }, + + matchWildcards: function (modifierMap) { + for (const [prefix, modifiers] of Object.entries(modifierMap)) { + context.wildcardModifierList.set(prefix, modifiers) + } + }, + matchUtilities: function (utilities, options) { let defaultOptions = { variants: [], @@ -773,6 +780,7 @@ function setupContext(configOrPath) { variantMap: new Map(), stylesheetCache: null, fileModifiedMap: new Map(), + wildcardModifierList: new Map(), } // --- diff --git a/tests/wildcards.test.css b/tests/wildcards.test.css new file mode 100644 index 0000000..26c5470 --- /dev/null +++ b/tests/wildcards.test.css @@ -0,0 +1,108 @@ +.p-0 { + padding: 0px; +} +.p-1 { + padding: 0.25rem; +} +.p-2 { + padding: 0.5rem; +} +.p-3 { + padding: 0.75rem; +} +.p-4 { + padding: 1rem; +} +.p-5 { + padding: 1.25rem; +} +.p-6 { + padding: 1.5rem; +} +.p-7 { + padding: 1.75rem; +} +.p-8 { + padding: 2rem; +} +.p-9 { + padding: 2.25rem; +} +.p-10 { + padding: 2.5rem; +} +.p-11 { + padding: 2.75rem; +} +.p-12 { + padding: 3rem; +} +.p-14 { + padding: 3.5rem; +} +.p-16 { + padding: 4rem; +} +.p-20 { + padding: 5rem; +} +.p-24 { + padding: 6rem; +} +.p-28 { + padding: 7rem; +} +.p-32 { + padding: 8rem; +} +.p-36 { + padding: 9rem; +} +.p-40 { + padding: 10rem; +} +.p-44 { + padding: 11rem; +} +.p-48 { + padding: 12rem; +} +.p-52 { + padding: 13rem; +} +.p-56 { + padding: 14rem; +} +.p-60 { + padding: 15rem; +} +.p-64 { + padding: 16rem; +} +.p-72 { + padding: 18rem; +} +.p-80 { + padding: 20rem; +} +.p-96 { + padding: 24rem; +} +.p-px { + padding: 1px; +} +.p-0\.5 { + padding: 0.125rem; +} +.p-1\.5 { + padding: 0.375rem; +} +.p-2\.5 { + padding: 0.625rem; +} +.p-3\.5 { + padding: 0.875rem; +} +.p-4 { + padding: 1rem; +} diff --git a/tests/wildcards.test.html b/tests/wildcards.test.html new file mode 100644 index 0000000..152f24d --- /dev/null +++ b/tests/wildcards.test.html @@ -0,0 +1,14 @@ + + + + + + + Title + + + +
+
+ + diff --git a/tests/wildcards.test.js b/tests/wildcards.test.js new file mode 100644 index 0000000..33f9bb2 --- /dev/null +++ b/tests/wildcards.test.js @@ -0,0 +1,29 @@ +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('wildcards', () => { + let config = { + darkMode: 'class', + purge: [path.resolve(__dirname, './wildcards.test.html')], + corePlugins: { preflight: false }, + theme: {}, + plugins: [], + } + + let css = ` + @tailwind utilities; + ` + + return run(css, config).then((result) => { + let expectedPath = path.resolve(__dirname, './wildcards.test.css') + let expected = fs.readFileSync(expectedPath, 'utf8') + + expect(result.css).toMatchCss(expected) + }) +})