Skip to content

Commit

Permalink
fix: recalibrate getTextColor function (#983)
Browse files Browse the repository at this point in the history
Ensure that getTextColor is choosing colors with better contrast.
  • Loading branch information
nataliepina authored Jul 27, 2023
1 parent 4c9c6e9 commit 402461e
Showing 1 changed file with 35 additions and 25 deletions.
60 changes: 35 additions & 25 deletions packages/shared/styles/color.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,38 +81,48 @@ export const getTextColor = (
darkTextColor,
lightTextColor
): string => {
// Convert color from hex to RGB.
const getRGB = (c: string | number): number => {
return parseInt(c as string, 16) || (c as number);
};

// Convert to sRGB and apply gamma correction.
const getsRGB = (c: string): number => {
const rgb = getRGB(c) / 255;
return rgb <= 0.03928 ? rgb / 12.92 : Math.pow((rgb + 0.055) / 1.055, 2.4);
};

// Calculate relative luminance.
const getLuminance = (hexColor: string): number => {
return (
0.2126 * getsRGB(hexColor.slice(1, 3)) +
0.7152 * getsRGB(hexColor.slice(3, 5)) +
0.0722 * getsRGB(hexColor.slice(5, 7))
);
};

// Use relative luminance to compare color contrast.
const getContrast = (f: string, b: string): number => {
// Use relative luminance to compare color contrast.
const getLuminance = (hexColor: string): number => {
// Convert to sRGB and apply gamma correction.
const getRGB = (c: string | number): number =>
parseInt(c as string, 16) || (c as number);
const getsRGB = (c: string): number => {
const rgb = getRGB(c) / 255;
return rgb <= 0.03928
? rgb / 12.92
: Math.pow((rgb + 0.055) / 1.055, 2.4);
};

return (
0.2126 * getsRGB(hexColor.slice(1, 3)) +
0.7152 * getsRGB(hexColor.slice(3, 5)) +
0.0722 * getsRGB(hexColor.slice(5, 7))
);
};

const L1 = getLuminance(f);
const L2 = getLuminance(b);
// Ratio formula is defined by WCAG guidelines
return (Math.max(L1, L2) + 0.05) / (Math.min(L1, L2) + 0.05);
};

const LIGHT_COLOR = getContrast(bgColor, lightTextColor);
const DARK_COLOR = getContrast(bgColor, darkTextColor);
// WCAG 2.2 color contrast standard for normal text.
const MIN_NORMAL_CONTRAST = 4.5;

const contrastWithDarkText = getContrast(bgColor, darkTextColor);
const contrastWithLightText = getContrast(bgColor, lightTextColor);

if (
contrastWithLightText >= MIN_NORMAL_CONTRAST &&
contrastWithDarkText < MIN_NORMAL_CONTRAST
) {
return lightTextColor;
}

// Determine which color has the highest contrast ratio and return that color.
return LIGHT_COLOR > DARK_COLOR ? lightTextColor : darkTextColor;
return contrastWithDarkText > MIN_NORMAL_CONTRAST
? darkTextColor
: lightTextColor;
};

// Assumes we always want our default hover colors to be lower
Expand Down

0 comments on commit 402461e

Please sign in to comment.