Robin Malfait 498f9ff003
Migrate bare values to named values (#18000)
This PR improves the upgrade tool by also migrating bare values to named
values defined in the `@theme`.

Recently we shipped some updates dat allowed us to migrate arbitrary
values (with square brackets), but we didn't migrate bare values yet.

That means that in this example:
```html
<div class="aspect-[16/9]"></div>
<div class="aspect-16/9"></div>
```

We migrated this to:
```html
<div class="aspect-video"></div>
<div class="aspect-16/9"></div>
```

With this change, we will also try and migrate the bare value to a named
value. So this example:
```html
<div class="aspect-[16/9]"></div>
<div class="aspect-16/9"></div>
```

Now becomes:
```html
<div class="aspect-video"></div>
<div class="aspect-video"></div>
```

## Test plan

1. Added unit tests for the new functionality.
2. Ran this on a local project


Before:
<img width="432" alt="image"
src="https://github.com/user-attachments/assets/ce1adfbd-7be1-4062-bea5-66368f748e44"
/>

After:
<img width="382" alt="image"
src="https://github.com/user-attachments/assets/a385c94c-4e4c-4e1c-ac73-680c56ac4081"
/>
2025-05-13 17:35:11 +02:00

46 lines
1.7 KiB
TypeScript

import type { Config } from '../../../../tailwindcss/src/compat/plugin-api'
import type { DesignSystem } from '../../../../tailwindcss/src/design-system'
import { replaceObject } from '../../utils/replace-object'
import type { Writable } from '../../utils/types'
import { walkVariants } from '../../utils/walk-variants'
import { computeVariantSignature, preComputedVariants } from './signatures'
export function migrateArbitraryVariants(
designSystem: DesignSystem,
_userConfig: Config | null,
rawCandidate: string,
): string {
let signatures = computeVariantSignature.get(designSystem)
let variants = preComputedVariants.get(designSystem)
for (let readonlyCandidate of designSystem.parseCandidate(rawCandidate)) {
// We are only interested in the variants
if (readonlyCandidate.variants.length <= 0) return rawCandidate
// The below logic makes use of mutation. Since candidates in the
// DesignSystem are cached, we can't mutate them directly.
let candidate = structuredClone(readonlyCandidate) as Writable<typeof readonlyCandidate>
for (let [variant] of walkVariants(candidate)) {
if (variant.kind === 'compound') continue
let targetString = designSystem.printVariant(variant)
let targetSignature = signatures.get(targetString)
if (typeof targetSignature !== 'string') continue
let foundVariants = variants.get(targetSignature)
if (foundVariants.length !== 1) continue
let foundVariant = foundVariants[0]
let parsedVariant = designSystem.parseVariant(foundVariant)
if (parsedVariant === null) continue
replaceObject(variant, parsedVariant)
}
return designSystem.printCandidate(candidate)
}
return rawCandidate
}