diff --git a/package.json b/package.json index 57ad2c504..f2c3fedc8 100644 --- a/package.json +++ b/package.json @@ -18,5 +18,8 @@ "postcss": "^6.0.9", "postcss-cssnext": "^3.0.2", "suitcss-base": "^3.0.0" + }, + "devDependencies": { + "stylefmt": "^6.0.0" } } diff --git a/src/lib/addCustomMediaQueries.js b/src/lib/addCustomMediaQueries.js index 4f9ab0543..50a40380b 100644 --- a/src/lib/addCustomMediaQueries.js +++ b/src/lib/addCustomMediaQueries.js @@ -1,35 +1,35 @@ const _ = require('lodash') const postcss = require('postcss') -module.exports = function(css, {breakpoints}) { - function buildMediaQuery(breakpoint) { - if (_.isString(breakpoint)) { - breakpoint = {min: breakpoint} - } - return _(breakpoint) - .toPairs() - .map(([feature, value]) => { - feature = _.get( - { - min: 'min-width', - max: 'max-width', - }, - feature, - feature - ) +function buildMediaQuery(breakpoint) { + if (_.isString(breakpoint)) { + breakpoint = {min: breakpoint} + } - return `(${feature}: ${value})` - }) - .join(' and ') - } + return _(breakpoint).toPairs().map(([feature, value]) => { + feature = _.get( + { + min: 'min-width', + max: 'max-width', + }, + feature, + feature + ) - Object.keys(breakpoints).forEach(breakpoint => { - const variableName = `--breakpoint-${breakpoint}` - const mediaQuery = buildMediaQuery(breakpoints[breakpoint]) - const rule = postcss.atRule({ - name: 'custom-media', - params: `${variableName} ${mediaQuery}`, - }) - css.prepend(rule) - }) + return `(${feature}: ${value})` + }).join(' and ') +} + +module.exports = function ({breakpoints}) { + return function (css) { + Object.keys(breakpoints).forEach(breakpoint => { + const variableName = `--breakpoint-${breakpoint}` + const mediaQuery = buildMediaQuery(breakpoints[breakpoint]) + const rule = postcss.atRule({ + name: 'custom-media', + params: `${variableName} ${mediaQuery}`, + }) + css.prepend(rule) + }) + } } diff --git a/src/lib/generateUtilities.js b/src/lib/generateUtilities.js index bca4234f2..1bb1cfcc3 100644 --- a/src/lib/generateUtilities.js +++ b/src/lib/generateUtilities.js @@ -5,41 +5,43 @@ const shadows = require('../generators/shadows') const flex = require('../generators/flex') const cloneNodes = require('../util/cloneNodes') -module.exports = function(css, options) { - const rules = [] +module.exports = function (options) { + return function (css) { + const rules = [] - css.walkAtRules(atRule => { - if (atRule.name === 'responsive') { - const nodes = atRule.nodes - rules.push(...cloneNodes(nodes)) - css.insertBefore(atRule, nodes) - atRule.remove() - } - if (atRule.name === 'tailwind' && atRule.params === 'utilities') { - const utilities = _.flatten([ - backgroundColors(options), - shadows(options), - flex(), - ]) - rules.push(...cloneNodes(utilities)) - css.insertBefore(atRule, utilities) - atRule.remove() - } - }) - - Object.keys(options.breakpoints).forEach(breakpoint => { - const mediaQuery = postcss.atRule({ - name: 'media', - params: `(--breakpoint-${breakpoint})`, + css.walkAtRules(atRule => { + if (atRule.name === 'responsive') { + const nodes = atRule.nodes + rules.push(...cloneNodes(nodes)) + css.insertBefore(atRule, nodes) + atRule.remove() + } + if (atRule.name === 'tailwind' && atRule.params === 'utilities') { + const utilities = _.flatten([ + backgroundColors(options), + shadows(options), + flex(), + ]) + rules.push(...cloneNodes(utilities)) + css.insertBefore(atRule, utilities) + atRule.remove() + } }) - mediaQuery.append( - rules.map(rule => { - const cloned = rule.clone() - cloned.selector = `.${breakpoint}\\:${rule.selector.slice(1)}` - return cloned + Object.keys(options.breakpoints).forEach(breakpoint => { + const mediaQuery = postcss.atRule({ + name: 'media', + params: `(--breakpoint-${breakpoint})`, }) - ) - css.append(mediaQuery) - }) + + mediaQuery.append( + rules.map(rule => { + const cloned = rule.clone() + cloned.selector = `.${breakpoint}\\:${rule.selector.slice(1)}` + return cloned + }) + ) + css.append(mediaQuery) + }) + } } diff --git a/src/lib/substituteClassApplyAtRules.js b/src/lib/substituteClassApplyAtRules.js index 9f83df52e..08a498c34 100644 --- a/src/lib/substituteClassApplyAtRules.js +++ b/src/lib/substituteClassApplyAtRules.js @@ -2,28 +2,30 @@ const postcss = require('postcss') const _ = require('lodash') const findMixin = require('../util/findMixin') -module.exports = function(css) { - css.walkRules(function(rule) { - rule.walkAtRules('apply', atRule => { - const mixins = postcss.list.space(atRule.params) +module.exports = function (options) { + return function (css) { + css.walkRules(rule => { + rule.walkAtRules('apply', atRule => { + const mixins = postcss.list.space(atRule.params) - const [customProperties, classes] = _.partition(mixins, mixin => { - return _.startsWith(mixin, '--') - }) - - const decls = _.flatMap(classes, mixin => { - return findMixin(css, mixin, () => { - throw atRule.error(`No ${mixin} class found.`) + const [customProperties, classes] = _.partition(mixins, mixin => { + return _.startsWith(mixin, '--') }) + + const decls = _.flatMap(classes, mixin => { + return findMixin(css, mixin, () => { + throw atRule.error(`No ${mixin} class found.`) + }) + }) + + rule.insertBefore(atRule, decls) + + atRule.params = customProperties.join(' ') + + if (_.isEmpty(customProperties)) { + atRule.remove() + } }) - - rule.insertBefore(atRule, decls) - - atRule.params = customProperties.join(' ') - - if (_.isEmpty(customProperties)) { - atRule.remove() - } }) - }) + } } diff --git a/src/tailwind.js b/src/tailwind.js index 78e922290..303b8a79a 100644 --- a/src/tailwind.js +++ b/src/tailwind.js @@ -1,23 +1,19 @@ const _ = require('lodash') const postcss = require('postcss') -const cssnext = require('postcss-cssnext') const fs = require('fs') const addCustomMediaQueries = require('./lib/addCustomMediaQueries') const generateUtilities = require('./lib/generateUtilities') const substituteClassApplyAtRules = require('./lib/substituteClassApplyAtRules') -module.exports = postcss.plugin('tailwind', function(options) { - return function(css) { - options = options || require('./default-config') +module.exports = postcss.plugin('tailwind', options => { + options = options || require('./default-config') - // const normalize = fs.readFileSync('../node_modules/normalize.css/normalize.css') - // const base = fs.readFileSync('../node_modules/suitcss-base/lib/base.css') - // css.prepend(postcss.parse(base)) - // css.prepend(postcss.parse(normalize)) - - addCustomMediaQueries(css, options) - generateUtilities(css, options) - substituteClassApplyAtRules(css) - } + return postcss([ + addCustomMediaQueries(options), + generateUtilities(options), + substituteClassApplyAtRules(options), + require('postcss-cssnext')(), + require('stylefmt'), + ]) })