From f8ee567c377058721a582e38292b00a78a39176d Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Mon, 26 May 2025 14:25:13 +0200 Subject: [PATCH 1/3] add failing test --- .../src/codemods/template/migrate.test.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/@tailwindcss-upgrade/src/codemods/template/migrate.test.ts b/packages/@tailwindcss-upgrade/src/codemods/template/migrate.test.ts index 5c91f3d07e7b..216be87e35a7 100644 --- a/packages/@tailwindcss-upgrade/src/codemods/template/migrate.test.ts +++ b/packages/@tailwindcss-upgrade/src/codemods/template/migrate.test.ts @@ -53,6 +53,17 @@ describe.each([['default'], ['with-variant'], ['important'], ['prefix']])('%s', // Migrate deprecated named values to bare values ['order-none', 'order-0'], + + // `-0` should not be migrated to `0`. + // + // This used to be a bug that translate `mt-[0px]` into `-mt-[0px]` because + // `-mt-[0px]` translates to `margin-top: calc(0px * -1);` and therefore we + // handle the `0px * -1` case which translates to `0px` not `-0px`. + // + // This translation is actually fine, because now, we will prefer the + // non-negative version first so we can replace `-mt-[0px]` with `mt-[0px]`. + ['mt-[0px]', 'mt-[0px]'], + ['-mt-[0px]', 'mt-[0px]'], ])(testName, async (candidate, result) => { if (strategy === 'with-variant') { candidate = `focus:${candidate}` From 0c973247157b8967f78ed62dad77c7e1bfe2bd14 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Mon, 26 May 2025 14:25:21 +0200 Subject: [PATCH 2/3] prefer non-negative version of negative version --- .../src/codemods/template/migrate-arbitrary-utilities.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/@tailwindcss-upgrade/src/codemods/template/migrate-arbitrary-utilities.ts b/packages/@tailwindcss-upgrade/src/codemods/template/migrate-arbitrary-utilities.ts index c03100cdd8c8..63aa9396d875 100644 --- a/packages/@tailwindcss-upgrade/src/codemods/template/migrate-arbitrary-utilities.ts +++ b/packages/@tailwindcss-upgrade/src/codemods/template/migrate-arbitrary-utilities.ts @@ -161,7 +161,12 @@ export function migrateArbitraryUtilities( let spacingMultiplier = spacing.get(designSystem)?.get(value) - for (let root of designSystem.utilities.keys('functional')) { + for (let root of Array.from(designSystem.utilities.keys('functional')).sort( + // Sort negative roots after positive roots so that we can try + // `mt-*` before `-mt-*`. This is especially useful in situations where + // `-mt-[0px]` can be translated to `mt-[0px]`. + (a, z) => Number(a[0] === '-') - Number(z[0] === '-'), + )) { // Try as bare value for (let replacementCandidate of parseCandidate(designSystem, `${root}-${value}`)) { yield replacementCandidate From 8a6a8bea1a37143b65648d6c5d5f6c33608f3d8c Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Mon, 26 May 2025 14:38:26 +0200 Subject: [PATCH 3/3] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc106a20e950..dc14695211ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Upgrade: Migrate deprecated `order-none` to `order-0` ([#18126](https://github.com/tailwindlabs/tailwindcss/pull/18126)) - Support Leptos `class:` attributes when extracting classes ([#18093](https://github.com/tailwindlabs/tailwindcss/pull/18093)) - Fix "Cannot read properties of undefined" crash on malformed arbitrary value ([#18133](https://github.com/tailwindlabs/tailwindcss/pull/18133)) +- Upgrade: Migrate `-mt-[0px]` to `mt-[0px]` instead of the other way around ([#18154](https://github.com/tailwindlabs/tailwindcss/pull/18154)) ## [4.1.7] - 2025-05-15