Ensure compound variants work with variants with multiple selectors (#14016)

* Ensure compound variants work with variants with multiple selectors

* Update changelog
This commit is contained in:
Jordan Pittman 2024-07-17 15:03:57 -04:00 committed by GitHub
parent e8546df800
commit 705255583c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 140 additions and 34 deletions

View File

@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Discard invalid `variants` and `utilities` with modifiers ([#13977](https://github.com/tailwindlabs/tailwindcss/pull/13977))
- Add missing utilities that exist in v3, such as `resize`, `fill-none`, `accent-none`, `drop-shadow-none`, and negative `hue-rotate` and `backdrop-hue-rotate` utilities ([#13971](https://github.com/tailwindlabs/tailwindcss/pull/13971))
- Dont allow at-rule-only variants to be compounded ([#14015](https://github.com/tailwindlabs/tailwindcss/pull/14015))
- Ensure compound variants work with variants with multiple selectors ([#14016](https://github.com/tailwindlabs/tailwindcss/pull/14016))
### Added

View File

@ -738,12 +738,25 @@ test('group-[...]', () => {
test('group-*', () => {
expect(
run([
'group-hover:flex',
'group-focus:flex',
'group-hover:group-focus:flex',
'group-focus:group-hover:flex',
]),
compileCss(
css`
@variant hocus {
&:hover,
&:focus {
@slot;
}
}
@tailwind utilities;
`,
[
'group-hover:flex',
'group-focus:flex',
'group-hocus:flex',
'group-hover:group-focus:flex',
'group-focus:group-hover:flex',
],
),
).toMatchInlineSnapshot(`
".group-hover\\:flex:is(:where(.group):hover *) {
display: flex;
@ -759,6 +772,10 @@ test('group-*', () => {
.group-hover\\:group-focus\\:flex:is(:where(.group):hover *):is(:where(.group):focus *) {
display: flex;
}
.group-hocus\\:flex:is(:is(:where(.group):hover, :where(.group):focus) *) {
display: flex;
}"
`)
@ -816,12 +833,24 @@ test('peer-[...]', () => {
test('peer-*', () => {
expect(
run([
'peer-hover:flex',
'peer-focus:flex',
'peer-hover:peer-focus:flex',
'peer-focus:peer-hover:flex',
]),
compileCss(
css`
@variant hocus {
&:hover,
&:focus {
@slot;
}
}
@tailwind utilities;
`,
[
'peer-hover:flex',
'peer-focus:flex',
'peer-hocus:flex',
'peer-hover:peer-focus:flex',
'peer-focus:peer-hover:flex',
],
),
).toMatchInlineSnapshot(`
".peer-hover\\:flex:is(:where(.peer):hover ~ *) {
display: flex;
@ -837,6 +866,10 @@ test('peer-*', () => {
.peer-hover\\:peer-focus\\:flex:is(:where(.peer):hover ~ *):is(:where(.peer):focus ~ *) {
display: flex;
}
.peer-hocus\\:flex:is(:is(:where(.peer):hover, :where(.peer):focus) ~ *) {
display: flex;
}"
`)
@ -1502,19 +1535,39 @@ test('supports', () => {
test('not', () => {
expect(
run([
'not-[:checked]:flex',
compileCss(
css`
@variant hocus {
&:hover,
&:focus {
@slot;
}
}
@tailwind utilities;
`,
[
'not-[:checked]:flex',
'not-hocus:flex',
'group-not-[:checked]:flex',
'group-not-[:checked]/parent-name:flex',
'group-not-checked:flex',
'group-not-[:checked]:flex',
'group-not-[:checked]/parent-name:flex',
'group-not-checked:flex',
'group-not-hocus:flex',
'group-not-hocus/parent-name:flex',
'peer-not-[:checked]:flex',
'peer-not-[:checked]/parent-name:flex',
'peer-not-checked:flex',
]),
'peer-not-[:checked]:flex',
'peer-not-[:checked]/sibling-name:flex',
'peer-not-checked:flex',
'peer-not-hocus:flex',
'peer-not-hocus/sibling-name:flex',
],
),
).toMatchInlineSnapshot(`
".not-\\[\\:checked\\]\\:flex:not(:checked) {
".not-hocus\\:flex:not(:hover, :focus) {
display: flex;
}
.not-\\[\\:checked\\]\\:flex:not(:checked) {
display: flex;
}
@ -1522,6 +1575,14 @@ test('not', () => {
display: flex;
}
.group-not-hocus\\:flex:is(:where(.group):not(:hover, :focus) *) {
display: flex;
}
.group-not-hocus\\/parent-name\\:flex:is(:where(.group\\/parent-name):not(:hover, :focus) *) {
display: flex;
}
.group-not-\\[\\:checked\\]\\:flex:is(:where(.group):not(:checked) *) {
display: flex;
}
@ -1534,11 +1595,19 @@ test('not', () => {
display: flex;
}
.peer-not-hocus\\:flex:is(:where(.peer):not(:hover, :focus) ~ *) {
display: flex;
}
.peer-not-hocus\\/sibling-name\\:flex:is(:where(.peer\\/sibling-name):not(:hover, :focus) ~ *) {
display: flex;
}
.peer-not-\\[\\:checked\\]\\:flex:is(:where(.peer):not(:checked) ~ *) {
display: flex;
}
.peer-not-\\[\\:checked\\]\\/parent-name\\:flex:is(:where(.peer\\/parent-name):not(:checked) ~ *) {
.peer-not-\\[\\:checked\\]\\/sibling-name\\:flex:is(:where(.peer\\/sibling-name):not(:checked) ~ *) {
display: flex;
}"
`)
@ -1556,22 +1625,46 @@ test('not', () => {
test('has', () => {
expect(
run([
'has-[:checked]:flex',
compileCss(
css`
@variant hocus {
&:hover,
&:focus {
@slot;
}
}
@tailwind utilities;
`,
[
'has-[:checked]:flex',
'has-hocus:flex',
'group-has-[:checked]:flex',
'group-has-[:checked]/parent-name:flex',
'group-has-checked:flex',
'group-has-[:checked]:flex',
'group-has-[:checked]/parent-name:flex',
'group-has-checked:flex',
'group-has-hocus:flex',
'group-has-hocus/parent-name:flex',
'peer-has-[:checked]:flex',
'peer-has-[:checked]/sibling-name:flex',
'peer-has-checked:flex',
]),
'peer-has-[:checked]:flex',
'peer-has-[:checked]/sibling-name:flex',
'peer-has-checked:flex',
'peer-has-hocus:flex',
'peer-has-hocus/sibling-name:flex',
],
),
).toMatchInlineSnapshot(`
".group-has-checked\\:flex:is(:where(.group):has(:checked) *) {
display: flex;
}
.group-has-hocus\\:flex:is(:where(.group):has(:hover, :focus) *) {
display: flex;
}
.group-has-hocus\\/parent-name\\:flex:is(:where(.group\\/parent-name):has(:hover, :focus) *) {
display: flex;
}
.group-has-\\[\\:checked\\]\\:flex:is(:where(.group):has(:checked) *) {
display: flex;
}
@ -1584,6 +1677,14 @@ test('has', () => {
display: flex;
}
.peer-has-hocus\\:flex:is(:where(.peer):has(:hover, :focus) ~ *) {
display: flex;
}
.peer-has-hocus\\/sibling-name\\:flex:is(:where(.peer\\/sibling-name):has(:hover, :focus) ~ *) {
display: flex;
}
.peer-has-\\[\\:checked\\]\\:flex:is(:where(.peer):has(:checked) ~ *) {
display: flex;
}
@ -1592,6 +1693,10 @@ test('has', () => {
display: flex;
}
.has-hocus\\:flex:has(:hover, :focus) {
display: flex;
}
.has-\\[\\:checked\\]\\:flex:has(:checked) {
display: flex;
}"

View File

@ -216,7 +216,7 @@ export function createVariants(theme: Theme): Variants {
// Replace `&` in target variant with `*`, so variants like `&:hover`
// become `&:not(*:hover)`. The `*` will often be optimized away.
node.selector = `&:not(${node.selector.replace('&', '*')})`
node.selector = `&:not(${node.selector.replaceAll('&', '*')})`
// Track that the variant was actually applied
didApply = true
@ -442,7 +442,7 @@ export function createVariants(theme: Theme): Variants {
// Replace `&` in target variant with `*`, so variants like `&:hover`
// become `&:has(*:hover)`. The `*` will often be optimized away.
node.selector = `&:has(${node.selector.replace('&', '*')})`
node.selector = `&:has(${node.selector.replaceAll('&', '*')})`
// Track that the variant was actually applied
didApply = true