Very basic AOT matchUtilities support

This commit is contained in:
Adam Wathan 2021-04-30 11:21:43 -04:00
parent d497777202
commit cd2db712c5
2 changed files with 104 additions and 22 deletions

View File

@ -41,6 +41,33 @@ export default function (plugins, config) {
return prefixSelector(config.prefix, selector)
}
function 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 && !isKeyframeRule(rule)) {
rule.selector = applyConfiguredPrefix(rule.selector)
}
if (options.respectImportant && config.important) {
rule.__tailwind = {
...rule.__tailwind,
important: config.important,
}
}
})
pluginUtilities.push(
wrapWithLayer(wrapWithVariants(styles.nodes, options.variants), 'utilities')
)
}
const getConfigValue = (path, defaultValue) => (path ? _.get(config, path, defaultValue) : config)
plugins.forEach((plugin) => {
@ -75,31 +102,17 @@ export default function (plugins, config) {
},
e: escapeClassName,
prefix: applyConfiguredPrefix,
addUtilities: (utilities, options) => {
const defaultOptions = { variants: [], respectPrefix: true, respectImportant: true }
addUtilities,
matchUtilities: (matches, { values, variants, respectPrefix, respectImportant }) => {
let modifierValues = Object.entries(values)
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 && !isKeyframeRule(rule)) {
rule.selector = applyConfiguredPrefix(rule.selector)
}
if (options.respectImportant && config.important) {
rule.__tailwind = {
...rule.__tailwind,
important: config.important,
}
}
let result = Object.values(matches).flatMap((utilityFunction) => {
return modifierValues.map(([modifier, value]) => {
return utilityFunction(modifier, { value })
})
})
pluginUtilities.push(
wrapWithLayer(wrapWithVariants(styles.nodes, options.variants), 'utilities')
)
addUtilities(result, { variants, respectPrefix, respectImportant })
},
addComponents: (components, options) => {
const defaultOptions = { variants: [], respectPrefix: true }

View File

@ -2483,3 +2483,72 @@ test('animation values are joined when retrieved using the theme function', () =
}
`)
})
test('plugins can add utilities using matchUtilities in AOT mode', () => {
const { components, utilities } = processPlugins(
[
function ({ matchUtilities, theme, variants }) {
matchUtilities(
{
'flex-grow': (modifier, { value }) => {
return {
[`.flex-grow-${modifier}`]: {
'flex-grow': value,
},
}
},
'flex-shrink': (modifier, { value }) => {
return {
[`.flex-shrink-${modifier}`]: {
'flex-shrink': value,
},
}
},
},
{
values: theme('flexyPants'),
variants: variants('flexyPants'),
}
)
},
],
makeConfig({
theme: {
flexyPants: {
0: '0',
1: '1',
2: '2',
},
},
variants: {
flexyPants: ['responsive', 'hover', 'focus'],
},
})
)
expect(components.length).toBe(0)
expect(css(utilities)).toMatchCss(`
@layer utilities {
@variants responsive, hover, focus {
.flex-grow-0 {
flex-grow: 0
}
.flex-grow-1 {
flex-grow: 1
}
.flex-grow-2 {
flex-grow: 2
}
.flex-shrink-0 {
flex-shrink: 0
}
.flex-shrink-1 {
flex-shrink: 1
}
.flex-shrink-2 {
flex-shrink: 2
}
}
}
`)
})