From 005edae6c18dcd5e957eb12aab7d5ac36ff1f87a Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Thu, 24 Oct 2024 00:35:02 +0200 Subject: [PATCH 1/5] add failing test --- integrations/upgrade/index.test.ts | 522 +----------------- .../migrate-border-compatibility.test.ts | 189 ++++++- 2 files changed, 172 insertions(+), 539 deletions(-) diff --git a/integrations/upgrade/index.test.ts b/integrations/upgrade/index.test.ts index 83d1bc89e860..d92502a9fd39 100644 --- a/integrations/upgrade/index.test.ts +++ b/integrations/upgrade/index.test.ts @@ -893,39 +893,6 @@ test( @import 'tailwindcss/utilities' layer(utilities); @import './utilities.css'; - /* - 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; - } - } - --- ./src/utilities.css --- @utility no-scrollbar { &::-webkit-scrollbar { @@ -1037,82 +1004,13 @@ test( @import 'tailwindcss/utilities' layer(utilities); @import './a.1.css' layer(utilities); @import './a.1.utilities.1.css'; - @import './b.1.css' layer(components); - @import './b.1.utilities.css'; + @import './b.1.css'; @import './c.1.css'; @import './c.1.utilities.css'; @import './d.1.css'; - @import './d.1.utilities.css'; - - /* - 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; - } - } --- ./src/a.1.css --- - @import './a.1.utilities.css'; - - /* - 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; - } - } + @import './a.1.utilities.css' --- ./src/a.1.utilities.1.css --- @import './a.1.utilities.utilities.css'; @@ -1136,41 +1034,6 @@ test( } --- ./src/b.1.css --- - /* - 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; - } - } - - --- ./src/b.1.utilities.css --- @import './b.1.components.css'; @utility bar-from-b { color: red; @@ -1178,40 +1041,6 @@ test( --- ./src/c.1.css --- @import './c.2.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; - } - } .baz-from-c { color: green; } @@ -1221,40 +1050,6 @@ test( --- ./src/c.2.css --- @import './c.3.css'; - - /* - 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; - } - } #baz { --keep: me; } @@ -1276,121 +1071,12 @@ test( } --- ./src/d.1.css --- - @import './d.2.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; - } - } - - --- ./src/d.1.utilities.css --- - @import './d.2.utilities.css' + @import './d.2.css' --- ./src/d.2.css --- - @import './d.3.css'; - - /* - 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; - } - } - - --- ./src/d.2.utilities.css --- - @import './d.3.utilities.css' + @import './d.3.css' --- ./src/d.3.css --- - /* - 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; - } - } - - --- ./src/d.3.utilities.css --- @import './d.4.css' --- ./src/d.4.css --- @@ -1456,112 +1142,13 @@ test( @import 'tailwindcss/utilities' layer(utilities); @import './a.1.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; - } - } - --- ./src/root.2.css --- @import 'tailwindcss/utilities' layer(utilities); @import './a.1.css' layer(components); - /* - 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; - } - } - --- ./src/root.3.css --- @import 'tailwindcss/utilities' layer(utilities); @import './a.1.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; - } - } " `) }, @@ -1777,76 +1364,9 @@ test( @import './root.4/utilities.css'; @config '../tailwind.config.ts'; - /* - 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; - } - } - --- ./src/root.5.css --- @import './root.5/tailwind.css'; - /* - 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; - } - } - --- ./src/root.4/base.css --- @import 'tailwindcss/theme' layer(theme); @import 'tailwindcss/preflight' layer(base); @@ -1888,40 +1408,6 @@ test( --- ./src/root.4/utilities.css --- @import 'tailwindcss/utilities' 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; - } - } - --- ./src/root.5/tailwind.css --- /* Inject missing @config in this file, due to full import */ @import 'tailwindcss'; diff --git a/packages/@tailwindcss-upgrade/src/codemods/migrate-border-compatibility.test.ts b/packages/@tailwindcss-upgrade/src/codemods/migrate-border-compatibility.test.ts index df633df5f75d..65bbaac3dbc0 100644 --- a/packages/@tailwindcss-upgrade/src/codemods/migrate-border-compatibility.test.ts +++ b/packages/@tailwindcss-upgrade/src/codemods/migrate-border-compatibility.test.ts @@ -69,14 +69,14 @@ it("should add compatibility CSS after the `@import 'tailwindcss'`", async () => it('should add the compatibility CSS after the last `@import`', async () => { expect( await migrate(css` - @import 'tailwindcss/base'; - @import 'tailwindcss/components'; - @import 'tailwindcss/utilities'; + @import 'tailwindcss'; + @import './foo.css'; + @import './bar.css'; `), ).toMatchInlineSnapshot(` - "@import 'tailwindcss/base'; - @import 'tailwindcss/components'; - @import 'tailwindcss/utilities'; + "@import 'tailwindcss'; + @import './foo.css'; + @import './bar.css'; /* The default border color has changed to \`currentColor\` in Tailwind CSS v4, @@ -117,27 +117,91 @@ it('should add the compatibility CSS after the last import, even if a body-less expect( await migrate(css` @charset "UTF-8"; - @layer foo, bar, baz; + @layer foo, bar, baz, base; /**! * License header */ - @import 'tailwindcss/base'; - @import 'tailwindcss/components'; - @import 'tailwindcss/utilities'; + @import 'tailwindcss'; + @import './foo.css'; + @import './bar.css'; `), ).toMatchInlineSnapshot(` "@charset "UTF-8"; - @layer foo, bar, baz; + @layer foo, bar, baz, base; /**! * License header */ - @import 'tailwindcss/base'; - @import 'tailwindcss/components'; - @import 'tailwindcss/utilities'; + @import 'tailwindcss'; + @import './foo.css'; + @import './bar.css'; + + /* + 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 add the compatibility CSS before the first `@layer base` (if the "tailwindcss" import exists)', async () => { + expect( + await migrate(css` + @import 'tailwindcss'; + + @variant foo { + } + + @utility bar { + } + + @layer base { + } + + @utility baz { + } + + @layer base { + } + `), + ).toMatchInlineSnapshot(` + "@import 'tailwindcss'; + + @variant foo { + } + + @utility bar { + } /* The default border color has changed to \`currentColor\` in Tailwind CSS v4, @@ -147,6 +211,7 @@ it('should add the compatibility CSS after the last import, even if a body-less 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, @@ -156,6 +221,7 @@ it('should add the compatibility CSS after the last import, even if a body-less 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 @@ -170,16 +236,23 @@ it('should add the compatibility CSS after the last import, even if a body-less textarea { border-width: 0; } + } + + @layer base { + } + + @utility baz { + } + + @layer base { }" `) }) -it('should add the compatibility CSS before the first `@layer base`', async () => { +it('should add the compatibility CSS before the first `@layer base` (if the "tailwindcss/preflight" import exists)', async () => { expect( await migrate(css` - @import 'tailwindcss/base'; - @import 'tailwindcss/components'; - @import 'tailwindcss/utilities'; + @import 'tailwindcss/preflight'; @variant foo { } @@ -197,9 +270,7 @@ it('should add the compatibility CSS before the first `@layer base`', async () = } `), ).toMatchInlineSnapshot(` - "@import 'tailwindcss/base'; - @import 'tailwindcss/components'; - @import 'tailwindcss/utilities'; + "@import 'tailwindcss/preflight'; @variant foo { } @@ -252,3 +323,79 @@ it('should add the compatibility CSS before the first `@layer base`', async () = }" `) }) + +it('should not add the backwards compatibility CSS when no `@import "tailwindcss"` or `@import "tailwindcss/preflight"` exists', async () => { + expect( + await migrate(css` + @variant foo { + } + + @utility bar { + } + + @layer base { + } + + @utility baz { + } + + @layer base { + } + `), + ).toMatchInlineSnapshot(` + "@variant foo { + } + + @utility bar { + } + + @layer base { + } + + @utility baz { + } + + @layer base { + }" + `) +}) + +it('should not add the backwards compatibility CSS when another `@import "tailwindcss"` import exists such as theme or utilities', async () => { + expect( + await migrate(css` + @import 'tailwindcss/theme'; + + @variant foo { + } + + @utility bar { + } + + @layer base { + } + + @utility baz { + } + + @layer base { + } + `), + ).toMatchInlineSnapshot(` + "@import 'tailwindcss/theme'; + + @variant foo { + } + + @utility bar { + } + + @layer base { + } + + @utility baz { + } + + @layer base { + }" + `) +}) From 195ac50f005848a83f3fc44d0b9a7741a60c3d3f Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Thu, 24 Oct 2024 00:35:07 +0200 Subject: [PATCH 2/5] inject the border compatibility CSS in "root" files We were always injecting the border compatibility CSS above the first `@layer base`. But in projects where you have multiple files using this `@layer base` it means that the reset is injected in each file. Instead, only try to inject it in files where `@import 'tailwindcss'` or `@import 'tailwindcss/preflight'` is being used. When we see a file with `@import 'tailwindcss'`, we consider it a root file because that's where Tailwind CSS will be injected. If you split up your code, it could be that you have a different file that contains `@import "tailwindcss/preflight";`. This is the import responsible for adding the `@layer base` resets, so this is a good file to put the border compatibility CSS as well. --- .../src/codemods/migrate-border-compatibility.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/@tailwindcss-upgrade/src/codemods/migrate-border-compatibility.ts b/packages/@tailwindcss-upgrade/src/codemods/migrate-border-compatibility.ts index a81465d9cedf..f6e7b1e38246 100644 --- a/packages/@tailwindcss-upgrade/src/codemods/migrate-border-compatibility.ts +++ b/packages/@tailwindcss-upgrade/src/codemods/migrate-border-compatibility.ts @@ -64,6 +64,19 @@ export function migrateBorderCompatibility({ } function migrate(root: Root) { + let isTailwindRoot = false + root.walkAtRules('import', (node) => { + if ( + /['"]tailwindcss['"]/.test(node.params) || + /['"]tailwindcss\/preflight['"]/.test(node.params) + ) { + isTailwindRoot = true + return false + } + }) + + if (!isTailwindRoot) return + let targetNode = null as AtRule | null root.walkAtRules((node) => { From 3a91299b996bb713702613a6bf4cfc7a2aa735c7 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Thu, 24 Oct 2024 12:39:46 +0200 Subject: [PATCH 3/5] add dedicated integration tests to ensure border compatibility is injected in the correct spot --- integrations/upgrade/js-config.test.ts | 174 +++++++++++++++++++++++++ 1 file changed, 174 insertions(+) diff --git a/integrations/upgrade/js-config.test.ts b/integrations/upgrade/js-config.test.ts index 9d2a6c5ee194..612202bac0f9 100644 --- a/integrations/upgrade/js-config.test.ts +++ b/integrations/upgrade/js-config.test.ts @@ -992,4 +992,178 @@ describe('border compatibility', () => { `) }, ) + + test( + 'migrate border compatibility in the file that uses the `@import "tailwindcss"` import', + { + fs: { + 'package.json': json` + { + "dependencies": { + "@tailwindcss/upgrade": "workspace:^" + } + } + `, + 'tailwind.config.ts': ts` + import { type Config } from 'tailwindcss' + + export default { + theme: {}, + } satisfies Config + `, + 'src/input.css': css`@import './tailwind.css';`, + 'src/tailwind.css': css` + @tailwind base; + @tailwind components; + @tailwind utilities; + `, + }, + }, + async ({ exec, fs }) => { + await exec('npx @tailwindcss/upgrade') + + expect(await fs.dumpFiles('src/**/*.css')).toMatchInlineSnapshot(` + " + --- src/input.css --- + @import './tailwind.css'; + + --- src/tailwind.css --- + @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; + } + } + " + `) + }, + ) + + test( + 'migrate border compatibility in the file that uses the `@import "tailwindcss/preflight"` import', + { + fs: { + 'package.json': json` + { + "dependencies": { + "@tailwindcss/upgrade": "workspace:^" + } + } + `, + 'tailwind.config.ts': ts` + import { type Config } from 'tailwindcss' + + export default { + theme: {}, + } satisfies Config + `, + 'src/input.css': css` + @import './base.css'; + @import './my-base.css'; + @import './utilities.css'; + `, + 'src/base.css': css`@tailwind base;`, + 'src/utilities.css': css` + @tailwind components; + @tailwind utilities; + `, + 'src/my-base.css': css` + @layer base { + html { + color: black; + } + } + `, + }, + }, + async ({ exec, fs }) => { + await exec('npx @tailwindcss/upgrade') + + expect(await fs.dumpFiles('src/**/*.css')).toMatchInlineSnapshot(` + " + --- src/base.css --- + @import 'tailwindcss/theme' layer(theme); + @import 'tailwindcss/preflight' layer(base); + + /* + 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; + } + } + + --- src/input.css --- + @import './base.css'; + @import './my-base.css'; + @import './utilities.css'; + + --- src/my-base.css --- + @layer base { + html { + color: black; + } + } + + --- src/utilities.css --- + @import 'tailwindcss/utilities' layer(utilities); + " + `) + }, + ) }) From 8754b6ce62678ac21a49bb8f7b0e4b508f40f5ea Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Thu, 24 Oct 2024 12:45:42 +0200 Subject: [PATCH 4/5] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 14897da09111..401c2dc6ced3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Ensure individual logical property utilities are sorted later than left/right pair utilities ([#14777](https://github.com/tailwindlabs/tailwindcss/pull/14777)) - _Upgrade (experimental)_: Ensure `@import` statements for relative CSS files are actually migrated to use relative path syntax ([#14769](https://github.com/tailwindlabs/tailwindcss/pull/14769)) +- _Upgrade (experimental)_: Improve injection of the border compatibility CSS ([#14773](https://github.com/tailwindlabs/tailwindcss/pull/14773)) ## [4.0.0-alpha.29] - 2024-10-23 From ac358ff742eea46238c813b29f23dce98f30e00d Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Thu, 24 Oct 2024 19:02:33 +0200 Subject: [PATCH 5/5] Update CHANGELOG.md Co-authored-by: Adam Wathan --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 401c2dc6ced3..fbc512633aa2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Ensure individual logical property utilities are sorted later than left/right pair utilities ([#14777](https://github.com/tailwindlabs/tailwindcss/pull/14777)) - _Upgrade (experimental)_: Ensure `@import` statements for relative CSS files are actually migrated to use relative path syntax ([#14769](https://github.com/tailwindlabs/tailwindcss/pull/14769)) -- _Upgrade (experimental)_: Improve injection of the border compatibility CSS ([#14773](https://github.com/tailwindlabs/tailwindcss/pull/14773)) +- _Upgrade (experimental)_: Only generate Preflight compatibility styles when Preflight is used ([#14773](https://github.com/tailwindlabs/tailwindcss/pull/14773)) ## [4.0.0-alpha.29] - 2024-10-23