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.
35 lines
825 B
TypeScript
35 lines
825 B
TypeScript
import postcss, { type Plugin } from 'postcss'
|
|
import { expect, it } from 'vitest'
|
|
import { formatNodes } from './format-nodes'
|
|
|
|
function markPretty(): Plugin {
|
|
return {
|
|
postcssPlugin: '@tailwindcss/upgrade/mark-pretty',
|
|
OnceExit(root) {
|
|
root.walkAtRules('utility', (atRule) => {
|
|
atRule.raws.tailwind_pretty = true
|
|
})
|
|
},
|
|
}
|
|
}
|
|
|
|
function migrate(input: string) {
|
|
return postcss()
|
|
.use(markPretty())
|
|
.use(formatNodes())
|
|
.process(input, { from: expect.getState().testPath })
|
|
.then((result) => result.css)
|
|
}
|
|
|
|
it('should format PostCSS nodes that are marked with tailwind_pretty', async () => {
|
|
expect(
|
|
await migrate(`
|
|
@utility .foo { .foo { color: red; } }`),
|
|
).toMatchInlineSnapshot(`
|
|
"@utility .foo {
|
|
.foo {
|
|
color: red;
|
|
}
|
|
}"
|
|
`)
|
|
})
|