Repository navigation
Don't collapse utilities into a utility with other theme variables - #20574
RobinMalfait merged 5 commits into
Conversation
`mt-card mb-card` collapses into `my-4` when `--spacing-card` and `--spacing` produce the same value by default. The result then uses `--spacing` instead of `--spacing-card`, which renders differently once one of the variables changes (e.g. in `.dark`).
No change in behavior. The next commit uses it to compute the theme variables of a utility, with the same AST as its signature.
Signatures inline theme variables, so `mt-card mb-card` and `my-4` both have `margin-top: 1rem; margin-bottom: 1rem` when `--spacing-card` is `1rem`. The collapse step then picked `my-4`, and dropped the reference to `--spacing-card`. Now the collapse step also compares the theme variables that are inlined in each declaration of the signature. A replacement has to use the same theme variables as the candidates it replaces. A declaration without theme variables can still become one with theme variables, so `[width:16px] [height:16px]` still becomes `size-4`. The theme variables are only computed for a replacement whose signature already matches, so the extra work is small.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
WalkthroughCandidate collapsing now checks theme-variable metadata in addition to compiled utility signatures. A shared compilation pipeline collects inlined theme variables for each declaration. Regression tests cover matching variables, differing variables, and mixtures of theme-backed and bare values. The changelog adds a fix entry describing the behavior. Priority: ➖ Normal Merge Risk: ⚪ Minimal · up to
|
[Medium impact] The PR appears safe to merge. Reviews (1) · Last reviewed commit: "Update changelog" · Reviewed by Greptile |
This PR fixes an issue where
canonicalizeCandidates(…, { collapse: true })replaces a group of utilities with a utility that uses a different theme variable. The two variables only have the same value by default.Given this theme:
mt-card mb-cardmy-4my-cardw-card h-cardsize-4size-cardmt-card mb-othermy-4mt-card mb-otherw-card h-othersize-4w-card h-othermt-card mb-4my-4mt-card mb-4p-card px-otherp-cardp-card px-otherThe results on the left render differently once one of the variables changes, e.g. in
.dark, in a media query, or in a class.The cause
Signatures inline theme variables to their default value. This is correct for single candidates (e.g.
text-[var(--color-red-500)]→text-red-500). Butvar(--spacing-card)andcalc(var(--spacing) * 4)then both become1rem, so the collapse step can't see which variable a utility uses.The fix
A new cache compiles a utility the same way as its signature, and records the theme variables that are inlined in each declaration. The collapse step only uses this after the signature of a replacement already matches. Then each declaration of the replacement must use the same theme variables as the candidates it replaces.
A declaration without theme variables can still become one with theme variables. This is the same as for single candidates (
mt-[16px]→mt-4), and it keeps existing results like:[width:16px] [height:16px]→size-4[font-size:14px] [line-height:1.625]→text-sm/relaxedmt-[1px] mb-[1px]→my-pxtext-sm leading-5→text-sm/5No existing test expectation changes.
Performance
The theme variables are only computed for a replacement whose signature already matches, and they are cached. With 10 class lists and the full default theme, the extra compiles take about 0.35ms of about 28ms on the first call (about 1%). Repeated calls do no extra work.
Test plan
packages/tailwindcsspass