Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ignore PostCSS nodes returned by addVariant #8608

Merged
merged 2 commits into from Jun 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Fix extraction of multi-word utilities with arbitrary values and quotes ([#8604](https://github.com/tailwindlabs/tailwindcss/pull/8604))
- Fix casing of import of `corePluginList` type definition ([#8587](https://github.com/tailwindlabs/tailwindcss/pull/8587))
- Ignore PostCSS nodes returned by `addVariant` ([#8608](https://github.com/tailwindlabs/tailwindcss/pull/8608))

## [3.1.2] - 2022-06-10

Expand Down
7 changes: 5 additions & 2 deletions src/lib/setupContextUtils.js
Expand Up @@ -465,11 +465,14 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
}

if (Array.isArray(result)) {
return result.map((variant) => parseVariant(variant))
return result
.filter((variant) => typeof variant === 'string')
.map((variant) => parseVariant(variant))
}

// result may be undefined with legacy variants that use APIs like `modifySelectors`
return result && parseVariant(result)(api)
// result may also be a postcss node if someone was returning the result from `modifySelectors`
return result && typeof result === 'string' && parseVariant(result)(api)
}
}

Expand Down
51 changes: 51 additions & 0 deletions tests/variants.test.js
Expand Up @@ -461,6 +461,57 @@ test('before and after variants are a bit special, and forced to the end (2)', (
})
})

test('returning non-strings and non-selectors in addVariant', () => {
/** @type {import('../types/config').Config} */
let config = {
content: [
{
raw: html`
<div class="peer-aria-expanded:text-center"></div>
<div class="peer-aria-expanded-2:text-center"></div>
`,
},
],
plugins: [
function ({ addVariant, e }) {
addVariant('peer-aria-expanded', ({ modifySelectors, separator }) =>
// Returning anything other string | string[] | undefined here is not supported
// But we're trying to be lenient here and just throw it out
modifySelectors(
({ className }) =>
`.peer[aria-expanded="true"] ~ .${e(`peer-aria-expanded${separator}${className}`)}`
)
)

addVariant('peer-aria-expanded-2', ({ modifySelectors, separator }) => {
let nodes = modifySelectors(
({ className }) =>
`.peer[aria-expanded="false"] ~ .${e(`peer-aria-expanded${separator}${className}`)}`
)

return [
// Returning anything other than strings here is not supported
// But we're trying to be lenient here and just throw it out
nodes,
'.peer[aria-expanded="false"] ~ &',
]
})
},
],
}

return run('@tailwind components;@tailwind utilities', config).then((result) => {
return expect(result.css).toMatchFormattedCss(css`
.peer[aria-expanded='true'] ~ .peer-aria-expanded\:text-center {
text-align: center;
}
.peer[aria-expanded='false'] ~ .peer-aria-expanded-2\:text-center {
text-align: center;
}
`)
})
})

it('should not generate variants of user css if it is not inside a layer', () => {
let config = {
content: [{ raw: html`<div class="hover:foo"></div>` }],
Expand Down