-
-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Don't escape underscores for the first parameter of var()
#14776
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Don't escape underscores for the first parameter of var()
#14776
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. Join @philipp-spiess and the rest of your teammates on |
8879dbb to
951e6a6
Compare
| 'calc(var(--10-10px,calc(-20px-(-30px--40px)-50px)))', | ||
| 'calc(var(--10-10px,calc(-20px - (-30px - -40px) - 50px)))', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test case didn't have the proper number of closing quotes. I remember that @RobinMalfait once mentioned that we do validate this already at the parser level.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we only validate the parens in your CSS file (and throw), but we don't validate if it happens in a candidate.
Input:
<div class="[--foo:calc(var(--10-10px,calc(-20px-(-30px--40px)-50px)]"></div>Output:
.\[--foo\:calc\(var\(--10-10px\,calc\(-20px-\(-30px--40px\)-50px\)\] {
--foo: calc(var(--10-10px,calc(-20px - (-30px - -40px) - 50px);
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, lol!
With this change the closing parentheses would be automatically inserted actually (because we can't encode the absence of them in the ValueParser—That's how I found out about this example in the first place! But I think it would be better if we throw away candidates like this 🤔
| if (input.indexOf('(') === -1) { | ||
| return convertUnderscoresToWhitespace(input) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check was moved up from being inside the addWhitespaceAroundMathOperators, since neither the url() nor the var() handling need to run if the arbitrary value has no parenthesis.
951e6a6 to
1b1d7b9
Compare
6460bcb to
21eb011
Compare
Co-authored-by: Adam Wathan <[email protected]>
21eb011 to
75aa966
Compare
Quick follow-up to #14776 to treat the `theme()` function the same way.
This PR fixes an issue where currently a `theme()` function call inside an arbitrary value that used a dot in the key path: ```jsx let className = "ml-[theme(spacing[1.5])]" ``` Was causing issues when going though the codemod. The issue is that for candidates, we require `_` to be _escaped_, since otherwise they will be replaced with underscore. When going through the codemods, the above candidate would be translated to the following CSS variable access: ```js let className = "ml-[var(--spacing-1\_5))" ``` Because the underscore was escaped, we now have an invalid string inside a JavaScript file (as the `\` would escape inside the quoted string. To resolve this, we decided that this common case (as its used by the Tailwind CSS default theme) should work without escaping. In #14776, we made the changes that CSS variables used via `var()` no longer unescape underscores. This PR extends that so that the Variant printer (that creates the serialized candidate representation after the codemods make changes) take this new encoding into account. This will result in the above example being translated into: ```js let className = "ml-[var(--spacing-1_5))" ``` With no more escaping. Nice! ## Test Plan I have added test for this to the kitchen-sink upgrade tests. Furthermore, to ensure this really works full-stack, I have updated the kitchen-sink test to _actually build the migrated project with Tailwind CSS v4_. After doing so, we can assert that we indeed have the right class name in the generated CSS. --------- Co-authored-by: Adam Wathan <[email protected]>
Resolves #16170 This PR fixes an issue where the previously opted-out escaping of the first argument for the `var(…)` function was not unescaped at all. This was introduced in #14776 where the intention was to not require escaping of underscores in the var function (e.g. `ml-[var(--spacing-1_5)]`). However, I do think it still makes sense to unescape an eventually escaped underline for consistency. ## Test plan The example from #1670 now parses as expected: <img width="904" alt="Screenshot 2025-02-03 at 13 51 35" src="https://github.com/user-attachments/assets/cac0f06e-37da-4dcb-a554-9606d144a8d5" /> --------- Co-authored-by: Robin Malfait <[email protected]>

This PR updates our arbitrary value decoder to:
No longer require an escaping for underscores in the first parameter of
var(). Example:Ensures that properties before an eventual
url()are properly unescaped. Example:I will ensure that this properly works for the migrate use case in a follow-up PR in the stack.
Test Plan
Added unit tests as well as tests for the variant decoder. Additionally this PR also adds a higher-level test using the public Tailwind APIs to ensure this is properly propagated.