From 396ce7dc1186f7274e9e4f293dbcb212b477c5b4 Mon Sep 17 00:00:00 2001 From: govizlora Date: Mon, 29 Sep 2025 15:25:18 -0700 Subject: [PATCH 1/3] Fix react classnames not being migrated --- .../codemods/template/is-safe-migration.test.ts | 17 +++++++++++++++++ .../src/codemods/template/is-safe-migration.ts | 12 +++++------- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/packages/@tailwindcss-upgrade/src/codemods/template/is-safe-migration.test.ts b/packages/@tailwindcss-upgrade/src/codemods/template/is-safe-migration.test.ts index 8bcaf52f427a..405e37f841d3 100644 --- a/packages/@tailwindcss-upgrade/src/codemods/template/is-safe-migration.test.ts +++ b/packages/@tailwindcss-upgrade/src/codemods/template/is-safe-migration.test.ts @@ -112,4 +112,21 @@ describe('is-safe-migration', async () => { }), ).toEqual(candidate) }) + + test.each([ + // Vue classes + [`
`, 'shadow', 'shadow-sm'], + [`
`, 'shadow', 'shadow-sm'], + + // React classes + [`
`, 'shadow', 'shadow-sm'], + ])('replaces classes in valid positions #%#', async (example, candidate, expected) => { + expect( + await migrateCandidate(designSystem, {}, candidate, { + contents: example, + start: example.indexOf(candidate), + end: example.indexOf(candidate) + candidate.length, + }), + ).toEqual(expected) + }) }) diff --git a/packages/@tailwindcss-upgrade/src/codemods/template/is-safe-migration.ts b/packages/@tailwindcss-upgrade/src/codemods/template/is-safe-migration.ts index 7851db65002e..39e4769828d4 100644 --- a/packages/@tailwindcss-upgrade/src/codemods/template/is-safe-migration.ts +++ b/packages/@tailwindcss-upgrade/src/codemods/template/is-safe-migration.ts @@ -5,18 +5,16 @@ import * as version from '../../utils/version' const LOGICAL_OPERATORS = ['&&', '||', '?', '===', '==', '!=', '!==', '>', '>=', '<', '<='] const CONDITIONAL_TEMPLATE_SYNTAX = [ - // Vue - /v-else-if=['"]$/, - /v-if=['"]$/, - /v-show=['"]$/, - /(? Date: Tue, 30 Sep 2025 10:59:32 -0400 Subject: [PATCH 2/3] Allow ignore case on `class` and `className` This lets things like `enterClass` and `enterClassName` work which are common React-isms --- .../src/codemods/template/is-safe-migration.test.ts | 6 ++++++ .../src/codemods/template/is-safe-migration.ts | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/@tailwindcss-upgrade/src/codemods/template/is-safe-migration.test.ts b/packages/@tailwindcss-upgrade/src/codemods/template/is-safe-migration.test.ts index 405e37f841d3..2061f27d4ad2 100644 --- a/packages/@tailwindcss-upgrade/src/codemods/template/is-safe-migration.test.ts +++ b/packages/@tailwindcss-upgrade/src/codemods/template/is-safe-migration.test.ts @@ -117,9 +117,15 @@ describe('is-safe-migration', async () => { // Vue classes [`
`, 'shadow', 'shadow-sm'], [`
`, 'shadow', 'shadow-sm'], + [`
`, 'shadow', 'shadow-sm'], + [`
`, 'shadow', 'shadow-sm'], // React classes [`
`, 'shadow', 'shadow-sm'], + [`
`, 'shadow', 'shadow-sm'], + + // Preact-style + [`
`, 'shadow', 'shadow-sm'], ])('replaces classes in valid positions #%#', async (example, candidate, expected) => { expect( await migrateCandidate(designSystem, {}, candidate, { diff --git a/packages/@tailwindcss-upgrade/src/codemods/template/is-safe-migration.ts b/packages/@tailwindcss-upgrade/src/codemods/template/is-safe-migration.ts index 39e4769828d4..fa7ee7f4a1c5 100644 --- a/packages/@tailwindcss-upgrade/src/codemods/template/is-safe-migration.ts +++ b/packages/@tailwindcss-upgrade/src/codemods/template/is-safe-migration.ts @@ -9,7 +9,7 @@ const CONDITIONAL_TEMPLATE_SYNTAX = [ // including Vue conditions like `v-if="something && shadow"` // and Alpine conditions like `x-if="shadow"`, // but allow Vue and React classes - /(? Date: Tue, 30 Sep 2025 11:02:51 -0400 Subject: [PATCH 3/3] Update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2740ac27b481..4243ca1ec616 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Ensure files with only `@theme` produce no output when built ([#18979](https://github.com/tailwindlabs/tailwindcss/pull/18979)) - Support Maud templates when extracting classes ([#18988](https://github.com/tailwindlabs/tailwindcss/pull/18988)) - Show version mismatch (if any) when running upgrade tool ([#19028](https://github.com/tailwindlabs/tailwindcss/pull/19028)) +- Upgrade: Ensure first class inside className in React is migrated ([#19031](https://github.com/tailwindlabs/tailwindcss/pull/19031)) +- Upgrade: Migrate classes inside `*ClassName` and `*Class` attributes ([#19031](https://github.com/tailwindlabs/tailwindcss/pull/19031)) ## [4.1.13] - 2025-09-03