Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CSS codemod for missing @layer #14504

Merged
merged 13 commits into from
Sep 24, 2024

Conversation

RobinMalfait
Copy link
Member

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:

@tailwind base;
@tailwind components;
@tailwind utilities;

Into:

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

@tailwind base;

body {
  background-color: red;
}

@tailwind components;

.btn {}

@tailwind utilities;

This will now be turned into:

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

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

import { expect, it } from 'vitest'
import { formatNodes } from './format-nodes'

function markPretty(): Plugin {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a quick plugin to mark the nodes with tailwind_pretty

walk(root, (child) => {
if (child.raws.tailwind_pretty) {
nodesToFormat.push(child)
return WalkAction.Skip
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the custom walk implementation so that we can skip going inside of the node, once we found a node with tailwind_pretty.

@RobinMalfait RobinMalfait force-pushed the feat/css-codemods-at-layer-utilities branch from e361319 to 7abb3fd Compare September 24, 2024 15:59
@RobinMalfait RobinMalfait force-pushed the feat/css-codemods-inject-missing-layers branch from 5f46eb2 to 266fffb Compare September 24, 2024 16:04
Base automatically changed from feat/css-codemods-at-layer-utilities to next September 24, 2024 16:17
This way we can ensure that all migrations run in order as expected.
This allows us to re-use the logic, the only thing we have to do is mark
a node with `raws.tailwind_pretty = true`
We will convert `@tailwind` directives in one step to `@import`
at-rules. These could now exist in the middle of the CSS. This step
hoists them to the top in a separate pass.
We don't need this, the migrate directives already takes care of this by
prepending at-rules to the top.
Instead of crafting a bad input, we can just not do it.
@RobinMalfait RobinMalfait force-pushed the feat/css-codemods-inject-missing-layers branch from 266fffb to e5e07f9 Compare September 24, 2024 16:17
@RobinMalfait RobinMalfait enabled auto-merge (squash) September 24, 2024 16:27
@RobinMalfait RobinMalfait merged commit d869442 into next Sep 24, 2024
3 checks passed
@RobinMalfait RobinMalfait deleted the feat/css-codemods-inject-missing-layers branch September 24, 2024 16:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants