4 Commits

Author SHA1 Message Date
Robin Malfait
ceae1dbdfb
CSS codemod: do not wrap comment nodes in @layer (#14517)
When CSS exists between two tailwind directives, then the CSS will be
wrapped in an `@layer` to ensure it all ends up in the correct location
in the final CSS file.

However, if the only thing between two tailwind directives is a comment,
then the comment will also be wrapped in an `@layer` directive.

E.g.:
```css
@tailwind base;
/* This is a comment */
@tailwind components;
/* This is another comment */
@tailwind utilities;
```

Results in:
```css
@import "tailwindcss";
@layer base {
  /* This is a comment */
}
@layer components {
  /* This is another comment */
}
```

In this case, the layers don't matter, so this can be simplified to:
```css
@import "tailwindcss";
/* This is a comment */
/* This is another comment */
```
2024-09-25 12:58:05 +00:00
Robin Malfait
723f5db38b
CSS codemod: Fix incorrect empty layer() at the end of @import at-rules (#14513)
This PR fixes an issue where some `@import` at-rules had an empty
`layer()` attached at the end of the `@import` string.

We should only add that if a Tailwind directive or Tailwind import such
as `@tailwind base` or `@import "tailwindcss/base"` preceded the current
`@import` at-rule. If there was no Tailwind directive, the `lastLayer`
will be empty and we don't need to attach it to the `@import` string.
2024-09-25 13:48:14 +02:00
Robin Malfait
951f6448fe
Improve missing layer codemod (#14512)
This PR improves the missing layers codemod where everything after the
last Tailwind directive can stay as-is without wrapping it in a `@layer`
directive.

The `@layer` at-rules are only important for CSS that exists between
Tailwind directives.

E.g.:
```css
@tailwind base;

html {}

@tailwind components;

.btn {}

@tailwind utilities;

.foo {}

.bar {}
```

Was transformed into:
```css
@import "tailwindcss";

@layer base {
  html {}
}

@layer components {
  .btn {}
}

@layer utilities {
  .foo {}
  
  .bar {}
}
```

But the last `@layer utilities` is already in the correct spot, so we
can simplify this to just this instead:
```css
@import "tailwindcss";

@layer base {
  html {}
}

@layer components {
  .btn {}
}

.foo {}

.bar {}
```
2024-09-25 08:42:19 +00:00
Robin Malfait
d869442a54
Add CSS codemod for missing @layer (#14504)
This PR adds a codemod that ensures that some parts of your stylesheet
are wrapped in an `@layer`.

This is a follow-up PR of #14411, in that PR we migrate `@tailwind`
directives to imports.

As a quick summary, that will turn this:
```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

Into:
```css
@import 'tailwindcss';
```

But there are a few issues with that _if_ we have additional CSS on the
page. For example let's imagine we had this:
```css
@tailwind base;

body {
  background-color: red;
}

@tailwind components;

.btn {}

@tailwind utilities;
```

This will now be turned into:
```css
@import 'tailwindcss';

body {
  background-color: red;
}

.btn {}
```

But in v4 we use real layers, in v3 we used to replace the directive
with the result of that layer. This means that now the `body` and `.btn`
styles are in the incorrect spot.

To solve this, we have to wrap them in a layer. The `body` should go in
an `@layer base`, and the `.btn` should be in an `@layer components` to
make sure it's in the same spot as it was before.

That's what this PR does, the original input will now be turned into:

```css
@import 'tailwindcss';

@layer base {
  body {
    background-color: red;
  }
}

@layer components {
  .btn {
  }
}
```

There are a few internal refactors going on as well, but those are less
important.
2024-09-24 16:32:50 +00:00