Improve upgrade tool to pretty print --spacing(2) (#15596)
This PR improves the upgrade tool to make sure that newly upgraded `--spacing(2)` CSS functions is pretty printed to prevent unambiguous looking classes (even though it compiles correctly). If you have a class such as `m-[calc(100dvh-theme(spacing.2))]`, then we used to convert it to `m-[calc(100dvh-calc(var(--spacing)*2))]`. But recently we introduced the `--spacing(2)` CSS function which means that the output now looks like this instead: `m-[calc(100dvh---spacing(2))]`. The triple `-` is valid because the first `-` is the minus sign, the next two `-` characters are from the function. One solution is to introduce spaces via underscores: ``` m-[calc(100dvh_-_--spacing(2))] ``` But a simpler solution, is to wrap the `--spacing(2)` in parens to remove the underscores and improve the readability of the `---` characters. ``` m-[calc(100dvh-(--spacing(2)))] ```
This commit is contained in:
parent
27f8bab7ab
commit
b4a20af4d0
4 changed files with 43 additions and 2 deletions
|
|
@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
### Fixed
|
||||
|
||||
- Add missing `main` and `browser` fields for `@tailwindcss/browser` ([#15594](https://github.com/tailwindlabs/tailwindcss/pull/15594))
|
||||
- _Upgrade (experimental)_: Pretty print `--spacing(…)` to prevent ambiguity ([#15596](https://github.com/tailwindlabs/tailwindcss/pull/15596))
|
||||
|
||||
## [4.0.0-beta.9] - 2025-01-09
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,13 @@ test.each([
|
|||
['bg-[theme(colors.red.500)]', 'bg-(--color-red-500)'], // Arbitrary value
|
||||
['bg-[size:theme(spacing.4)]', 'bg-[size:--spacing(4)]'], // Arbitrary value + data type hint
|
||||
|
||||
// Pretty print CSS functions preceded by an operator to prevent consecutive
|
||||
// operator characters.
|
||||
['w-[calc(100dvh-theme(spacing.2))]', 'w-[calc(100dvh-(--spacing(2)))]'],
|
||||
['w-[calc(100dvh+theme(spacing.2))]', 'w-[calc(100dvh+(--spacing(2)))]'],
|
||||
['w-[calc(100dvh/theme(spacing.2))]', 'w-[calc(100dvh/(--spacing(2)))]'],
|
||||
['w-[calc(100dvh*theme(spacing.2))]', 'w-[calc(100dvh*(--spacing(2)))]'],
|
||||
|
||||
// Convert to `var(…)` if we can resolve the path, but keep fallback values
|
||||
['bg-[theme(colors.red.500,red)]', 'bg-(--color-red-500,red)'],
|
||||
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ function substituteFunctionsInValue(
|
|||
ast: ValueParser.ValueAstNode[],
|
||||
handle: (value: string, fallback?: string) => string | null,
|
||||
) {
|
||||
ValueParser.walk(ast, (node, { replaceWith }) => {
|
||||
ValueParser.walk(ast, (node, { parent, replaceWith }) => {
|
||||
if (node.kind === 'function' && node.value === 'theme') {
|
||||
if (node.nodes.length < 1) return
|
||||
|
||||
|
|
@ -275,6 +275,37 @@ function substituteFunctionsInValue(
|
|||
fallbackValues.length > 0 ? handle(path, ValueParser.toCss(fallbackValues)) : handle(path)
|
||||
if (replacement === null) return
|
||||
|
||||
if (parent) {
|
||||
let idx = parent.nodes.indexOf(node) - 1
|
||||
while (idx !== -1) {
|
||||
let previous = parent.nodes[idx]
|
||||
// Skip the space separator
|
||||
if (previous.kind === 'separator' && previous.value.trim() === '') {
|
||||
idx -= 1
|
||||
continue
|
||||
}
|
||||
|
||||
// If the previous node is a word and contains an operator, we need to
|
||||
// wrap the replacement in parentheses to make the output less
|
||||
// ambiguous.
|
||||
//
|
||||
// Input:
|
||||
// - `calc(100dvh-theme(spacing.2))`
|
||||
//
|
||||
// Output:
|
||||
// - `calc(100dvh-(--spacing(2)))`
|
||||
//
|
||||
// Not:
|
||||
// -`calc(100dvh---spacing(2))`
|
||||
//
|
||||
if (/^[-+*/]$/.test(previous.value.trim())) {
|
||||
replacement = `(${replacement})`
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
replaceWith(ValueParser.parse(replacement))
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -177,7 +177,9 @@ describe('--theme(…)', () => {
|
|||
color: --theme(colors.red.500);
|
||||
}
|
||||
`),
|
||||
).rejects.toThrowErrorMatchingInlineSnapshot(`[Error: The --theme(…) function can only be used with CSS variables from your theme.]`)
|
||||
).rejects.toThrowErrorMatchingInlineSnapshot(
|
||||
`[Error: The --theme(…) function can only be used with CSS variables from your theme.]`,
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue