Fix matchVariants that use at-rules and placeholders (#8392)
* Fix matchVariants that use at-rules and placeholders * update changelog * Update CHANGELOG.md * Only parseVariant when result is defined Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
This commit is contained in:
parent
1a564fa7e2
commit
bb4f5dab6b
3 changed files with 82 additions and 16 deletions
|
|
@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Move `important` selector to the front when `@apply`-ing selector-modifying variants in custom utilities ([#8313](https://github.com/tailwindlabs/tailwindcss/pull/8313))
|
||||
- Error when registering an invalid custom variant ([#8345](https://github.com/tailwindlabs/tailwindcss/pull/8345))
|
||||
- Create tailwind.config.cjs file in ESM package when running init ([#8363](https://github.com/tailwindlabs/tailwindcss/pull/8363))
|
||||
- Fix `matchVariants` that use at-rules and placeholders ([#8392](https://github.com/tailwindlabs/tailwindcss/pull/8392))
|
||||
|
||||
### Changed
|
||||
|
||||
|
|
|
|||
|
|
@ -439,7 +439,8 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
|
|||
variantFunctions = [].concat(variantFunctions).map((variantFunction) => {
|
||||
if (typeof variantFunction !== 'string') {
|
||||
// Safelist public API functions
|
||||
return ({ args, modifySelectors, container, separator, wrap, format }) => {
|
||||
return (api) => {
|
||||
let { args, modifySelectors, container, separator, wrap, format } = api
|
||||
let result = variantFunction(
|
||||
Object.assign(
|
||||
{ modifySelectors, container, separator },
|
||||
|
|
@ -453,7 +454,8 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
|
|||
)
|
||||
}
|
||||
|
||||
return result
|
||||
// result may be undefined with legacy variants that use APIs like `modifySelectors`
|
||||
return result && parseVariant(result)(api)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -477,20 +479,7 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
|
|||
|
||||
api.addVariant(
|
||||
variant,
|
||||
Object.assign(
|
||||
({ args, wrap }) => {
|
||||
let formatString = variants[variant](args)
|
||||
if (!formatString) return null
|
||||
|
||||
if (!formatString.startsWith('@')) {
|
||||
return formatString
|
||||
}
|
||||
|
||||
let [, name, params] = /@(.*?)( .+|[({].*)/g.exec(formatString)
|
||||
return wrap(postcss.atRule({ name, params: params.trim() }))
|
||||
},
|
||||
{ [MATCH_VARIANT]: true }
|
||||
),
|
||||
Object.assign(({ args }) => variants[variant](args), { [MATCH_VARIANT]: true }),
|
||||
options
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,82 @@ test('partial arbitrary variants', () => {
|
|||
})
|
||||
})
|
||||
|
||||
test('partial arbitrary variants with at-rules', () => {
|
||||
let config = {
|
||||
content: [
|
||||
{
|
||||
raw: html`<div class="potato-[yellow]:bg-yellow-200 potato-[baked]:w-3"></div> `,
|
||||
},
|
||||
],
|
||||
corePlugins: { preflight: false },
|
||||
plugins: [
|
||||
({ matchVariant }) => {
|
||||
matchVariant({
|
||||
potato: (flavor) => `@media (potato: ${flavor})`,
|
||||
})
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
let input = css`
|
||||
@tailwind utilities;
|
||||
`
|
||||
|
||||
return run(input, config).then((result) => {
|
||||
expect(result.css).toMatchFormattedCss(css`
|
||||
@media (potato: baked) {
|
||||
.potato-\[baked\]\:w-3 {
|
||||
width: 0.75rem;
|
||||
}
|
||||
}
|
||||
@media (potato: yellow) {
|
||||
.potato-\[yellow\]\:bg-yellow-200 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(254 240 138 / var(--tw-bg-opacity));
|
||||
}
|
||||
}
|
||||
`)
|
||||
})
|
||||
})
|
||||
|
||||
test('partial arbitrary variants with at-rules and placeholder', () => {
|
||||
let config = {
|
||||
content: [
|
||||
{
|
||||
raw: html`<div class="potato-[yellow]:bg-yellow-200 potato-[baked]:w-3"></div> `,
|
||||
},
|
||||
],
|
||||
corePlugins: { preflight: false },
|
||||
plugins: [
|
||||
({ matchVariant }) => {
|
||||
matchVariant({
|
||||
potato: (flavor) => `@media (potato: ${flavor}) { &:potato }`,
|
||||
})
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
let input = css`
|
||||
@tailwind utilities;
|
||||
`
|
||||
|
||||
return run(input, config).then((result) => {
|
||||
expect(result.css).toMatchFormattedCss(css`
|
||||
@media (potato: baked) {
|
||||
.potato-\[baked\]\:w-3:potato {
|
||||
width: 0.75rem;
|
||||
}
|
||||
}
|
||||
@media (potato: yellow) {
|
||||
.potato-\[yellow\]\:bg-yellow-200:potato {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(254 240 138 / var(--tw-bg-opacity));
|
||||
}
|
||||
}
|
||||
`)
|
||||
})
|
||||
})
|
||||
|
||||
test('partial arbitrary variants with default values', () => {
|
||||
let config = {
|
||||
content: [
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue