mirror of
https://github.com/grafana/grafana.git
synced 2025-02-14 01:23:32 -06:00
Contrast: Improve automatic contrast text logic to include opacity and background (#34190)
This commit is contained in:
parent
c2ee2f10a7
commit
8ecfad6995
@ -177,6 +177,10 @@ describe('utils/colorManipulator', () => {
|
||||
expect(getContrastRatio('#FFF', '#FFF')).toEqual(1);
|
||||
});
|
||||
|
||||
it('Can also take into account opacity for background', () => {
|
||||
expect(getContrastRatio('#FFF', 'rgba(255,255,255,0.1)', '#000')).toEqual(17.5);
|
||||
});
|
||||
|
||||
it('returns a ratio for dark-grey : light-grey', () => {
|
||||
//expect(getContrastRatio('#707070', '#E5E5E5'))to.be.approximately(3.93, 0.01);
|
||||
});
|
||||
|
@ -175,12 +175,13 @@ export function recomposeColor(color: DecomposeColor) {
|
||||
* Formula: https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests
|
||||
* @param foreground - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla()
|
||||
* @param background - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla()
|
||||
* @param canvas - A CSS color that alpha based backgrounds blends into
|
||||
* @returns A contrast ratio value in the range 0 - 21.
|
||||
* @beta
|
||||
*/
|
||||
export function getContrastRatio(foreground: string, background: string) {
|
||||
export function getContrastRatio(foreground: string, background: string, canvas?: string) {
|
||||
const lumA = getLuminance(foreground);
|
||||
const lumB = getLuminance(background);
|
||||
const lumB = getLuminance(background, canvas);
|
||||
return (Math.max(lumA, lumB) + 0.05) / (Math.min(lumA, lumB) + 0.05);
|
||||
}
|
||||
|
||||
@ -190,13 +191,23 @@ export function getContrastRatio(foreground: string, background: string) {
|
||||
*
|
||||
* Formula: https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests
|
||||
* @param color - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla(), color()
|
||||
* @param background - CSS color that needs to be take in to account to calculate luminance for colors with opacity
|
||||
* @returns The relative brightness of the color in the range 0 - 1
|
||||
* @beta
|
||||
*/
|
||||
export function getLuminance(color: string) {
|
||||
export function getLuminance(color: string, background?: string) {
|
||||
const parts = decomposeColor(color);
|
||||
|
||||
let rgb = parts.type === 'hsl' ? decomposeColor(hslToRgb(color)).values : parts.values;
|
||||
|
||||
if (background && parts.type === 'rgba') {
|
||||
const backgroundParts = decomposeColor(background);
|
||||
const alpha = rgb[3];
|
||||
rgb[0] = rgb[0] * alpha + backgroundParts.values[0] * (1 - alpha);
|
||||
rgb[1] = rgb[1] * alpha + backgroundParts.values[1] * (1 - alpha);
|
||||
rgb[2] = rgb[2] * alpha + backgroundParts.values[2] * (1 - alpha);
|
||||
}
|
||||
|
||||
const rgbNumbers = rgb.map((val: any) => {
|
||||
if (parts.type !== 'color') {
|
||||
val /= 255; // normalized
|
||||
|
@ -257,7 +257,9 @@ export function createColors(colors: ThemeColorsInput): ThemeColors {
|
||||
|
||||
function getContrastText(background: string, threshold: number = contrastThreshold) {
|
||||
const contrastText =
|
||||
getContrastRatio(dark.text.maxContrast, background) >= threshold ? dark.text.maxContrast : light.text.maxContrast;
|
||||
getContrastRatio(dark.text.maxContrast, background, base.background.primary) >= threshold
|
||||
? dark.text.maxContrast
|
||||
: light.text.maxContrast;
|
||||
// todo, need color framework
|
||||
return contrastText;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user