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;
}
```
This commit is contained in:
Robin Malfait 2024-10-04 12:47:05 +02:00 • committed by GitHub
parent 60b0e9c6a0
commit e3764ac843
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 59 additions and 0 deletions

View file

@ -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

View file

@ -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;
}
}"
`)
})

View file

@ -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

View file

@ -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;
}"
`)
})