tailwindcss/src/util/processPlugins.js

90 lines
2.7 KiB
JavaScript
Raw Normal View History

2018-03-01 16:34:29 -05:00
import _ from 'lodash'
import postcss from 'postcss'
import Node from 'postcss/lib/node'
2018-03-01 16:34:29 -05:00
import escapeClassName from '../util/escapeClassName'
import parseObjectStyles from '../util/parseObjectStyles'
import prefixSelector from '../util/prefixSelector'
2018-03-01 16:34:29 -05:00
import wrapWithVariants from '../util/wrapWithVariants'
function parseStyles(styles) {
if (!Array.isArray(styles)) {
return parseStyles([styles])
}
2018-03-01 16:34:29 -05:00
2018-03-06 15:03:09 -05:00
return _.flatMap(styles, style => (style instanceof Node ? style : parseObjectStyles(style)))
2018-03-01 16:34:29 -05:00
}
function generateVariantFunction(generator) {
return (container, config) => {
const cloned = container.clone()
cloned.walkRules(rule => {
rule.selector = generator({
className: rule.selector.slice(1),
separator: escapeClassName(config.options.separator),
})
})
container.before(cloned.nodes)
}
}
2018-03-01 19:21:19 -05:00
export default function(config) {
2018-03-01 16:34:29 -05:00
const pluginComponents = []
const pluginUtilities = []
const pluginVariantGenerators = {}
2018-03-01 16:34:29 -05:00
config.plugins.forEach(plugin => {
plugin({
config: (path, defaultValue) => _.get(config, path, defaultValue),
2018-03-01 16:34:29 -05:00
e: escapeClassName,
prefix: selector => {
return prefixSelector(config.options.prefix, selector)
},
addUtilities: (utilities, options) => {
const defaultOptions = { variants: [], respectPrefix: true, respectImportant: true }
options = Array.isArray(options)
? Object.assign({}, defaultOptions, { variants: options })
: _.defaults(options, defaultOptions)
const styles = postcss.root({ nodes: parseStyles(utilities) })
styles.walkRules(rule => {
if (options.respectPrefix) {
rule.selector = prefixSelector(config.options.prefix, rule.selector)
}
if (options.respectImportant && _.get(config, 'options.important')) {
2018-03-06 15:03:09 -05:00
rule.walkDecls(decl => (decl.important = true))
}
})
pluginUtilities.push(wrapWithVariants(styles.nodes, options.variants))
},
addComponents: (components, options) => {
options = Object.assign({ respectPrefix: true }, options)
const styles = postcss.root({ nodes: parseStyles(components) })
styles.walkRules(rule => {
if (options.respectPrefix) {
rule.selector = prefixSelector(config.options.prefix, rule.selector)
}
})
pluginComponents.push(...styles.nodes)
},
addVariant: (name, generator) => {
pluginVariantGenerators[name] = generateVariantFunction(generator)
},
2018-03-01 16:34:29 -05:00
})
})
return {
components: pluginComponents,
utilities: pluginUtilities,
variantGenerators: pluginVariantGenerators,
}
2018-03-01 16:34:29 -05:00
}