Upgrade: Migrate spacing scale (#14905)
This PR adds migrations for the recent changes to the `--spacing` scale done in #12263. There are a few steps that we do to ensure we have the best upgrade experience: - If you are overwriting the `spacing` theme with custom values, we now check if the new values are multiplies of the default spacing scale. When they are, we can safely remove the overwrite. - If you are extending the `spacing` theme, we will unset the default `--spacing` scale and only use the values you provided. - Any `theme()` function calls are replaced with `calc(var(--spacing) * multiplier)` unless the values are extending the default scale. One caveat here is for `theme()` key which can not be replaced with `var()` (e.g. in `@media` attribute positions). These will not be able to be replaced with `calc()` either so the following needs to stay unmigrated: ```css @media (max-width: theme(spacing.96)) { .foo { color: red; } } ``` ## Test plan We are mainly testing two scenarios: The JS config _extends_ the `spacing` namespace and the JS config _overwrites_ the `spacing` namespace. For both cases we have added an integration test each to ensure this works as expected. The test contains a mixture of keys (some of it matching the default multiples, some don't, some have different scales, and some use non-numeric identifiers). In addition to asserting on the created CSS `@theme`, we also ensure that `theme()` calls are properly replaced. --------- Co-authored-by: Adam Wathan <adam.wathan@gmail.com> Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
This commit is contained in:
parent
28e46badf7
commit
95c4877200
7 changed files with 387 additions and 49 deletions
|
|
@ -2,7 +2,7 @@ import { atRoot, atRule, decl, styleRule, type AstNode } from './ast'
|
|||
import type { Candidate, CandidateModifier, NamedUtilityValue } from './candidate'
|
||||
import type { Theme, ThemeKey } from './theme'
|
||||
import { DefaultMap } from './utils/default-map'
|
||||
import { inferDataType, isPositiveInteger } from './utils/infer-data-type'
|
||||
import { inferDataType, isPositiveInteger, isValidSpacingMultiplier } from './utils/infer-data-type'
|
||||
import { replaceShadowColors } from './utils/replace-shadow-colors'
|
||||
import { segment } from './utils/segment'
|
||||
|
||||
|
|
@ -397,9 +397,7 @@ export function createUtilities(theme: Theme) {
|
|||
handleBareValue: ({ value }) => {
|
||||
let multiplier = theme.resolve(null, ['--spacing'])
|
||||
if (!multiplier) return null
|
||||
|
||||
let num = Number(value)
|
||||
if (num < 0 || num % 0.25 !== 0 || String(num) !== value) return null
|
||||
if (!isValidSpacingMultiplier(value)) return null
|
||||
|
||||
return `calc(${multiplier} * ${value})`
|
||||
},
|
||||
|
|
|
|||
|
|
@ -328,3 +328,11 @@ export function isPositiveInteger(value: any) {
|
|||
let num = Number(value)
|
||||
return Number.isInteger(num) && num >= 0 && String(num) === String(value)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the value is either a positive whole number or a multiple of 0.25.
|
||||
*/
|
||||
export function isValidSpacingMultiplier(value: any) {
|
||||
let num = Number(value)
|
||||
return num >= 0 && num % 0.25 === 0 && String(num) === String(value)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue