fix(color): correct grad hue parsing and reject non-percentage color-mix weights#120
Open
rmyndharis wants to merge 1 commit into
Open
Conversation
…mix weights
parseHue tested `endsWith('rad')` before `endsWith('grad')`, so a gradian
angle matched the radians branch first: `100grad` resolved to ~329.58deg
instead of 90deg, silently producing the wrong color, luminance, contrast
result, and exports. Test `grad` before `rad`; deg/rad/turn/unitless
behavior is unchanged.
parseColorWithWeight treated any bare number as a weight and multiplied it
by 100, so `color-mix(in srgb, red 20, blue)` produced a wildly wrong blend
instead of being rejected. CSS color-mix weights are percentages only;
require a `%` suffix and otherwise return null (invalid color).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two CSS color-parsing correctness fixes in
model/color-parser.ts.gradhue angles were parsed as radiansparseHuecheckedendsWith('rad')beforeendsWith('grad'). Since"100grad"ends with"rad", it matched the radians branch first —parseFloat("100g") * 180/π % 360 ≈ 329.58°instead of100grad = 90°. The token was accepted with no error, so the wrong hue silently propagated to the resolved hex, WCAG luminance/contrast result, and the Tailwind/DTCG exports. Affects every hue notation:hsl,hwb,lch,oklch.Fix: test
gradbeforerad(longest-suffix-first).deg/rad/turn/unitless behavior is byte-identical.color-mixaccepted and over-scaled bare-number weightsparseColorWithWeighttreated any numeric token as a weight and multiplied bare numbers by 100.color-mix(in srgb, red 20, blue)became weight2000, producing a wildly wrong (red-dominated) blend instead of being rejected. CSScolor-mixweights are percentages only.Fix: require a
%suffix; a bare number is no longer a weight, so such input returnsnull(invalid color) — matching CSS.Testing
bun test: 284 pass, 1 skip, 0 fail (added 2 tests:100grad === 90deg, and bare-number color-mix weight rejection)bun run lint(tsc --noEmit): clean%-weight color-mix andhsl/hwb/lch/oklchtests unchanged and passing