From 46877777883a93191beaa075dfe02c43a79b65a6 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Mon, 18 Nov 2024 16:19:15 +0100 Subject: [PATCH] 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: image image Note: the swapped order of variants is another codemod at work --------- Co-authored-by: Adam Wathan --- CHANGELOG.md | 2 + .../modernize-arbitrary-values.test.ts | 3 ++ .../codemods/modernize-arbitrary-values.ts | 37 ++++++++++++++++++- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85babe29c019..dd2b3c2879f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/packages/@tailwindcss-upgrade/src/template/codemods/modernize-arbitrary-values.test.ts b/packages/@tailwindcss-upgrade/src/template/codemods/modernize-arbitrary-values.test.ts index 9a5441da95cb..f5a2c3d7e6d4 100644 --- a/packages/@tailwindcss-upgrade/src/template/codemods/modernize-arbitrary-values.test.ts +++ b/packages/@tailwindcss-upgrade/src/template/codemods/modernize-arbitrary-values.test.ts @@ -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'], diff --git a/packages/@tailwindcss-upgrade/src/template/codemods/modernize-arbitrary-values.ts b/packages/@tailwindcss-upgrade/src/template/codemods/modernize-arbitrary-values.ts index dbf08084fc40..7bcd252eb797 100644 --- a/packages/@tailwindcss-upgrade/src/template/codemods/modernize-arbitrary-values.ts +++ b/packages/@tailwindcss-upgrade/src/template/codemods/modernize-arbitrary-values.ts @@ -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 (