Intermingle component and utility screens

This commit is contained in:
Adam Wathan 2020-07-14 16:41:41 -04:00
parent 9959b1f691
commit fc1d4c4cb1
3 changed files with 81 additions and 101 deletions

View file

@ -9,15 +9,13 @@ function removeTailwindComments(css) {
css.walkComments(comment => {
switch (comment.text.trim()) {
case 'tailwind start base':
case 'tailwind end base':
case 'tailwind start components':
case 'tailwind end components':
case 'tailwind start screens components':
case 'tailwind end screens components':
case 'tailwind start utilities':
case 'tailwind start screens':
case 'tailwind end base':
case 'tailwind end components':
case 'tailwind end utilities':
case 'tailwind start screens utilities':
case 'tailwind end screens utilities':
case 'tailwind end screens':
comment.remove()
break
default:
@ -68,20 +66,18 @@ export default function purgeUnusedUtilities(config) {
css.walkComments(comment => {
switch (comment.text.trim()) {
case 'tailwind start utilities':
case 'tailwind start screens utilities':
comment.text = 'purgecss end ignore'
break
case 'tailwind end utilities':
case 'tailwind end screens utilities':
comment.text = 'purgecss start ignore'
break
default:
break
}
})
} else if (mode === 'all') {
removeTailwindComments(css)
}
removeTailwindComments(css)
},
purgecss({
content: Array.isArray(config.purge) ? config.purge : config.purge.content,

View file

@ -4,69 +4,79 @@ import cloneNodes from '../util/cloneNodes'
import buildMediaQuery from '../util/buildMediaQuery'
import buildSelectorVariant from '../util/buildSelectorVariant'
function matchesBucket(atRule, bucket) {
return (
atRule.params === bucket ||
(bucket === 'utilities' && (atRule.params === '' || atRule.params === undefined))
)
}
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]),
})
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)
})
const hasScreenRules = finalRules.some(i => i.nodes.length !== 0)
css.walkAtRules('screens', atRule => {
if (atRule.params !== bucket) {
return
}
if (hasScreenRules) {
atRule.before(finalRules)
}
atRule.remove()
})
}
export default function(config) {
return function(css) {
insertResponsiveRules(config, css, 'components')
insertResponsiveRules(config, css, 'utilities')
const {
theme: { screens },
separator,
} = config
const responsiveRules = {
components: postcss.root(),
utilities: postcss.root(),
}
const finalRules = []
css.walkAtRules('responsive', atRule => {
const bucket = atRule.params === 'components' ? 'components' : 'utilities'
const nodes = atRule.nodes
responsiveRules[bucket].append(...cloneNodes(nodes))
atRule.before(nodes)
atRule.remove()
})
_.keys(screens).forEach(screen => {
const mediaQuery = postcss.atRule({
name: 'media',
params: buildMediaQuery(screens[screen]),
})
mediaQuery.append(postcss.comment({ text: 'tailwind start components' }))
mediaQuery.append(
_.tap(responsiveRules.components.clone(), clonedRoot => {
clonedRoot.walkRules(rule => {
rule.selectors = _.map(rule.selectors, selector =>
buildSelectorVariant(selector, screen, separator, message => {
throw rule.error(message)
})
)
})
})
)
mediaQuery.append(postcss.comment({ text: 'tailwind end components' }))
mediaQuery.append(postcss.comment({ text: 'tailwind start utilities' }))
mediaQuery.append(
_.tap(responsiveRules.utilities.clone(), clonedRoot => {
clonedRoot.walkRules(rule => {
rule.selectors = _.map(rule.selectors, selector =>
buildSelectorVariant(selector, screen, separator, message => {
throw rule.error(message)
})
)
})
})
)
mediaQuery.append(postcss.comment({ text: 'tailwind end utilities' }))
finalRules.push(mediaQuery)
})
const hasScreenRules = finalRules.some(i => i.nodes.length !== 0)
css.walkAtRules('tailwind', atRule => {
if (atRule.params !== 'screens') {
return
}
if (hasScreenRules) {
atRule.before(finalRules)
}
atRule.remove()
})
}
}

View file

@ -47,22 +47,7 @@ export default function(
}
})
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' }))
}
})
let includesScreensExplicitly = false
function hasChildren(atRule) {
return atRule.nodes !== undefined && atRule.nodes.length > 0
@ -108,13 +93,6 @@ export default function(
atRule.before(updateSource(pluginComponents, atRule.source))
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()
}
@ -127,12 +105,8 @@ export default function(
}
})
if (!includesUtilitiesScreensExplicitly) {
css.append([
postcss.comment({ text: 'tailwind start screens utilities' }),
postcss.atRule({ name: 'screens', params: 'utilities' }),
postcss.comment({ text: 'tailwind end screens utilities' }),
])
if (!includesScreensExplicitly) {
css.append([postcss.atRule({ name: 'tailwind', params: 'screens' })])
}
}
}