Utilities for disability accommodations: color blindness simulation, WCAG contrast math, and media-query watchers for user preferences.
npm install @accessibility-devkit/accommodationsReturns the hex color as it appears to someone with the given color vision deficiency.
import { simulateColorBlindness } from '@accessibility-devkit/accommodations';
simulateColorBlindness('#ff0000', 'protanopia'); // red as seen with protanopia
simulateColorBlindness('#00ff00', 'deuteranomaly'); // green as seen with partial deutan deficiencyAll 7 supported deficiency types:
| Value | Description |
|---|---|
'protanopia' |
Complete red insensitivity |
'deuteranopia' |
Complete green insensitivity |
'tritanopia' |
Complete blue insensitivity |
'achromatopsia' |
Complete color blindness (monochromacy) |
'protanomaly' |
Partial red insensitivity |
'deuteranomaly' |
Partial green insensitivity |
'tritanomaly' |
Partial blue insensitivity |
The -omaly variants are partial deficiencies; the others are complete loss of that channel.
Calculates the WCAG relative luminance contrast ratio between two hex colors. Returns a value between 1 (no contrast) and 21 (black on white).
import { getContrastRatio } from '@accessibility-devkit/accommodations';
getContrastRatio('#ffffff', '#000000'); // 21
getContrastRatio('#777777', '#ffffff'); // ~4.48Checks whether a foreground/background pair meets a WCAG contrast threshold.
import { meetsWCAG } from '@accessibility-devkit/accommodations';
meetsWCAG('#767676', '#ffffff'); // false — fails AA normal text
meetsWCAG('#595959', '#ffffff'); // true — passes AA normal text
meetsWCAG('#767676', '#ffffff', 'AA', 'large'); // true — passes AA large text
meetsWCAG('#595959', '#ffffff', 'AAA'); // false — fails AAA normal textWCAG thresholds: AA normal = 4.5:1, AA large = 3:1, AAA normal = 7:1, AAA large = 4.5:1.
Adjusts a foreground color (darkening first, then lightening) until it meets the WCAG threshold against the given background. Returns the original color unchanged if it already passes.
import { findAccessibleColor } from '@accessibility-devkit/accommodations';
findAccessibleColor('#aaaaaa', '#ffffff'); // returns a darker gray that passes AA
findAccessibleColor('#aaaaaa', '#ffffff', 'AAA'); // returns an even darker shade for AAAimport { prefersReducedMotion } from '@accessibility-devkit/accommodations';
if (prefersReducedMotion()) {
// use a simple fade instead of a complex animation
}Subscribes to changes in prefers-reduced-motion. Returns an unsubscribe function.
import { watchPrefersReducedMotion } from '@accessibility-devkit/accommodations';
const unsubscribe = watchPrefersReducedMotion((prefers) => {
animator.setReduced(prefers);
});
// When the component unmounts:
unsubscribe();import {
prefersHighContrast,
prefersDarkMode,
} from '@accessibility-devkit/accommodations';
if (prefersHighContrast()) { /* apply high-contrast theme */ }
if (prefersDarkMode()) { /* apply dark theme */ }color-blind— color vision deficiency simulation
MIT. Author: Luke Steuber.