Skip to content

fix(color): correct grad hue parsing and reject non-percentage color-mix weights#120

Open
rmyndharis wants to merge 1 commit into
google-labs-code:mainfrom
rmyndharis:fix/color-parsing-grad-and-colormix
Open

fix(color): correct grad hue parsing and reject non-percentage color-mix weights#120
rmyndharis wants to merge 1 commit into
google-labs-code:mainfrom
rmyndharis:fix/color-parsing-grad-and-colormix

Conversation

@rmyndharis

Copy link
Copy Markdown

Summary

Two CSS color-parsing correctness fixes in model/color-parser.ts.

grad hue angles were parsed as radians

parseHue checked endsWith('rad') before endsWith('grad'). Since "100grad" ends with "rad", it matched the radians branch first — parseFloat("100g") * 180/π % 360 ≈ 329.58° instead of 100grad = 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 grad before rad (longest-suffix-first). deg/rad/turn/unitless behavior is byte-identical.

color-mix accepted and over-scaled bare-number weights

parseColorWithWeight treated any numeric token as a weight and multiplied bare numbers by 100. color-mix(in srgb, red 20, blue) became weight 2000, producing a wildly wrong (red-dominated) blend instead of being rejected. CSS color-mix weights are percentages only.

Fix: require a % suffix; a bare number is no longer a weight, so such input returns null (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
  • Existing %-weight color-mix and hsl/hwb/lch/oklch tests unchanged and passing

…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).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant