mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
This PR fixes 2 issues with the migration tool where certain classes
weren't migrated. This PR fixes those 2 scenarios:
### Scenario 1
When you have an arbitrary opacity modifier that doesn't use `%`, but is
just a number typically between `0` and `1` then this was not converted
to the bare value equivalent before.
E.g.:
```html
<div class="bg-[#f00]/[0.16]"></dv>
```
Will now be converted to:
```html
<div class="bg-[#f00]/16"></dv>
```
### Scenario 2
Fixes a bug when a CSS function was used in a fallback value in the CSS
variable shorthand syntax. In that case we didn't migrate the class to
the new syntax.
This was because we assumed that a `(` was found, that we are dealing
with a CSS function.
E.g.:
```html
<div class="w-[--spacing(1)]"></div>
^ This indicates a CSS function, we should not be
converting this to `w-(--spacing(1))`
```
But if a function was used as a fallback value, for example:
```html
<div class="bg-[--my-color,theme(colors.red.500)]"></dv>
```
Then we also didn't migrate it, but since the function call is in the
fallback, we can still migrate it.
Will now properly be converted to:
```html
<div class="bg-(--my-color,var(--color-red-500))"></dv>
```
## Test plan
1. Added a test for the first case
2. Added a test for the second case
3. Also added an integration-like test that runs all the migration steps
to make sure that the `theme(…)` in the fallback also gets updated to
`var(…)`. This one caught an issue because the `var(…)` wasn't handling
prefixes correctly.
69 lines
3.3 KiB
TypeScript
69 lines
3.3 KiB
TypeScript
import { __unstable__loadDesignSystem } from '@tailwindcss/node'
|
|
import { expect, test } from 'vitest'
|
|
import { migrateAutomaticVarInjection } from './migrate-automatic-var-injection'
|
|
|
|
test.each([
|
|
// Arbitrary candidates
|
|
['[color:--my-color]', '[color:var(--my-color)]'],
|
|
['[--my-color:red]', '[--my-color:red]'],
|
|
['[--my-color:--my-other-color]', '[--my-color:var(--my-other-color)]'],
|
|
|
|
// Arbitrary values for functional candidates
|
|
['bg-[--my-color]', 'bg-(--my-color)'],
|
|
['bg-[color:--my-color]', 'bg-(color:--my-color)'],
|
|
['border-[length:--my-length]', 'border-(length:--my-length)'],
|
|
['border-[line-width:--my-width]', 'border-(line-width:--my-width)'],
|
|
|
|
// Can clean up the workaround for opting out of automatic var injection
|
|
['bg-[_--my-color]', 'bg-[--my-color]'],
|
|
['bg-[color:_--my-color]', 'bg-[color:--my-color]'],
|
|
['border-[length:_--my-length]', 'border-[length:--my-length]'],
|
|
['border-[line-width:_--my-width]', 'border-[line-width:--my-width]'],
|
|
|
|
// Modifiers
|
|
['[color:--my-color]/[--my-opacity]', '[color:var(--my-color)]/(--my-opacity)'],
|
|
['bg-red-500/[--my-opacity]', 'bg-red-500/(--my-opacity)'],
|
|
['bg-[--my-color]/[--my-opacity]', 'bg-(--my-color)/(--my-opacity)'],
|
|
['bg-[color:--my-color]/[--my-opacity]', 'bg-(color:--my-color)/(--my-opacity)'],
|
|
|
|
// Can clean up the workaround for opting out of automatic var injection
|
|
['[color:--my-color]/[_--my-opacity]', '[color:var(--my-color)]/[--my-opacity]'],
|
|
['bg-red-500/[_--my-opacity]', 'bg-red-500/[--my-opacity]'],
|
|
['bg-[--my-color]/[_--my-opacity]', 'bg-(--my-color)/[--my-opacity]'],
|
|
['bg-[color:--my-color]/[_--my-opacity]', 'bg-(color:--my-color)/[--my-opacity]'],
|
|
|
|
// Variants
|
|
['supports-[--test]:flex', 'supports-(--test):flex'],
|
|
['supports-[_--test]:flex', 'supports-[--test]:flex'],
|
|
|
|
// Custom CSS functions that look like variables should not be converted
|
|
['w-[--spacing(5)]', 'w-[--spacing(5)]'],
|
|
['bg-[--theme(--color-red-500)]', 'bg-[--theme(--color-red-500)]'],
|
|
|
|
// Fallback values should be included inside the `var(…)` function
|
|
['bg-[--my-color,red]', 'bg-(--my-color,red)'],
|
|
// Fallback values can contain CSS functions
|
|
['bg-[--my-color,theme(spacing.1)]', 'bg-(--my-color,theme(spacing.1))'],
|
|
|
|
// Some properties never had var() injection in v3.
|
|
['[scroll-timeline-name:--myTimeline]', '[scroll-timeline-name:--myTimeline]'],
|
|
['[timeline-scope:--myScope]', '[timeline-scope:--myScope]'],
|
|
['[view-timeline-name:--myTimeline]', '[view-timeline-name:--myTimeline]'],
|
|
['[font-palette:--myPalette]', '[font-palette:--myPalette]'],
|
|
['[anchor-name:--myAnchor]', '[anchor-name:--myAnchor]'],
|
|
['[anchor-scope:--myScope]', '[anchor-scope:--myScope]'],
|
|
['[position-anchor:--myAnchor]', '[position-anchor:--myAnchor]'],
|
|
['[position-try-options:--myAnchor]', '[position-try-options:--myAnchor]'],
|
|
['[scroll-timeline:--myTimeline]', '[scroll-timeline:--myTimeline]'],
|
|
['[animation-timeline:--myAnimation]', '[animation-timeline:--myAnimation]'],
|
|
['[view-timeline:--myTimeline]', '[view-timeline:--myTimeline]'],
|
|
['[position-try:--myAnchor]', '[position-try:--myAnchor]'],
|
|
])('%s => %s', async (candidate, result) => {
|
|
let designSystem = await __unstable__loadDesignSystem('@import "tailwindcss";', {
|
|
base: __dirname,
|
|
})
|
|
|
|
let migrated = migrateAutomaticVarInjection(designSystem, {}, candidate)
|
|
expect(migrated).toEqual(result)
|
|
})
|