mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
During the migration process, a lot of changes to the CSS file happen.
Some parts are converted, some parts are deleted and some new CSS is
added.
To make sure we are generating a sensible and good looking CSS file, we
will sort the final CSS and pretty print it.
The order we came up with looks like this:
```css
/* Imports */
@import "tailwindcss";
@import "../other.css";
/* Configuration */
@config "../path/to/tailwindcss.config.js";
@plugin "my-plugin-1";
@plugin "my-plugin-2";
@source "./foo/**/*.ts";
@source "./bar/**/*.ts";
@variant foo {}
@variant bar {}
@theme {}
/* Border compatibility CSS */
@layer base {}
/* Utilities */
@utility foo {}
@utility bar {}
/* Rest of your own CSS if any */
```
---------
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
312 lines
7.0 KiB
TypeScript
312 lines
7.0 KiB
TypeScript
import { __unstable__loadDesignSystem } from '@tailwindcss/node'
|
|
import dedent from 'dedent'
|
|
import path from 'node:path'
|
|
import postcss from 'postcss'
|
|
import { expect, it } from 'vitest'
|
|
import { formatNodes } from './codemods/format-nodes'
|
|
import { sortBuckets } from './codemods/sort-buckets'
|
|
import { migrateContents } from './migrate'
|
|
|
|
const css = dedent
|
|
|
|
let designSystem = await __unstable__loadDesignSystem(
|
|
css`
|
|
@import 'tailwindcss';
|
|
`,
|
|
{ base: __dirname },
|
|
)
|
|
|
|
let config = {
|
|
designSystem,
|
|
userConfig: {},
|
|
newPrefix: null,
|
|
configFilePath: path.resolve(__dirname, './tailwind.config.js'),
|
|
jsConfigMigration: null,
|
|
}
|
|
|
|
function migrate(input: string, config: any) {
|
|
return migrateContents(input, config, expect.getState().testPath)
|
|
.then((result) => postcss([sortBuckets(), formatNodes()]).process(result.root, result.opts))
|
|
.then((result) => result.css)
|
|
}
|
|
|
|
it('should print the input as-is', async () => {
|
|
expect(
|
|
await migrate(
|
|
css`
|
|
/* above */
|
|
.foo/* after */ {
|
|
/* above */
|
|
color: /* before */ red /* after */;
|
|
/* below */
|
|
}
|
|
`,
|
|
config,
|
|
),
|
|
).toMatchInlineSnapshot(`
|
|
"/* above */
|
|
.foo/* after */ {
|
|
/* above */
|
|
color: /* before */ red /* after */;
|
|
/* below */
|
|
}"
|
|
`)
|
|
})
|
|
|
|
it('should migrate a stylesheet', async () => {
|
|
expect(
|
|
await migrate(
|
|
css`
|
|
@tailwind base;
|
|
|
|
html {
|
|
overflow: hidden;
|
|
}
|
|
|
|
@tailwind components;
|
|
|
|
.a {
|
|
z-index: 1;
|
|
}
|
|
|
|
@layer components {
|
|
.b {
|
|
z-index: 2;
|
|
}
|
|
}
|
|
|
|
.c {
|
|
z-index: 3;
|
|
}
|
|
|
|
@tailwind utilities;
|
|
|
|
.d {
|
|
z-index: 4;
|
|
}
|
|
|
|
@layer utilities {
|
|
.e {
|
|
z-index: 5;
|
|
}
|
|
}
|
|
`,
|
|
config,
|
|
),
|
|
).toMatchInlineSnapshot(`
|
|
"@import 'tailwindcss';
|
|
|
|
/*
|
|
The default border color has changed to \`currentColor\` in Tailwind CSS v4,
|
|
so we've added these compatibility styles to make sure everything still
|
|
looks the same as it did with Tailwind CSS v3.
|
|
|
|
If we ever want to remove these styles, we need to add an explicit border
|
|
color utility to any element that depends on these defaults.
|
|
*/
|
|
@layer base {
|
|
*,
|
|
::after,
|
|
::before,
|
|
::backdrop,
|
|
::file-selector-button {
|
|
border-color: var(--color-gray-200, currentColor);
|
|
}
|
|
}
|
|
|
|
/*
|
|
Form elements have a 1px border by default in Tailwind CSS v4, so we've
|
|
added these compatibility styles to make sure everything still looks the
|
|
same as it did with Tailwind CSS v3.
|
|
|
|
If we ever want to remove these styles, we need to add \`border-0\` to
|
|
any form elements that shouldn't have a border.
|
|
*/
|
|
@layer base {
|
|
input:where(:not([type='button'], [type='reset'], [type='submit'])),
|
|
select,
|
|
textarea {
|
|
border-width: 0;
|
|
}
|
|
}
|
|
|
|
@utility b {
|
|
z-index: 2;
|
|
}
|
|
|
|
@utility e {
|
|
z-index: 5;
|
|
}
|
|
|
|
@layer base {
|
|
html {
|
|
overflow: hidden;
|
|
}
|
|
}
|
|
|
|
@layer components {
|
|
.a {
|
|
z-index: 1;
|
|
}
|
|
}
|
|
|
|
@layer components {
|
|
.c {
|
|
z-index: 3;
|
|
}
|
|
}
|
|
|
|
@layer utilities {
|
|
.d {
|
|
z-index: 4;
|
|
}
|
|
}"
|
|
`)
|
|
})
|
|
|
|
it('should migrate a stylesheet (with imports)', async () => {
|
|
expect(
|
|
await migrate(
|
|
css`
|
|
@import 'tailwindcss/base';
|
|
@import './my-base.css';
|
|
@import 'tailwindcss/components';
|
|
@import './my-components.css';
|
|
@import 'tailwindcss/utilities';
|
|
@import './my-utilities.css';
|
|
`,
|
|
config,
|
|
),
|
|
).toMatchInlineSnapshot(`
|
|
"@import 'tailwindcss';
|
|
@import './my-base.css' layer(base);
|
|
@import './my-components.css' layer(components);
|
|
@import './my-utilities.css' layer(utilities);
|
|
|
|
/*
|
|
The default border color has changed to \`currentColor\` in Tailwind CSS v4,
|
|
so we've added these compatibility styles to make sure everything still
|
|
looks the same as it did with Tailwind CSS v3.
|
|
|
|
If we ever want to remove these styles, we need to add an explicit border
|
|
color utility to any element that depends on these defaults.
|
|
*/
|
|
@layer base {
|
|
*,
|
|
::after,
|
|
::before,
|
|
::backdrop,
|
|
::file-selector-button {
|
|
border-color: var(--color-gray-200, currentColor);
|
|
}
|
|
}
|
|
|
|
/*
|
|
Form elements have a 1px border by default in Tailwind CSS v4, so we've
|
|
added these compatibility styles to make sure everything still looks the
|
|
same as it did with Tailwind CSS v3.
|
|
|
|
If we ever want to remove these styles, we need to add \`border-0\` to
|
|
any form elements that shouldn't have a border.
|
|
*/
|
|
@layer base {
|
|
input:where(:not([type='button'], [type='reset'], [type='submit'])),
|
|
select,
|
|
textarea {
|
|
border-width: 0;
|
|
}
|
|
}"
|
|
`)
|
|
})
|
|
|
|
it('should migrate a stylesheet (with preceding rules that should be wrapped in an `@layer`)', async () => {
|
|
expect(
|
|
await migrate(
|
|
css`
|
|
@charset "UTF-8";
|
|
@layer foo, bar, baz;
|
|
/**! My license comment */
|
|
html {
|
|
color: red;
|
|
}
|
|
@tailwind base;
|
|
@tailwind components;
|
|
@tailwind utilities;
|
|
`,
|
|
config,
|
|
),
|
|
).toMatchInlineSnapshot(`
|
|
"@charset "UTF-8";
|
|
@layer foo, bar, baz;
|
|
/**! My license comment */
|
|
@import 'tailwindcss';
|
|
|
|
/*
|
|
The default border color has changed to \`currentColor\` in Tailwind CSS v4,
|
|
so we've added these compatibility styles to make sure everything still
|
|
looks the same as it did with Tailwind CSS v3.
|
|
|
|
If we ever want to remove these styles, we need to add an explicit border
|
|
color utility to any element that depends on these defaults.
|
|
*/
|
|
@layer base {
|
|
*,
|
|
::after,
|
|
::before,
|
|
::backdrop,
|
|
::file-selector-button {
|
|
border-color: var(--color-gray-200, currentColor);
|
|
}
|
|
}
|
|
|
|
/*
|
|
Form elements have a 1px border by default in Tailwind CSS v4, so we've
|
|
added these compatibility styles to make sure everything still looks the
|
|
same as it did with Tailwind CSS v3.
|
|
|
|
If we ever want to remove these styles, we need to add \`border-0\` to
|
|
any form elements that shouldn't have a border.
|
|
*/
|
|
@layer base {
|
|
input:where(:not([type='button'], [type='reset'], [type='submit'])),
|
|
select,
|
|
textarea {
|
|
border-width: 0;
|
|
}
|
|
}
|
|
|
|
@layer base {
|
|
html {
|
|
color: red;
|
|
}
|
|
}"
|
|
`)
|
|
})
|
|
|
|
it('should keep CSS as-is before existing `@layer` at-rules', async () => {
|
|
expect(
|
|
await migrate(
|
|
css`
|
|
.foo {
|
|
color: blue;
|
|
}
|
|
|
|
@layer components {
|
|
.bar {
|
|
color: red;
|
|
}
|
|
}
|
|
`,
|
|
config,
|
|
),
|
|
).toMatchInlineSnapshot(`
|
|
"@utility bar {
|
|
color: red;
|
|
}
|
|
|
|
.foo {
|
|
color: blue;
|
|
}"
|
|
`)
|
|
})
|