mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
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:
parent
e8546df800
commit
705255583c
@ -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))
|
||||
- Don’t 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
|
||||
|
||||
|
||||
@ -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;
|
||||
}"
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user