From 8a0972612f07cc6982186560dc4a5a7fccf2d2b0 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Thu, 10 Oct 2024 22:37:18 +0200 Subject: [PATCH] add migration for simple legacy classes --- .../codemods/simple-legacy-classes.test.ts | 22 +++++++++++ .../codemods/simple-legacy-classes.ts | 39 +++++++++++++++++++ .../src/template/migrate.ts | 2 + 3 files changed, 63 insertions(+) create mode 100644 packages/@tailwindcss-upgrade/src/template/codemods/simple-legacy-classes.test.ts create mode 100644 packages/@tailwindcss-upgrade/src/template/codemods/simple-legacy-classes.ts diff --git a/packages/@tailwindcss-upgrade/src/template/codemods/simple-legacy-classes.test.ts b/packages/@tailwindcss-upgrade/src/template/codemods/simple-legacy-classes.test.ts new file mode 100644 index 000000000000..d0a89da58b32 --- /dev/null +++ b/packages/@tailwindcss-upgrade/src/template/codemods/simple-legacy-classes.test.ts @@ -0,0 +1,22 @@ +import { __unstable__loadDesignSystem } from '@tailwindcss/node' +import { expect, test } from 'vitest' +import { simpleLegacyClasses } from './simple-legacy-classes' + +test.each([ + ['overflow-clip', 'text-clip'], + ['overflow-ellipsis', 'text-ellipsis'], + ['flex-grow-0', 'grow-0'], + ['flex-shrink-0', 'shrink-0'], + ['decoration-clone', 'box-decoration-clone'], + ['decoration-slice', 'box-decoration-slice'], + + ['max-lg:hover:decoration-slice', 'max-lg:hover:box-decoration-slice'], + ['max-lg:hover:decoration-slice!', 'max-lg:hover:box-decoration-slice!'], + ['max-lg:hover:!decoration-slice', 'max-lg:hover:box-decoration-slice!'], +])('%s => %s', async (candidate, result) => { + let designSystem = await __unstable__loadDesignSystem('@import "tailwindcss";', { + base: __dirname, + }) + + expect(simpleLegacyClasses(designSystem, {}, candidate)).toEqual(result) +}) diff --git a/packages/@tailwindcss-upgrade/src/template/codemods/simple-legacy-classes.ts b/packages/@tailwindcss-upgrade/src/template/codemods/simple-legacy-classes.ts new file mode 100644 index 000000000000..1131ee57aa3d --- /dev/null +++ b/packages/@tailwindcss-upgrade/src/template/codemods/simple-legacy-classes.ts @@ -0,0 +1,39 @@ +import type { Config } from 'tailwindcss' +import type { DesignSystem } from '../../../../tailwindcss/src/design-system' +import { segment } from '../../../../tailwindcss/src/utils/segment' + +// Classes that used to exist in Tailwind CSS v3, but do not exist in Tailwind +// CSS v4 anymore. +const LEGACY_CLASS_MAP = { + 'overflow-clip': 'text-clip', + 'overflow-ellipsis': 'text-ellipsis', + 'flex-grow-0': 'grow-0', + 'flex-shrink-0': 'shrink-0', + 'decoration-clone': 'box-decoration-clone', + 'decoration-slice': 'box-decoration-slice', +} + +export function simpleLegacyClasses( + _designSystem: DesignSystem, + _userConfig: Config, + rawCandidate: string, +): string { + let variants = segment(rawCandidate, ':') + let utility = variants.pop()! + + let important = false + if (utility[0] === '!') { + important = true + utility = utility.slice(1) + } else if (utility[utility?.length - 1] === '!') { + important = true + utility = utility.slice(0, -1) + } + + if (utility in LEGACY_CLASS_MAP) { + let replacement = LEGACY_CLASS_MAP[utility as keyof typeof LEGACY_CLASS_MAP] + return `${variants.concat(replacement).join(':')}${important ? '!' : ''}` + } + + return rawCandidate +} diff --git a/packages/@tailwindcss-upgrade/src/template/migrate.ts b/packages/@tailwindcss-upgrade/src/template/migrate.ts index 5fd710d4fdaa..df9d22b15af8 100644 --- a/packages/@tailwindcss-upgrade/src/template/migrate.ts +++ b/packages/@tailwindcss-upgrade/src/template/migrate.ts @@ -7,6 +7,7 @@ import { automaticVarInjection } from './codemods/automatic-var-injection' import { bgGradient } from './codemods/bg-gradient' import { important } from './codemods/important' import { prefix } from './codemods/prefix' +import { simpleLegacyClasses } from './codemods/simple-legacy-classes' import { variantOrder } from './codemods/variant-order' export type Migration = ( @@ -20,6 +21,7 @@ export const DEFAULT_MIGRATIONS: Migration[] = [ important, automaticVarInjection, bgGradient, + simpleLegacyClasses, variantOrder, ]