tailwindcss/src/tailwind.js

83 lines
1.8 KiB
JavaScript
Raw Normal View History

2017-08-24 19:38:25 -04:00
const _ = require('lodash');
const postcss = require('postcss');
const cssnext = require('postcss-cssnext');
function defaultOptions() {
return {
breakpoints: {
sm: '576px',
md: '768px',
lg: '992px',
xl: '1200px',
},
}
}
function findMixin(css, mixin) {
2017-08-24 19:38:25 -04:00
let match;
css.walkRules((rule) => {
if (_.trimStart(rule.selector, '.') === mixin) {
match = rule
return false
}
})
return match.clone().nodes
}
function addCustomMediaQueries(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)
return `(${feature}: ${value})`
}).join(' and ')
}
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)
})
}
function substituteClassMixins(css) {
css.walkRules(function (rule) {
rule.walkAtRules('class', atRule => {
const mixins = _.trim(atRule.params, ` "'`).split(' ')
const decls = _.flatMap(mixins, (mixin) => {
return findMixin(css, mixin)
})
rule.insertBefore(atRule, decls)
atRule.remove()
})
})
}
2017-08-24 19:38:25 -04:00
module.exports = postcss.plugin('tailwind', function (options) {
return function (css) {
options = options || defaultOptions()
2017-08-24 19:38:25 -04:00
addCustomMediaQueries(css, options.breakpoints)
2017-08-24 19:38:25 -04:00
// Generate utilities
// css.
substituteClassMixins(css)
2017-08-24 19:38:25 -04:00
// return cssnext.process(css)
2017-08-24 19:38:25 -04:00
}
})