Add first-class support for "responsive" components and bucket children
This commit is contained in:
parent
658250a96d
commit
9959b1f691
8 changed files with 501 additions and 68 deletions
|
|
@ -1114,6 +1114,62 @@ test("component declarations can optionally ignore 'prefix' option", () => {
|
|||
`)
|
||||
})
|
||||
|
||||
test('responsive components are generated with the components at-rule argument', () => {
|
||||
const { components } = processPlugins(
|
||||
[
|
||||
function({ addComponents }) {
|
||||
addComponents(
|
||||
{
|
||||
'.btn-blue': {
|
||||
backgroundColor: 'blue',
|
||||
},
|
||||
},
|
||||
{ variants: ['responsive'] }
|
||||
)
|
||||
},
|
||||
],
|
||||
makeConfig()
|
||||
)
|
||||
|
||||
expect(css(components)).toMatchCss(`
|
||||
@responsive components {
|
||||
@variants {
|
||||
.btn-blue {
|
||||
background-color: blue
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
})
|
||||
|
||||
test('components can use the array shorthand to add variants', () => {
|
||||
const { components } = processPlugins(
|
||||
[
|
||||
function({ addComponents }) {
|
||||
addComponents(
|
||||
{
|
||||
'.btn-blue': {
|
||||
backgroundColor: 'blue',
|
||||
},
|
||||
},
|
||||
['responsive']
|
||||
)
|
||||
},
|
||||
],
|
||||
makeConfig()
|
||||
)
|
||||
|
||||
expect(css(components)).toMatchCss(`
|
||||
@responsive components {
|
||||
@variants {
|
||||
.btn-blue {
|
||||
background-color: blue
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
})
|
||||
|
||||
test("component declarations are not affected by the 'important' option", () => {
|
||||
const { components } = processPlugins(
|
||||
[
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ test('it can generate responsive variants', () => {
|
|||
.chocolate { color: brown; }
|
||||
}
|
||||
|
||||
@tailwind screens;
|
||||
@screens utilities;
|
||||
`
|
||||
|
||||
const output = `
|
||||
|
|
@ -55,7 +55,7 @@ test('it can generate responsive variants with a custom separator', () => {
|
|||
.chocolate { color: brown; }
|
||||
}
|
||||
|
||||
@tailwind screens;
|
||||
@screens utilities;
|
||||
`
|
||||
|
||||
const output = `
|
||||
|
|
@ -97,7 +97,7 @@ test('it can generate responsive variants when classes have non-standard charact
|
|||
.chocolate-2\\.5 { color: brown; }
|
||||
}
|
||||
|
||||
@tailwind screens;
|
||||
@screens utilities;
|
||||
`
|
||||
|
||||
const output = `
|
||||
|
|
@ -144,7 +144,7 @@ test('responsive variants are grouped', () => {
|
|||
.chocolate { color: brown; }
|
||||
}
|
||||
|
||||
@tailwind screens;
|
||||
@screens utilities;
|
||||
`
|
||||
|
||||
const output = `
|
||||
|
|
@ -190,7 +190,7 @@ test('it can generate responsive variants for nested at-rules', () => {
|
|||
}
|
||||
}
|
||||
|
||||
@tailwind screens;
|
||||
@screens utilities;
|
||||
`
|
||||
|
||||
const output = `
|
||||
|
|
@ -255,7 +255,7 @@ test('it can generate responsive variants for deeply nested at-rules', () => {
|
|||
}
|
||||
}
|
||||
|
||||
@tailwind screens;
|
||||
@screens utilities;
|
||||
`
|
||||
|
||||
const output = `
|
||||
|
|
@ -320,7 +320,7 @@ test('screen prefix is only applied to the last class in a selector', () => {
|
|||
.banana li * .sandwich #foo > div { color: yellow; }
|
||||
}
|
||||
|
||||
@tailwind screens;
|
||||
@screens utilities;
|
||||
`
|
||||
|
||||
const output = `
|
||||
|
|
@ -357,7 +357,7 @@ test('responsive variants are generated for all selectors in a rule', () => {
|
|||
.foo, .bar { color: yellow; }
|
||||
}
|
||||
|
||||
@tailwind screens;
|
||||
@screens utilities;
|
||||
`
|
||||
|
||||
const output = `
|
||||
|
|
@ -394,7 +394,7 @@ test('selectors with no classes cannot be made responsive', () => {
|
|||
div { color: yellow; }
|
||||
}
|
||||
|
||||
@tailwind screens;
|
||||
@screens utilities;
|
||||
`
|
||||
expect.assertions(1)
|
||||
return run(input, {
|
||||
|
|
@ -417,7 +417,7 @@ test('all selectors in a rule must contain classes', () => {
|
|||
.foo, div { color: yellow; }
|
||||
}
|
||||
|
||||
@tailwind screens;
|
||||
@screens utilities;
|
||||
`
|
||||
expect.assertions(1)
|
||||
return run(input, {
|
||||
|
|
@ -433,3 +433,59 @@ test('all selectors in a rule must contain classes', () => {
|
|||
expect(e).toMatchObject({ name: 'CssSyntaxError' })
|
||||
})
|
||||
})
|
||||
|
||||
test('responsive components are inserted at @screens components', () => {
|
||||
const input = `
|
||||
@responsive components {
|
||||
.banana { color: yellow; }
|
||||
}
|
||||
|
||||
.apple { color: red; }
|
||||
|
||||
@screens components;
|
||||
|
||||
@responsive {
|
||||
.chocolate { color: brown; }
|
||||
}
|
||||
|
||||
@screens utilities;
|
||||
`
|
||||
|
||||
const output = `
|
||||
.banana { color: yellow; }
|
||||
.apple { color: red; }
|
||||
@media (min-width: 500px) {
|
||||
.sm\\:banana { color: yellow; }
|
||||
}
|
||||
@media (min-width: 750px) {
|
||||
.md\\:banana { color: yellow; }
|
||||
}
|
||||
@media (min-width: 1000px) {
|
||||
.lg\\:banana { color: yellow; }
|
||||
}
|
||||
.chocolate { color: brown; }
|
||||
@media (min-width: 500px) {
|
||||
.sm\\:chocolate { color: brown; }
|
||||
}
|
||||
@media (min-width: 750px) {
|
||||
.md\\:chocolate { color: brown; }
|
||||
}
|
||||
@media (min-width: 1000px) {
|
||||
.lg\\:chocolate { color: brown; }
|
||||
}
|
||||
`
|
||||
|
||||
return run(input, {
|
||||
theme: {
|
||||
screens: {
|
||||
sm: '500px',
|
||||
md: '750px',
|
||||
lg: '1000px',
|
||||
},
|
||||
},
|
||||
separator: ':',
|
||||
}).then(result => {
|
||||
expect(result.css).toMatchCss(output)
|
||||
expect(result.warnings().length).toBe(0)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
226
__tests__/tailwindAtRule.test.js
Normal file
226
__tests__/tailwindAtRule.test.js
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
import postcss from 'postcss'
|
||||
import plugin from '../src/lib/substituteTailwindAtRules'
|
||||
import processPlugins from '../src/util/processPlugins'
|
||||
import config from '../stubs/defaultConfig.stub.js'
|
||||
|
||||
function run(input, opts = config) {
|
||||
const plugins = [
|
||||
function({ addBase, addComponents, addUtilities }) {
|
||||
addBase({ base: { property: 'test' } })
|
||||
addComponents({ '.components': { property: 'test' } })
|
||||
addUtilities({ '.utilities': { property: 'test' } })
|
||||
},
|
||||
]
|
||||
return postcss([plugin(opts, processPlugins(plugins, opts))]).process(input, {
|
||||
from: undefined,
|
||||
})
|
||||
}
|
||||
|
||||
test('tailwind directives are replaced with their underlying CSS rules', () => {
|
||||
const input = `
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
`
|
||||
|
||||
const output = `
|
||||
/* tailwind start base */
|
||||
base { property: test }
|
||||
/* tailwind end base */
|
||||
/* tailwind start components */
|
||||
.components { property: test }
|
||||
/* tailwind end components */
|
||||
/* tailwind start screens components */
|
||||
@screens components;
|
||||
/* tailwind end screens components */
|
||||
/* tailwind start utilities */
|
||||
@variants {
|
||||
.utilities { property: test }
|
||||
}
|
||||
/* tailwind end utilities */
|
||||
/* tailwind start screens utilities */
|
||||
@screens utilities;
|
||||
/* tailwind end screens utilities */
|
||||
`
|
||||
|
||||
return run(input).then(result => {
|
||||
expect(result.css).toMatchCss(output)
|
||||
expect(result.warnings().length).toBe(0)
|
||||
})
|
||||
})
|
||||
|
||||
test('root-level component classes are not part of the components group', () => {
|
||||
const input = `
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
.btn { background: blue }
|
||||
@tailwind utilities;
|
||||
`
|
||||
|
||||
const output = `
|
||||
/* tailwind start base */
|
||||
base { property: test }
|
||||
/* tailwind end base */
|
||||
|
||||
/* tailwind start components */
|
||||
.components { property: test }
|
||||
/* tailwind end components */
|
||||
|
||||
/* tailwind start screens components */
|
||||
@screens components;
|
||||
/* tailwind end screens components */
|
||||
|
||||
.btn { background: blue }
|
||||
|
||||
/* tailwind start utilities */
|
||||
@variants {
|
||||
.utilities { property: test }
|
||||
}
|
||||
/* tailwind end utilities */
|
||||
|
||||
/* tailwind start screens utilities */
|
||||
@screens utilities;
|
||||
/* tailwind end screens utilities */
|
||||
`
|
||||
|
||||
return run(input).then(result => {
|
||||
expect(result.css).toMatchCss(output)
|
||||
expect(result.warnings().length).toBe(0)
|
||||
})
|
||||
})
|
||||
|
||||
test('nested rules are included in the corresponding bucket', () => {
|
||||
const input = `
|
||||
@tailwind base {
|
||||
html { font-size: 20px }
|
||||
}
|
||||
@tailwind components {
|
||||
.btn { background: blue }
|
||||
}
|
||||
@tailwind utilities {
|
||||
.tabular-nums { font-variant-numeric: tabular-nums }
|
||||
}
|
||||
`
|
||||
|
||||
const output = `
|
||||
/* tailwind start base */
|
||||
base { property: test }
|
||||
html { font-size: 20px }
|
||||
/* tailwind end base */
|
||||
|
||||
/* tailwind start components */
|
||||
.components { property: test }
|
||||
.btn { background: blue }
|
||||
/* tailwind end components */
|
||||
|
||||
/* tailwind start screens components */
|
||||
@screens components;
|
||||
/* tailwind end screens components */
|
||||
|
||||
/* tailwind start utilities */
|
||||
@variants {
|
||||
.utilities { property: test }
|
||||
}
|
||||
.tabular-nums { font-variant-numeric: tabular-nums }
|
||||
/* tailwind end utilities */
|
||||
|
||||
/* tailwind start screens utilities */
|
||||
@screens utilities
|
||||
/* tailwind end screens utilities */
|
||||
`
|
||||
|
||||
return run(input).then(result => {
|
||||
expect(result.css).toMatchCss(output)
|
||||
expect(result.warnings().length).toBe(0)
|
||||
})
|
||||
})
|
||||
|
||||
test('nested responsive component classes have the components argument added automatically', () => {
|
||||
const input = `
|
||||
@tailwind base;
|
||||
@tailwind components {
|
||||
@responsive {
|
||||
.btn { background: blue }
|
||||
}
|
||||
}
|
||||
@tailwind utilities;
|
||||
`
|
||||
|
||||
const output = `
|
||||
/* tailwind start base */
|
||||
base { property: test }
|
||||
/* tailwind end base */
|
||||
|
||||
/* tailwind start components */
|
||||
.components { property: test }
|
||||
@responsive components {
|
||||
.btn { background: blue }
|
||||
}
|
||||
/* tailwind end components */
|
||||
|
||||
/* tailwind start screens components */
|
||||
@screens components;
|
||||
/* tailwind end screens components */
|
||||
|
||||
/* tailwind start utilities */
|
||||
@variants {
|
||||
.utilities { property: test }
|
||||
}
|
||||
/* tailwind end utilities */
|
||||
|
||||
/* tailwind start screens utilities */
|
||||
@screens utilities;
|
||||
/* tailwind end screens utilities */
|
||||
`
|
||||
|
||||
return run(input).then(result => {
|
||||
expect(result.css).toMatchCss(output)
|
||||
expect(result.warnings().length).toBe(0)
|
||||
})
|
||||
})
|
||||
|
||||
test('nested responsive component classes authored using the variants syntax have the components argument added automatically', () => {
|
||||
const input = `
|
||||
@tailwind base;
|
||||
@tailwind components {
|
||||
@variants responsive {
|
||||
.btn { background: blue }
|
||||
}
|
||||
}
|
||||
@tailwind utilities;
|
||||
`
|
||||
|
||||
const output = `
|
||||
/* tailwind start base */
|
||||
base { property: test }
|
||||
/* tailwind end base */
|
||||
|
||||
/* tailwind start components */
|
||||
.components { property: test }
|
||||
@responsive components {
|
||||
@variants {
|
||||
.btn { background: blue }
|
||||
}
|
||||
}
|
||||
/* tailwind end components */
|
||||
|
||||
/* tailwind start screens components */
|
||||
@screens components;
|
||||
/* tailwind end screens components */
|
||||
|
||||
/* tailwind start utilities */
|
||||
@variants {
|
||||
.utilities { property: test }
|
||||
}
|
||||
/* tailwind end utilities */
|
||||
|
||||
/* tailwind start screens utilities */
|
||||
@screens utilities;
|
||||
/* tailwind end screens utilities */
|
||||
`
|
||||
|
||||
return run(input).then(result => {
|
||||
expect(result.css).toMatchCss(output)
|
||||
expect(result.warnings().length).toBe(0)
|
||||
})
|
||||
})
|
||||
|
|
@ -8,12 +8,16 @@ import * as emoji from '../cli/emoji'
|
|||
function removeTailwindComments(css) {
|
||||
css.walkComments(comment => {
|
||||
switch (comment.text.trim()) {
|
||||
case 'tailwind start base':
|
||||
case 'tailwind end base':
|
||||
case 'tailwind start components':
|
||||
case 'tailwind start utilities':
|
||||
case 'tailwind start screens':
|
||||
case 'tailwind end components':
|
||||
case 'tailwind start screens components':
|
||||
case 'tailwind end screens components':
|
||||
case 'tailwind start utilities':
|
||||
case 'tailwind end utilities':
|
||||
case 'tailwind end screens':
|
||||
case 'tailwind start screens utilities':
|
||||
case 'tailwind end screens utilities':
|
||||
comment.remove()
|
||||
break
|
||||
default:
|
||||
|
|
@ -64,11 +68,11 @@ export default function purgeUnusedUtilities(config) {
|
|||
css.walkComments(comment => {
|
||||
switch (comment.text.trim()) {
|
||||
case 'tailwind start utilities':
|
||||
case 'tailwind start screens':
|
||||
case 'tailwind start screens utilities':
|
||||
comment.text = 'purgecss end ignore'
|
||||
break
|
||||
case 'tailwind end utilities':
|
||||
case 'tailwind end screens':
|
||||
case 'tailwind end screens utilities':
|
||||
comment.text = 'purgecss start ignore'
|
||||
break
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -4,55 +4,69 @@ import cloneNodes from '../util/cloneNodes'
|
|||
import buildMediaQuery from '../util/buildMediaQuery'
|
||||
import buildSelectorVariant from '../util/buildSelectorVariant'
|
||||
|
||||
export default function(config) {
|
||||
return function(css) {
|
||||
const {
|
||||
theme: { screens },
|
||||
separator,
|
||||
} = config
|
||||
const responsiveRules = postcss.root()
|
||||
const finalRules = []
|
||||
function matchesBucket(atRule, bucket) {
|
||||
return (
|
||||
atRule.params === bucket ||
|
||||
(bucket === 'utilities' && (atRule.params === '' || atRule.params === undefined))
|
||||
)
|
||||
}
|
||||
|
||||
css.walkAtRules('responsive', atRule => {
|
||||
function insertResponsiveRules(config, css, bucket) {
|
||||
const {
|
||||
theme: { screens },
|
||||
separator,
|
||||
} = config
|
||||
const responsiveRules = postcss.root()
|
||||
const finalRules = []
|
||||
|
||||
css.walkAtRules('responsive', atRule => {
|
||||
if (matchesBucket(atRule, bucket)) {
|
||||
const nodes = atRule.nodes
|
||||
responsiveRules.append(...cloneNodes(nodes))
|
||||
atRule.before(nodes)
|
||||
atRule.remove()
|
||||
}
|
||||
})
|
||||
|
||||
_.keys(screens).forEach(screen => {
|
||||
const mediaQuery = postcss.atRule({
|
||||
name: 'media',
|
||||
params: buildMediaQuery(screens[screen]),
|
||||
})
|
||||
|
||||
_.keys(screens).forEach(screen => {
|
||||
const mediaQuery = postcss.atRule({
|
||||
name: 'media',
|
||||
params: buildMediaQuery(screens[screen]),
|
||||
})
|
||||
|
||||
mediaQuery.append(
|
||||
_.tap(responsiveRules.clone(), clonedRoot => {
|
||||
clonedRoot.walkRules(rule => {
|
||||
rule.selectors = _.map(rule.selectors, selector =>
|
||||
buildSelectorVariant(selector, screen, separator, message => {
|
||||
throw rule.error(message)
|
||||
})
|
||||
)
|
||||
})
|
||||
mediaQuery.append(
|
||||
_.tap(responsiveRules.clone(), clonedRoot => {
|
||||
clonedRoot.walkRules(rule => {
|
||||
rule.selectors = _.map(rule.selectors, selector =>
|
||||
buildSelectorVariant(selector, screen, separator, message => {
|
||||
throw rule.error(message)
|
||||
})
|
||||
)
|
||||
})
|
||||
)
|
||||
})
|
||||
)
|
||||
|
||||
finalRules.push(mediaQuery)
|
||||
})
|
||||
finalRules.push(mediaQuery)
|
||||
})
|
||||
|
||||
const hasScreenRules = finalRules.some(i => i.nodes.length !== 0)
|
||||
const hasScreenRules = finalRules.some(i => i.nodes.length !== 0)
|
||||
|
||||
css.walkAtRules('tailwind', atRule => {
|
||||
if (atRule.params !== 'screens') {
|
||||
return
|
||||
}
|
||||
css.walkAtRules('screens', atRule => {
|
||||
if (atRule.params !== bucket) {
|
||||
return
|
||||
}
|
||||
|
||||
if (hasScreenRules) {
|
||||
atRule.before(finalRules)
|
||||
}
|
||||
if (hasScreenRules) {
|
||||
atRule.before(finalRules)
|
||||
}
|
||||
|
||||
atRule.remove()
|
||||
})
|
||||
atRule.remove()
|
||||
})
|
||||
}
|
||||
|
||||
export default function(config) {
|
||||
return function(css) {
|
||||
insertResponsiveRules(config, css, 'components')
|
||||
insertResponsiveRules(config, css, 'utilities')
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,54 @@ export default function(
|
|||
}
|
||||
})
|
||||
|
||||
let includesScreensExplicitly = false
|
||||
css.walkAtRules('tailwind', atRule => {
|
||||
if (atRule.params === 'screens') {
|
||||
atRule.name = 'screens'
|
||||
atRule.params = 'utilities'
|
||||
}
|
||||
})
|
||||
|
||||
let includesComponentsScreensExplicitly = false
|
||||
let includesUtilitiesScreensExplicitly = false
|
||||
|
||||
css.walkAtRules('screens', atRule => {
|
||||
if (atRule.params === 'components') {
|
||||
includesComponentsScreensExplicitly = true
|
||||
atRule.before(postcss.comment({ text: 'tailwind start screens components' }))
|
||||
atRule.after(postcss.comment({ text: 'tailwind end screens components' }))
|
||||
}
|
||||
|
||||
if (atRule.params === 'utilities') {
|
||||
includesUtilitiesScreensExplicitly = true
|
||||
atRule.before(postcss.comment({ text: 'tailwind start screens utilities' }))
|
||||
atRule.after(postcss.comment({ text: 'tailwind end screens utilities' }))
|
||||
}
|
||||
})
|
||||
|
||||
function hasChildren(atRule) {
|
||||
return atRule.nodes !== undefined && atRule.nodes.length > 0
|
||||
}
|
||||
|
||||
function extractChildren(atRule, bucket) {
|
||||
if (hasChildren(atRule)) {
|
||||
atRule.walkAtRules('variants', variantsAtRule => {
|
||||
const params = postcss.list.comma(variantsAtRule.params)
|
||||
if (params.includes('responsive')) {
|
||||
variantsAtRule.params = params.filter(p => p !== 'responsive').join(', ')
|
||||
variantsAtRule.before(
|
||||
postcss.atRule({ name: 'responsive', nodes: [variantsAtRule.clone()] })
|
||||
)
|
||||
variantsAtRule.remove()
|
||||
}
|
||||
})
|
||||
|
||||
atRule.walkAtRules('responsive', responsiveAtRule => {
|
||||
responsiveAtRule.params = bucket
|
||||
})
|
||||
|
||||
atRule.before(atRule.nodes)
|
||||
}
|
||||
}
|
||||
|
||||
css.walkAtRules('tailwind', atRule => {
|
||||
if (atRule.params === 'preflight') {
|
||||
|
|
@ -49,36 +96,42 @@ export default function(
|
|||
}
|
||||
|
||||
if (atRule.params === 'base') {
|
||||
atRule.before(postcss.comment({ text: 'tailwind start base' }))
|
||||
atRule.before(updateSource(pluginBase, atRule.source))
|
||||
extractChildren(atRule, 'base')
|
||||
atRule.before(postcss.comment({ text: 'tailwind end base' }))
|
||||
atRule.remove()
|
||||
}
|
||||
|
||||
if (atRule.params === 'components') {
|
||||
atRule.before(postcss.comment({ text: 'tailwind start components' }))
|
||||
atRule.before(updateSource(pluginComponents, atRule.source))
|
||||
atRule.after(postcss.comment({ text: 'tailwind end components' }))
|
||||
extractChildren(atRule, 'components')
|
||||
atRule.before(postcss.comment({ text: 'tailwind end components' }))
|
||||
|
||||
if (!includesComponentsScreensExplicitly) {
|
||||
atRule.before(postcss.comment({ text: 'tailwind start screens components' }))
|
||||
atRule.before(postcss.atRule({ name: 'screens', params: 'components' }))
|
||||
atRule.before(postcss.comment({ text: 'tailwind end screens components' }))
|
||||
}
|
||||
|
||||
atRule.remove()
|
||||
}
|
||||
|
||||
if (atRule.params === 'utilities') {
|
||||
atRule.before(postcss.comment({ text: 'tailwind start utilities' }))
|
||||
atRule.before(updateSource(pluginUtilities, atRule.source))
|
||||
atRule.after(postcss.comment({ text: 'tailwind end utilities' }))
|
||||
extractChildren(atRule, 'utilities')
|
||||
atRule.before(postcss.comment({ text: 'tailwind end utilities' }))
|
||||
atRule.remove()
|
||||
}
|
||||
|
||||
if (atRule.params === 'screens') {
|
||||
includesScreensExplicitly = true
|
||||
atRule.before(postcss.comment({ text: 'tailwind start screens' }))
|
||||
atRule.after(postcss.comment({ text: 'tailwind end screens' }))
|
||||
}
|
||||
})
|
||||
|
||||
if (!includesScreensExplicitly) {
|
||||
if (!includesUtilitiesScreensExplicitly) {
|
||||
css.append([
|
||||
postcss.comment({ text: 'tailwind start screens' }),
|
||||
postcss.atRule({ name: 'tailwind', params: 'screens' }),
|
||||
postcss.comment({ text: 'tailwind end screens' }),
|
||||
postcss.comment({ text: 'tailwind start screens utilities' }),
|
||||
postcss.atRule({ name: 'screens', params: 'utilities' }),
|
||||
postcss.comment({ text: 'tailwind end screens utilities' }),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,7 +111,11 @@ export default function(plugins, config) {
|
|||
pluginUtilities.push(wrapWithVariants(styles.nodes, options.variants))
|
||||
},
|
||||
addComponents: (components, options) => {
|
||||
options = Object.assign({ respectPrefix: true }, options)
|
||||
const defaultOptions = { variants: [], respectPrefix: true }
|
||||
|
||||
options = Array.isArray(options)
|
||||
? Object.assign({}, defaultOptions, { variants: options })
|
||||
: _.defaults(options, defaultOptions)
|
||||
|
||||
const styles = postcss.root({ nodes: parseStyles(components) })
|
||||
|
||||
|
|
@ -121,7 +125,11 @@ export default function(plugins, config) {
|
|||
}
|
||||
})
|
||||
|
||||
pluginComponents.push(...styles.nodes)
|
||||
if (options.variants.length > 0) {
|
||||
pluginComponents.push(wrapWithVariants(styles.nodes, options.variants, 'components'))
|
||||
} else {
|
||||
pluginComponents.push(...styles.nodes)
|
||||
}
|
||||
},
|
||||
addBase: baseStyles => {
|
||||
pluginBaseStyles.push(...parseStyles(baseStyles))
|
||||
|
|
|
|||
|
|
@ -1,7 +1,23 @@
|
|||
import postcss from 'postcss'
|
||||
import cloneNodes from './cloneNodes'
|
||||
|
||||
export default function wrapWithVariants(rules, variants) {
|
||||
export default function wrapWithVariants(rules, variants, bucket = 'utilities') {
|
||||
if (bucket === 'components' && variants.includes('responsive')) {
|
||||
return postcss
|
||||
.atRule({
|
||||
name: 'responsive',
|
||||
params: 'components',
|
||||
})
|
||||
.append(
|
||||
postcss
|
||||
.atRule({
|
||||
name: 'variants',
|
||||
params: variants.filter(v => v !== 'responsive').join(', '),
|
||||
})
|
||||
.append(cloneNodes(Array.isArray(rules) ? rules : [rules]))
|
||||
)
|
||||
}
|
||||
|
||||
return postcss
|
||||
.atRule({
|
||||
name: 'variants',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue