Support before/after

This commit is contained in:
Adam Wathan 2021-06-25 14:45:58 -04:00
parent 7db4c3a403
commit 611fffbb4e
3 changed files with 73 additions and 3 deletions

View file

@ -231,7 +231,7 @@ function* resolveMatches(candidate, context) {
for (let [sort, plugin] of plugins) {
if (typeof plugin === 'function') {
for (let ruleSet of [].concat(plugin(modifier, { candidate }))) {
for (let ruleSet of [].concat(plugin(modifier, { candidate, variants }))) {
let [rules, options] = parseRules(ruleSet, context.postCssNodeCache)
for (let rule of rules) {
matches.push([{ ...sort, options: { ...sort.options, ...options } }, rule])

View file

@ -125,6 +125,20 @@ function withIdentifiers(styles) {
})
}
function buildElementSelector(candidate, variants) {
let escaped = `.${escapeClassName(candidate)}`
if (variants.includes('before')) {
return escaped + '::before'
}
if (variants.includes('after')) {
return escaped + '::after'
}
return escaped
}
function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offsets }) {
function getConfigValue(path, defaultValue) {
return path ? dlv(tailwindConfig, path, defaultValue) : tailwindConfig
@ -265,7 +279,7 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
let prefixedIdentifier = prefixIdentifier(identifier, options)
let rule = utilities[identifier]
function wrapped(modifier, { candidate }) {
function wrapped(modifier, { candidate, variants }) {
let { type = 'any' } = options
type = [].concat(type)
let [value, coercedType] = coerceValue(type, modifier, options.values, tailwindConfig)
@ -278,7 +292,7 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
let ruleSets = []
.concat(
rule(value, {
selector: `.${escapeClassName(candidate)}`,
selector: buildElementSelector(candidate, variants),
includeRules(rules) {
includedRules.push(...rules)
},

View file

@ -209,6 +209,62 @@ test('with variants', async () => {
})
})
test('with pseudo-element variants', async () => {
let config = {
mode: 'jit',
purge: [
{
raw: '<div class="before:brightness-100 after:brightness-100 lg:hover:after:brightness-100',
},
],
corePlugins: ['filter', 'brightness', 'contrast'],
theme: {},
plugins: [],
}
let css = `
@tailwind base;
@tailwind utilities
`
return run(css, config).then((result) => {
expect(result.css).toMatchFormattedCss(`
.before\\:brightness-100::before,
.after\\:brightness-100::after,
.lg\\:hover\\:after\\:brightness-100::after {
--tw-blur: var(--tw-empty, /*!*/ /*!*/);
--tw-brightness: var(--tw-empty, /*!*/ /*!*/);
--tw-contrast: var(--tw-empty, /*!*/ /*!*/);
--tw-grayscale: var(--tw-empty, /*!*/ /*!*/);
--tw-hue-rotate: var(--tw-empty, /*!*/ /*!*/);
--tw-invert: var(--tw-empty, /*!*/ /*!*/);
--tw-saturate: var(--tw-empty, /*!*/ /*!*/);
--tw-sepia: var(--tw-empty, /*!*/ /*!*/);
--tw-drop-shadow: var(--tw-empty, /*!*/ /*!*/);
--tw-filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale)
var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
.before\\:brightness-100::before {
content: "";
--tw-brightness: brightness(1);
filter: var(--tw-filter);
}
.after\\:brightness-100::after {
content: "";
--tw-brightness: brightness(1);
filter: var(--tw-filter);
}
@media (min-width: 1024px) {
.lg\\:hover\\:after\\:brightness-100:hover::after {
content: "";
--tw-brightness: brightness(1);
filter: var(--tw-filter);
}
}
`)
})
})
test('without any filter classes', async () => {
let config = {
mode: 'jit',