diff --git a/__tests__/fixtures/tailwind-input.css b/__tests__/fixtures/tailwind-input.css index ac3999689..53204f9fd 100644 --- a/__tests__/fixtures/tailwind-input.css +++ b/__tests__/fixtures/tailwind-input.css @@ -1,5 +1,7 @@ @tailwind preflight; +@tailwind components; + @tailwind utilities; @responsive { diff --git a/css/tailwind.css b/css/tailwind.css index f2078b182..5881ba48f 100644 --- a/css/tailwind.css +++ b/css/tailwind.css @@ -1,3 +1,5 @@ @tailwind preflight; +@tailwind components; + @tailwind utilities; diff --git a/defaultConfig.stub.js b/defaultConfig.stub.js index 4f1349cd1..874c39756 100644 --- a/defaultConfig.stub.js +++ b/defaultConfig.stub.js @@ -859,6 +859,9 @@ module.exports = { }, + plugins: [], + + /* |----------------------------------------------------------------------------- | Advanced Options https://tailwindcss.com/docs/configuration#options diff --git a/src/index.js b/src/index.js index 0b392a1aa..2b70f8ca5 100644 --- a/src/index.js +++ b/src/index.js @@ -5,9 +5,8 @@ import postcss from 'postcss' import perfectionist from 'perfectionist' import registerConfigAsDependency from './lib/registerConfigAsDependency' -import substituteTailwindPreflightAtRule from './lib/substituteTailwindPreflightAtRule' +import substituteTailwindAtRules from './lib/substituteTailwindAtRules' import evaluateTailwindFunctions from './lib/evaluateTailwindFunctions' -import substituteTailwindUtilitiesAtRules from './lib/substituteTailwindUtilitiesAtRules' import substituteVariantsAtRules from './lib/substituteVariantsAtRules' import substituteResponsiveAtRules from './lib/substituteResponsiveAtRules' import substituteScreenAtRules from './lib/substituteScreenAtRules' @@ -34,9 +33,8 @@ const plugin = postcss.plugin('tailwind', config => { return postcss( ...plugins, ...[ - substituteTailwindPreflightAtRule(lazyConfig), + substituteTailwindAtRules(lazyConfig), evaluateTailwindFunctions(lazyConfig), - substituteTailwindUtilitiesAtRules(lazyConfig), substituteVariantsAtRules(lazyConfig), substituteResponsiveAtRules(lazyConfig), substituteScreenAtRules(lazyConfig), diff --git a/src/lib/substituteTailwindAtRules.js b/src/lib/substituteTailwindAtRules.js new file mode 100644 index 000000000..efa70661c --- /dev/null +++ b/src/lib/substituteTailwindAtRules.js @@ -0,0 +1,93 @@ +import _ from 'lodash' +import applyClassPrefix from '../util/applyClassPrefix' +import container from '../generators/container' +import fs from 'fs' +import generateModules from '../util/generateModules' +import postcss from 'postcss' +import utilityModules from '../utilityModules' +import wrapWithVariants from '../util/wrapWithVariants' + +function defineSelector(selector, properties) { + const decls = _.map(properties, (value, property) => { + return postcss.decl({ + prop: `${property}`, + value: `${value}`, + }) + }) + + return postcss.rule({ selector }).append(decls) +} + +export default function(config) { + return function(css) { + const unwrappedConfig = config() + + const pluginComponents = [] + const pluginUtilities = [] + + unwrappedConfig.plugins.forEach(plugin => { + plugin({ + selector: defineSelector, + addUtilities: (utilities, variants) => { + pluginUtilities.push(wrapWithVariants(utilities, variants)) + }, + addComponents: components => { + pluginComponents.push(...components) + }, + }) + }) + + css.walkAtRules('tailwind', atRule => { + if (atRule.params === 'preflight') { + atRule.before( + postcss.parse(fs.readFileSync(`${__dirname}/../../css/preflight.css`, 'utf8')) + ) + atRule.remove() + } + + if (atRule.params === 'components') { + const tailwindComponentTree = postcss.root({ + nodes: [...container(unwrappedConfig)], + }) + + const pluginComponentTree = postcss.root({ + nodes: [...pluginComponents], + }) + + applyClassPrefix(tailwindComponentTree, unwrappedConfig.options.prefix) + + tailwindComponentTree.walk(node => (node.source = atRule.source)) + pluginComponentTree.walk(node => (node.source = atRule.source)) + + atRule.before(tailwindComponentTree) + atRule.before(pluginComponentTree) + atRule.remove() + } + + if (atRule.params === 'utilities') { + const utilities = generateModules(utilityModules, unwrappedConfig.modules, unwrappedConfig) + + if (unwrappedConfig.options.important) { + utilities.walkDecls(decl => (decl.important = true)) + } + + const tailwindUtilityTree = postcss.root({ + nodes: [...utilities.nodes], + }) + + const pluginUtilityTree = postcss.root({ + nodes: [...pluginUtilities], + }) + + applyClassPrefix(tailwindUtilityTree, unwrappedConfig.options.prefix) + + tailwindUtilityTree.walk(node => (node.source = atRule.source)) + pluginUtilityTree.walk(node => (node.source = atRule.source)) + + atRule.before(tailwindUtilityTree) + atRule.before(pluginUtilityTree) + atRule.remove() + } + }) + } +} diff --git a/src/lib/substituteTailwindPreflightAtRule.js b/src/lib/substituteTailwindPreflightAtRule.js deleted file mode 100644 index a6a1c5931..000000000 --- a/src/lib/substituteTailwindPreflightAtRule.js +++ /dev/null @@ -1,15 +0,0 @@ -import fs from 'fs' -import postcss from 'postcss' - -export default function() { - return function(css) { - css.walkAtRules('tailwind', atRule => { - if (atRule.params !== 'preflight') { - return - } - - atRule.before(postcss.parse(fs.readFileSync(`${__dirname}/../../css/preflight.css`, 'utf8'))) - atRule.remove() - }) - } -} diff --git a/src/lib/substituteTailwindUtilitiesAtRules.js b/src/lib/substituteTailwindUtilitiesAtRules.js deleted file mode 100644 index d08f4457c..000000000 --- a/src/lib/substituteTailwindUtilitiesAtRules.js +++ /dev/null @@ -1,34 +0,0 @@ -import postcss from 'postcss' -import applyClassPrefix from '../util/applyClassPrefix' -import generateModules from '../util/generateModules' -import container from '../generators/container' -import utilityModules from '../utilityModules' - -export default function(config) { - return function(css) { - const unwrappedConfig = config() - - css.walkAtRules('tailwind', atRule => { - if (atRule.params !== 'utilities') { - return - } - - const utilities = generateModules(utilityModules, unwrappedConfig.modules, unwrappedConfig) - - if (unwrappedConfig.options.important) { - utilities.walkDecls(decl => (decl.important = true)) - } - - const tailwindClasses = postcss.root({ - nodes: [...container(unwrappedConfig), ...utilities.nodes], - }) - - applyClassPrefix(tailwindClasses, unwrappedConfig.options.prefix) - - tailwindClasses.walk(node => (node.source = atRule.source)) - - atRule.before(tailwindClasses) - atRule.remove() - }) - } -}