Ensure math operators are surrounded by whitespace in arbitrary values#20011
Conversation
When we use `-foo-[…]`, where the contents of `…` happens to contain a binary expression, then we have to make sure that the operators there receive whitespace around them. We already handle this whitespace when we parse arbitrary values. However, we only do that when we're dealing with a math-like function such as `calc`. But when you just have `-inset-[(var(--a)+var(--b))]`, then we see `(var(--a)+var(--b))`, not `calc(var(--a)+var(--b))`. You could assume that that's the case, but then we have to deal with edge cases where it could later be used in a spot that is not math-like
Confidence Score: 5/5Safe to merge; the fix is narrow and well-tested, with no regressions introduced. The change is a single-line call-site fix backed by an existing, well-exercised utility (addWhitespaceAroundMathOperators). The regression test correctly captures the before/after CSS. The utility already handles edge cases (scientific notation, leading unary operators, consecutive whitespace), and the * -1 suffix in calc(${value} * -1) is handled safely because - preceded by * is recognized as a unary sign and no extra space is inserted. No files require special attention. Reviews (2): Last reviewed commit: "update changelog" | Re-trigger Greptile |
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughThe tests were updated to expect a new negative arbitrary-value case using CSS variables ( 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
This PR fixes an issue where some
calc(…)expressions become invalid after we canonicalize them to a different syntax.Let's say you start with:
left-[calc(-1*(var(--my-var1)+var(--my-var2)))], then the produced AST for this candidate looks like this:Notice that the
+in between the vars already contain spaces.And the generated CSS looks like this:
Again, the
+has spaces aroudn it.However, we canoncialize this syntax where we remove the
calc(-1 * <value>)and move the-in front:-left-[(var(--my-var1)+var(--my-var2))], which should behave the same, but it did not. The parsed value for this looks like:Notice that the
+does not contain spaces around it. That's because we add them when we parse arbitrary values and when we are in acalc(…)expression. But thecalc(<value> * -1)is added later, so at this point, no spaces are added yet.This also means that the generated CSS currently looks like:
Which is invalid.
To solve this, we will make sure to add the whitespace around operators when we re-insert the
calc(<value> * -1). With this fix, the CSS looks like this:Which is correct again.
There are a few other issues that need a bit more work, but are not required for this fix.
(and)parens? E.g.:calc((<value>) * -1)instead ofcalc(<value> * -1)since<value>can be an expression on its own. Thiscould lead to unwanted behavior, but this will be a follow up PR if it's
worth it.
This last question is a bit more scary, but it has to do with how we compare results. We create a signature where we normalize a bunch of values to make sure that we can compare them. As a silly example
calc(var(--a) + var(--b))andcalc(var(--b) + var(--a))will result in the same value, therefor should have the same signature and should be swappable.But what's happening is that the signature of
left-[calc(-1*(var(--my-var1)+var(--my-var2)))]and-left-[(var(--my-var1)+var(--my-var2))]result in:This gets rid of whitespace to store less data, but this is obviously wrong now, so we need to improve the signatures around this. That said, that will be a follow up PR as well because this requires much more testing.
But this PR at least fixes the #20010 issue because we will properly insert the whitespace around the math operators.
Fixes: #20010
Test plan