Skip to content

feat(linter): add opt-in color-blind contrast lint rule#133

Open
mvanhorn wants to merge 1 commit into
google-labs-code:mainfrom
mvanhorn:feat/48-color-blind-contrast-lint
Open

feat(linter): add opt-in color-blind contrast lint rule#133
mvanhorn wants to merge 1 commit into
google-labs-code:mainfrom
mvanhorn:feat/48-color-blind-contrast-lint

Conversation

@mvanhorn

Copy link
Copy Markdown
Contributor

Summary

design.md lint checks component backgroundColor/textColor pairs against WCAG AA as perceived by full-color vision. This adds an opt-in color-blind-contrast rule, enabled with a new --cvd flag, that re-runs the contrast check under simulated protanopia, deuteranopia, and tritanopia and warns when a simulated pair drops below 3:1. It is off by default, so existing lint output is unchanged.

Why this matters

A pair that clears AA for full-color vision can still collapse for the roughly 5-10% of users with congenital color-vision deficiency, because the only cue is a hue shift those users do not see. The worked example from #48: brand orange #E44001 on white is 4.17:1, an AA near-miss the baseline rule already reports, but 2.92:1 under protanopia and 2.31:1 under deuteranopia. The opt-in rule surfaces exactly those two failures the default check never sees.

Demo

Simulated Demo (HyperFrames):

color-blind-contrast demo

Changes

  • The color-blind-contrast rule mirrors the existing contrast-ratio rule and reuses parseColor/contrastRatio for the simulated colors, so there is no duplicated color math. Simulation applies the Brettel-Vienot-Mollon matrices to each ResolvedColor, then re-parses the result to recover WCAG luminance.
  • The opt-in lives entirely in the CLI: --cvd composes the rule onto DEFAULT_RULE_DESCRIPTORS for that run. The rule is exported for selective composition but deliberately kept out of the default set, so default lint output is byte-identical.

Testing

  • bun test: 285 pass, 1 skip, 0 fail. New tests cover the Feature: color-blind contrast lint rule (opt-in, Brettel-Viénot-Mollon simulation) #48 worked example, a CVD-safe pair, and the rule's absence from the default rule set.
  • bun run lint and bun run build pass clean.
  • Dogfooded: design.md lint --cvd on a #E44001-on-white button reproduces the issue's exact figures (protanopia 2.92:1 on #9d9c10, deuteranopia 2.31:1 on #a7b314); without --cvd the output is unchanged.

Fixes #48

Adds a color-blind-contrast rule that simulates protanopia, deuteranopia,
and tritanopia, re-runs the component backgroundColor/textColor contrast
check on the simulated colors, and warns below a 3:1 floor. Off by default;
activated via a new --cvd flag on the lint command.

Fixes google-labs-code#48

@rajpratham1 rajpratham1 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a thoughtful accessibility enhancement that introduces an opt-in color-blind contrast lint rule without changing the default linting behavior. The implementation is modular, integrates cleanly with the existing rule system, exposes the feature through a CLI flag, and includes good test coverage to verify both the rule itself and that it remains disabled by default.

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.

Feature: color-blind contrast lint rule (opt-in, Brettel-Viénot-Mollon simulation)

2 participants