2018-03-01 16:34:29 -05:00
|
|
|
import _ from 'lodash'
|
|
|
|
|
import postcss from 'postcss'
|
2018-03-06 14:08:47 -05:00
|
|
|
import Node from 'postcss/lib/node'
|
2018-03-01 16:34:29 -05:00
|
|
|
import escapeClassName from '../util/escapeClassName'
|
2018-03-06 14:08:47 -05:00
|
|
|
import parseObjectStyles from '../util/parseObjectStyles'
|
2018-03-02 09:08:05 -05:00
|
|
|
import prefixSelector from '../util/prefixSelector'
|
2018-03-01 16:34:29 -05:00
|
|
|
import wrapWithVariants from '../util/wrapWithVariants'
|
|
|
|
|
|
2018-03-06 14:08:47 -05:00
|
|
|
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
|
|
|
}
|
|
|
|
|
|
2018-06-22 12:30:30 -04: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 = []
|
2018-06-22 12:08:54 -04:00
|
|
|
const pluginVariantGenerators = {}
|
2018-03-01 16:34:29 -05:00
|
|
|
|
|
|
|
|
config.plugins.forEach(plugin => {
|
|
|
|
|
plugin({
|
2018-03-02 07:45:11 -05:00
|
|
|
config: (path, defaultValue) => _.get(config, path, defaultValue),
|
2018-03-01 16:34:29 -05:00
|
|
|
e: escapeClassName,
|
2018-03-02 09:08:05 -05:00
|
|
|
prefix: selector => {
|
|
|
|
|
return prefixSelector(config.options.prefix, selector)
|
|
|
|
|
},
|
2018-03-06 14:08:47 -05:00
|
|
|
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))
|
2018-03-06 14:08:47 -05:00
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
pluginUtilities.push(wrapWithVariants(styles.nodes, options.variants))
|
|
|
|
|
},
|
2018-03-06 15:56:00 -05:00
|
|
|
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)
|
2018-03-06 14:08:47 -05:00
|
|
|
},
|
2018-06-22 12:30:30 -04:00
|
|
|
addVariant: (name, generator) => {
|
|
|
|
|
pluginVariantGenerators[name] = generateVariantFunction(generator)
|
|
|
|
|
},
|
2018-03-01 16:34:29 -05:00
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
2018-06-22 12:08:54 -04:00
|
|
|
return {
|
|
|
|
|
components: pluginComponents,
|
|
|
|
|
utilities: pluginUtilities,
|
|
|
|
|
variantGenerators: pluginVariantGenerators,
|
|
|
|
|
}
|
2018-03-01 16:34:29 -05:00
|
|
|
}
|