Migrate [&>*] to * variant, and [&_*] to ** variant (#15022)

This PR adds a migration to convert the `[&>*]` variant to the `*`
variant. Additionally this PR also converts the `[&_*]` variant to the
`**` variant.

We use this variant in Catalyst for example, and now that the
specificity is the same as `*`, we can use the more modern syntax
instead.


# Test plan:

Running this on Catalyst results in a diff like:
<img width="615" alt="image"
src="https://github.com/user-attachments/assets/f384885e-cae1-4b6b-80ab-85f76fa89a33">

<img width="833" alt="image"
src="https://github.com/user-attachments/assets/8a185e1d-0f1b-4fe6-9e06-ca7597534398">


Note: the swapped order of variants is another codemod at work

---------

Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
This commit is contained in:
Robin Malfait 2024-11-18 16:19:15 +01:00 • committed by GitHub
parent 3dc3bad781
commit 4687777788
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 40 additions and 2 deletions

View file

@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Reintroduce `max-w-screen-*` utilities that read from the `--breakpoint` namespace as deprecated utilities ([#15013](https://github.com/tailwindlabs/tailwindcss/pull/15013))
- Support using CSS variables as arbitrary values without `var(…)` by using parentheses instead of square brackets (e.g. `bg-(--my-color)`) ([#15020](https://github.com/tailwindlabs/tailwindcss/pull/15020))
- _Upgrade (experimental)_: Migrate `[&>*]` to the `*` variant ([#15022](https://github.com/tailwindlabs/tailwindcss/pull/15022))
- _Upgrade (experimental)_: Migrate `[&_*]` to the `**` variant ([#15022](https://github.com/tailwindlabs/tailwindcss/pull/15022))
### Fixed

View file

@ -9,8 +9,11 @@ test.each([
['[[data-visible]&]:flex', 'data-visible:flex'],
['[&>[data-visible]]:flex', '*:data-visible:flex'],
['[&_>_[data-visible]]:flex', '*:data-visible:flex'],
['[&>*]:flex', '*:flex'],
['[&_>_*]:flex', '*:flex'],
['[&_[data-visible]]:flex', '**:data-visible:flex'],
['[&_*]:flex', '**:flex'],
['[&:first-child]:flex', 'first:flex'],
['[&:not(:first-child)]:flex', 'not-first:flex'],

View file

@ -28,8 +28,41 @@ export function modernizeArbitraryValues(
let prefixedVariant: Variant | null = null
// Track whether we need to add a `**:` variant
let addStarStarVariant = false
// `[&>*]` can be replaced with `*`
if (
// Only top-level, so `has-[&>*]` is not supported
parent === null &&
// [&_>_*]:flex
// ^ ^ ^
ast.nodes[0].length === 3 &&
ast.nodes[0].nodes[0].type === 'nesting' &&
ast.nodes[0].nodes[0].value === '&' &&
ast.nodes[0].nodes[1].type === 'combinator' &&
ast.nodes[0].nodes[1].value === '>' &&
ast.nodes[0].nodes[2].type === 'universal'
) {
changed = true
Object.assign(variant, designSystem.parseVariant('*'))
continue
}
// `[&_*]` can be replaced with `**`
if (
// Only top-level, so `has-[&_*]` is not supported
parent === null &&
// [&_*]:flex
// ^ ^
ast.nodes[0].length === 3 &&
ast.nodes[0].nodes[0].type === 'nesting' &&
ast.nodes[0].nodes[0].value === '&' &&
ast.nodes[0].nodes[1].type === 'combinator' &&
ast.nodes[0].nodes[1].value === ' ' &&
ast.nodes[0].nodes[2].type === 'universal'
) {
changed = true
Object.assign(variant, designSystem.parseVariant('**'))
continue
}
// Handling a child combinator. E.g.: `[&>[data-visible]]` => `*:data-visible`
if (