From e3764ac843ad94863553cccea01046a03bc52982 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Fri, 4 Oct 2024 12:47:05 +0200 Subject: [PATCH] Ensure CSS before a layer stays unlayered (#14596) This PR fixes an issue where CSS that existed before a layer: ```css .foo { color: red; } @layer components { .bar { color: blue; } } ``` Was turned into an `@layer` without a name: ```css @layer { .foo { color: red; } } @utility bar { color: blue; } ``` But in this case, it should stay as-is: ```css .foo { color: red; } @utility bar { color: blue; } ``` --- CHANGELOG.md | 1 + .../codemods/migrate-missing-layers.test.ts | 26 ++++++++++++++++++ .../src/codemods/migrate-missing-layers.ts | 5 ++++ .../@tailwindcss-upgrade/src/index.test.ts | 27 +++++++++++++++++++ 4 files changed, 59 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c6be95ffc..07d67c8c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Don’t crash when scanning a candidate equal to the configured prefix ([#14588](https://github.com/tailwindlabs/tailwindcss/pull/14588)) +- _Experimental_: Ensure CSS before a layer stays unlayered when running codemods ([#14596](https://github.com/tailwindlabs/tailwindcss/pull/14596)) ## [4.0.0-alpha.26] - 2024-10-03 diff --git a/packages/@tailwindcss-upgrade/src/codemods/migrate-missing-layers.test.ts b/packages/@tailwindcss-upgrade/src/codemods/migrate-missing-layers.test.ts index 055a25269..7dec9bcda 100644 --- a/packages/@tailwindcss-upgrade/src/codemods/migrate-missing-layers.test.ts +++ b/packages/@tailwindcss-upgrade/src/codemods/migrate-missing-layers.test.ts @@ -165,3 +165,29 @@ it('should migrate rules between tailwind directives', async () => { }" `) }) + +it('should keep CSS above a layer unlayered', async () => { + expect( + await migrate(css` + .foo { + color: red; + } + + @layer components { + .bar { + color: blue; + } + } + `), + ).toMatchInlineSnapshot(` + ".foo { + color: red; + } + + @layer components { + .bar { + color: blue; + } + }" + `) +}) diff --git a/packages/@tailwindcss-upgrade/src/codemods/migrate-missing-layers.ts b/packages/@tailwindcss-upgrade/src/codemods/migrate-missing-layers.ts index 4ccfe9b96..c32c60906 100644 --- a/packages/@tailwindcss-upgrade/src/codemods/migrate-missing-layers.ts +++ b/packages/@tailwindcss-upgrade/src/codemods/migrate-missing-layers.ts @@ -97,6 +97,11 @@ export function migrateMissingLayers(): Plugin { // Wrap each bucket in an `@layer` at-rule for (let [layerName, nodes] of buckets) { + let targetLayerName = layerName || firstLayerName || '' + if (targetLayerName === '') { + continue + } + // Do not wrap comments in a layer, if they are the only nodes. if (nodes.every((node) => node.type === 'comment')) { continue diff --git a/packages/@tailwindcss-upgrade/src/index.test.ts b/packages/@tailwindcss-upgrade/src/index.test.ts index 8c84bc76e..4dbfaf46f 100644 --- a/packages/@tailwindcss-upgrade/src/index.test.ts +++ b/packages/@tailwindcss-upgrade/src/index.test.ts @@ -154,3 +154,30 @@ it('should migrate a stylesheet (with preceding rules that should be wrapped in }" `) }) + +it('should keep CSS as-is before existing `@layer` at-rules', async () => { + expect( + await migrateContents( + css` + .foo { + color: blue; + } + + @layer components { + .bar { + color: red; + } + } + `, + {}, + ), + ).toMatchInlineSnapshot(` + ".foo { + color: blue; + } + + @utility bar { + color: red; + }" + `) +})