Prepend a shadow lookup table when no @tailwind rules are in the tree

This commit is contained in:
Adam Wathan 2020-08-13 20:16:56 -04:00
parent c252e33254
commit 8646c94dd5
5 changed files with 37 additions and 16 deletions

View file

@ -13,7 +13,11 @@ const { utilities: defaultUtilities } = processPlugins(
)
function run(input, config = resolvedDefaultConfig, utilities = defaultUtilities) {
return postcss([substituteClassApplyAtRules(config, utilities)]).process(input, {
return postcss([
substituteClassApplyAtRules(config, () => ({
utilities,
})),
]).process(input, {
from: undefined,
})
}

View file

@ -259,6 +259,17 @@ test('you can apply utility classes that do not actually exist as long as they w
})
})
test('the shadow lookup is only used if no @tailwind rules were in the source tree', () => {
const input = `
@tailwind base;
.foo { @apply mt-4; }
`
return run(input).catch(e => {
expect(e).toMatchObject({ name: 'CssSyntaxError' })
})
})
test.skip('you can apply utility classes without using the given prefix', () => {
const input = `
.foo { @apply .tw-mt-4 .mb-4; }

View file

@ -8,16 +8,17 @@ import substituteResponsiveAtRules from '../lib/substituteResponsiveAtRules'
import convertLayerAtRulesToControlComments from '../lib/convertLayerAtRulesToControlComments'
import substituteScreenAtRules from '../lib/substituteScreenAtRules'
function hasInject(css) {
let foundInject = false
function hasAtRule(css, atRule) {
let foundAtRule = false
css.walkAtRules('apply', () => {
foundInject = true
css.walkAtRules(atRule, () => {
foundAtRule = true
return false
})
return foundInject
return foundAtRule
}
function applyUtility(rule, className, replaceWith) {
const processedSelectors = rule.selectors.map(selector => {
const processor = selectorParser(selectors => {
@ -85,7 +86,7 @@ function buildUtilityMap(css) {
index,
utilityName,
rule: rule.clone({ parent: rule.parent }),
containsApply: hasInject(rule),
containsApply: hasAtRule(rule, 'apply'),
})
index++
})
@ -153,10 +154,10 @@ function makeExtractUtilityRules(css) {
}
}
function themagic(css, lookupTree) {
function processApplyAtRules(css, lookupTree) {
const extractUtilityRules = makeExtractUtilityRules(lookupTree)
while (hasInject(css)) {
while (hasAtRule(css, 'apply')) {
css.walkRules(rule => {
const injectRules = []
@ -222,6 +223,11 @@ function themagic(css, lookupTree) {
export default function applyComplexClasses(config, getProcessedPlugins) {
return function(css) {
// Tree already contains @tailwind rules, don't prepend default Tailwind tree
if (hasAtRule(css, 'tailwind')) {
return processApplyAtRules(css, css)
}
return postcss([
substituteTailwindAtRules(config, getProcessedPlugins()),
evaluateTailwindFunctions(config),
@ -242,7 +248,7 @@ export default function applyComplexClasses(config, getProcessedPlugins) {
// if css already contains tailwind, css is the lookup tree
const lookupTree = _.tap(css.clone(), tree => tree.prepend(result.root))
return themagic(css, lookupTree)
return processApplyAtRules(css, lookupTree)
})
}
}

View file

@ -49,18 +49,15 @@ export default function(
}
if (atRule.params === 'base') {
atRule.before(updateSource(pluginBase, atRule.source))
atRule.remove()
atRule.after(updateSource(pluginBase, atRule.source))
}
if (atRule.params === 'components') {
atRule.before(updateSource(pluginComponents, atRule.source))
atRule.remove()
atRule.after(updateSource(pluginComponents, atRule.source))
}
if (atRule.params === 'utilities') {
atRule.before(updateSource(pluginUtilities, atRule.source))
atRule.remove()
atRule.after(updateSource(pluginUtilities, atRule.source))
}
if (atRule.params === 'screens') {

View file

@ -40,6 +40,9 @@ export default function(getConfig) {
convertLayerAtRulesToControlComments(config),
substituteScreenAtRules(config),
substituteClassApplyAtRules(config, getProcessedPlugins),
function(css) {
css.walkAtRules('tailwind', rule => rule.remove())
},
purgeUnusedStyles(config),
]).process(css, { from: _.get(css, 'source.input.file') })
}