mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
This PR converts legacy commas in arbitrary values to spaces. In Tailwind CSS v3, we allowed commas in arbitrary values for `grid-cols-[…]`, `grid-rows-[…]`, and `object-[…]` for backwards compatibility. The underlying CSS value did use spaces instead of commas. This PR adds a code mod where convert the commas to spaces when we see them. Test plan: --- Running this on Catalyst it goes from this: <img width="393" alt="image" src="https://github.com/user-attachments/assets/03cbda73-41f9-4601-b77a-5b511226b876"> To the expected value of: <img width="376" alt="image" src="https://github.com/user-attachments/assets/dd9bbe01-5eb1-4340-937b-70c435e7e4f0"> --------- Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
101 lines
2.9 KiB
TypeScript
101 lines
2.9 KiB
TypeScript
import fs from 'node:fs/promises'
|
|
import path, { extname } from 'node:path'
|
|
import type { Config } from 'tailwindcss'
|
|
import type { DesignSystem } from '../../../tailwindcss/src/design-system'
|
|
import { extractRawCandidates } from './candidates'
|
|
import { arbitraryValueToBareValue } from './codemods/arbitrary-value-to-bare-value'
|
|
import { automaticVarInjection } from './codemods/automatic-var-injection'
|
|
import { bgGradient } from './codemods/bg-gradient'
|
|
import { important } from './codemods/important'
|
|
import { legacyArbitraryValues } from './codemods/legacy-arbitrary-values'
|
|
import { maxWidthScreen } from './codemods/max-width-screen'
|
|
import { modernizeArbitraryValues } from './codemods/modernize-arbitrary-values'
|
|
import { prefix } from './codemods/prefix'
|
|
import { simpleLegacyClasses } from './codemods/simple-legacy-classes'
|
|
import { themeToVar } from './codemods/theme-to-var'
|
|
import { variantOrder } from './codemods/variant-order'
|
|
import { spliceChangesIntoString, type StringChange } from './splice-changes-into-string'
|
|
|
|
export type Migration = (
|
|
designSystem: DesignSystem,
|
|
userConfig: Config,
|
|
rawCandidate: string,
|
|
location?: {
|
|
contents: string
|
|
start: number
|
|
end: number
|
|
},
|
|
) => string
|
|
|
|
export const DEFAULT_MIGRATIONS: Migration[] = [
|
|
prefix,
|
|
important,
|
|
bgGradient,
|
|
simpleLegacyClasses,
|
|
maxWidthScreen,
|
|
themeToVar,
|
|
variantOrder, // Has to happen before migrations that modify variants
|
|
automaticVarInjection,
|
|
legacyArbitraryValues,
|
|
arbitraryValueToBareValue,
|
|
modernizeArbitraryValues,
|
|
]
|
|
|
|
export function migrateCandidate(
|
|
designSystem: DesignSystem,
|
|
userConfig: Config,
|
|
rawCandidate: string,
|
|
// Location is only set when migrating a candidate from a source file
|
|
location?: {
|
|
contents: string
|
|
start: number
|
|
end: number
|
|
},
|
|
): string {
|
|
for (let migration of DEFAULT_MIGRATIONS) {
|
|
rawCandidate = migration(designSystem, userConfig, rawCandidate, location)
|
|
}
|
|
return rawCandidate
|
|
}
|
|
|
|
export default async function migrateContents(
|
|
designSystem: DesignSystem,
|
|
userConfig: Config,
|
|
contents: string,
|
|
extension: string,
|
|
): Promise<string> {
|
|
let candidates = await extractRawCandidates(contents, extension)
|
|
|
|
let changes: StringChange[] = []
|
|
|
|
for (let { rawCandidate, start, end } of candidates) {
|
|
let migratedCandidate = migrateCandidate(designSystem, userConfig, rawCandidate, {
|
|
contents,
|
|
start,
|
|
end,
|
|
})
|
|
|
|
if (migratedCandidate === rawCandidate) {
|
|
continue
|
|
}
|
|
|
|
changes.push({
|
|
start,
|
|
end,
|
|
replacement: migratedCandidate,
|
|
})
|
|
}
|
|
|
|
return spliceChangesIntoString(contents, changes)
|
|
}
|
|
|
|
export async function migrate(designSystem: DesignSystem, userConfig: Config, file: string) {
|
|
let fullPath = path.isAbsolute(file) ? file : path.resolve(process.cwd(), file)
|
|
let contents = await fs.readFile(fullPath, 'utf-8')
|
|
|
|
await fs.writeFile(
|
|
fullPath,
|
|
await migrateContents(designSystem, userConfig, contents, extname(file)),
|
|
)
|
|
}
|