Try to canonicalize any arbitrary utility to a bare value (#19379)
This PR adds an improvement to our canonicalization logic when dealing with arbitrary values. When trying to canonicalize utilities, we make use of the intellisense suggestions list where we typically use multiples of the spacing scale. This means that a value like `gap-[128px]` gets properly canonicalized to `gap-32`. However, when you try a value that we typically don't suggest such as `gap-[116px]` then it doesn't get canonicalized at all. This PR fixes that by trying to use the spacing scale and convert `116px / 4px` and try the `gap-29` utility instead. This is done by canonicalizing the incoming arbitrary value and the spacing multipliers such that `--spacing: 0.25rem` and `--spacing: 4px` both work as expected. ### Test plan 1. Added some tests with a spacing scale of `0.25rem` (which is the default) 2. Added some tests with the same spacing scale in a different unit `4px` 3. Added some tests with a different spacing scale `1px` Also had to update 1 test that now gets canonicalized properly, e.g.: `w-[124px]` → `w-31`.
This commit is contained in:
parent
117433a100
commit
9e436f7751
3 changed files with 55 additions and 1 deletions
|
|
@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Preserve case of theme keys from JS configs and plugins ([#19337](https://github.com/tailwindlabs/tailwindcss/pull/19337))
|
||||
- Write source maps correctly on the CLI when using `--watch` ([#19373](https://github.com/tailwindlabs/tailwindcss/pull/19373))
|
||||
- Upgrade: Handle `future` and `experimental` config keys ([#19344](https://github.com/tailwindlabs/tailwindcss/pull/19344))
|
||||
- Try to canonicalize any arbitrary utility to a bare value ([#19379](https://github.com/tailwindlabs/tailwindcss/pull/19379))
|
||||
|
||||
### Added
|
||||
|
||||
|
|
|
|||
|
|
@ -530,8 +530,24 @@ describe.each([['default'], ['with-variant'], ['important'], ['prefix']])('%s',
|
|||
// Default spacing scale
|
||||
['w-[64rem]', 'w-256', '0.25rem'],
|
||||
|
||||
// Non-suggested numbers
|
||||
['gap-[7.25rem]', 'gap-29', '0.25rem'],
|
||||
['gap-[calc(7rem+0.25rem)]', 'gap-29', '0.25rem'],
|
||||
['gap-[116px]', 'gap-29', '0.25rem'],
|
||||
|
||||
// Non-suggested numbers, with the same spacing scale with different
|
||||
// units
|
||||
['gap-[7.25rem]', 'gap-29', '4px'],
|
||||
['gap-[calc(7rem+0.25rem)]', 'gap-29', '4px'],
|
||||
['gap-[116px]', 'gap-29', '4px'],
|
||||
|
||||
// Non-suggested numbers, with a different spacing scale
|
||||
['gap-[7.25rem]', 'gap-116', '1px'],
|
||||
['gap-[calc(7rem+0.25rem)]', 'gap-116', '1px'],
|
||||
['gap-[116px]', 'gap-116', '1px'],
|
||||
|
||||
// Keep arbitrary value if units are different
|
||||
['w-[124px]', 'w-[124px]', '0.25rem'],
|
||||
['w-[124px]', 'w-31', '0.25rem'],
|
||||
|
||||
// Keep arbitrary value if bare value doesn't fit in steps of .25
|
||||
['w-[0.123rem]', 'w-[0.123rem]', '0.25rem'],
|
||||
|
|
|
|||
|
|
@ -990,6 +990,43 @@ function arbitraryUtilities(candidate: Candidate, options: InternalCanonicalizeO
|
|||
candidate.kind === 'arbitrary' ? candidate.value : (candidate.value?.value ?? null)
|
||||
if (value === null) return
|
||||
|
||||
// Try to canonicalize any incoming arbitrary value. Canonicalization of
|
||||
// `rem` and `px` values will be converted to `px`, so we have to
|
||||
// canonicalize the spacing multiplier as well.
|
||||
if (
|
||||
options.signatureOptions.rem !== null &&
|
||||
candidate.kind === 'functional' &&
|
||||
candidate.value?.kind === 'arbitrary'
|
||||
) {
|
||||
let spacingMultiplier = designSystem.resolveThemeValue('--spacing')
|
||||
if (spacingMultiplier !== undefined) {
|
||||
// Canonicalizing the spacing multiplier allows us to handle both
|
||||
// `--spacing: 0.25rem` and `--spacing: 4px` values correctly.
|
||||
let canonicalizedSpacingMultiplier = constantFoldDeclaration(
|
||||
spacingMultiplier,
|
||||
options.signatureOptions.rem,
|
||||
)
|
||||
if (canonicalizedSpacingMultiplier !== null) {
|
||||
let canonicalizedValue = constantFoldDeclaration(value, options.signatureOptions.rem)
|
||||
let valueDimension = dimensions.get(canonicalizedValue)
|
||||
let spacingMultiplierDimension = dimensions.get(canonicalizedSpacingMultiplier)
|
||||
if (
|
||||
valueDimension &&
|
||||
spacingMultiplierDimension &&
|
||||
valueDimension[1] === spacingMultiplierDimension[1] && // Ensure the units match
|
||||
spacingMultiplierDimension[0] !== 0
|
||||
) {
|
||||
let bareValue = `${valueDimension[0] / spacingMultiplierDimension[0]}`
|
||||
if (isValidSpacingMultiplier(bareValue)) {
|
||||
yield Object.assign({}, candidate, {
|
||||
value: { kind: 'named', value: bareValue, fraction: null },
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let spacingMultiplier = designSystem.storage[SPACING_KEY]?.get(value) ?? null
|
||||
let rootPrefix = ''
|
||||
if (spacingMultiplier !== null && spacingMultiplier < 0) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue