Skip to content
This repository has been archived by the owner on Aug 21, 2023. It is now read-only.

Commit

Permalink
Revert BEMBED-275: Helpscout chat modal color contrast
Browse files Browse the repository at this point in the history
  • Loading branch information
maria-p committed May 28, 2021
1 parent 5ae9532 commit 57a5ee5
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 102 deletions.
17 changes: 10 additions & 7 deletions src/styles/utilities/color.js
Expand Up @@ -95,14 +95,14 @@ export const makeBrandColors = (brandColor = defaultBrandColor) => {
backgroundColorUIFocus = darken(brandColor, 10)
svgPathPrimary = darken(brandColor, 30)
svgPathSecondary = 'white'
textColorInactive = darken(brandColor, 35)
textColorInteractive = 'white'
textColorMuted = darken(brandColor, 10)
}

if (colorShade === 'lightest') {
backgroundColorInteractive = darken(brandColor, 50)
backgroundColorInteractive = darken(brandColor, 5)
textColor = darken(brandColor, 70)
textColorInteractive = darken(brandColor, 70)
textColorInactive = darken(brandColor, 35)
textColorMuted = darken(brandColor, 10)

if (isWhite) {
textColor = '#394956'
Expand All @@ -111,8 +111,11 @@ export const makeBrandColors = (brandColor = defaultBrandColor) => {
}

if (colorShade === 'light') {
backgroundColorInteractive = darken(brandColor, 40)
backgroundColorInteractive = darken(brandColor, 8)
textColor = darken(brandColor, 55)
textColorInteractive = darken(brandColor, 55)
textColorInactive = darken(brandColor, 35)
textColorMuted = darken(brandColor, 10)
}

if (colorShade === 'dark' || colorShade === 'darkest') {
Expand All @@ -126,7 +129,7 @@ export const makeBrandColors = (brandColor = defaultBrandColor) => {
}

if (colorShade === 'dark') {
backgroundColorInteractive = darken(brandColor, 30)
backgroundColorInteractive = darken(brandColor, 8)
backgroundColorUIHover = darken(brandColor, 3)
backgroundColorUIActive = darken(brandColor, 6)
backgroundColorUIFocus = darken(brandColor, 10)
Expand All @@ -136,7 +139,7 @@ export const makeBrandColors = (brandColor = defaultBrandColor) => {
}

if (colorShade === 'darkest') {
backgroundColorInteractive = lighten(brandColor, 30)
backgroundColorInteractive = lighten(brandColor, 16)
backgroundColorUIHover = lighten(brandColor, 3)
backgroundColorUIActive = lighten(brandColor, 6)
backgroundColorUIFocus = lighten(brandColor, 10)
Expand Down
18 changes: 0 additions & 18 deletions src/utilities/__tests__/color/contrast.test.js

This file was deleted.

37 changes: 18 additions & 19 deletions src/utilities/__tests__/color/getColorShade.test.js
Expand Up @@ -11,37 +11,36 @@ test('Returns "lightest" for lightest colors', () => {
expect(getColorShade('#eee')).toBe('lightest')
expect(getColorShade('#e6e6e6')).toBe('lightest')
expect(getColorShade('#e5e5e5')).toBe('lightest')
expect(getColorShade('#e4e4d4')).toBe('lightest')
expect(getColorShade('#ddd')).toBe('lightest')
})

test('Returns "light" for light colors', () => {
expect(getColorShade('#e4e4d4')).toBe('light')
expect(getColorShade('#ddd')).toBe('light')
expect(getColorShade('#ccc')).toBe('light')
expect(getColorShade('#bbb')).toBe('light')
expect(getColorShade('#ffa3ff')).toBe('light')
expect(getColorShade('#50E3C2')).toBe('light')
expect(getColorShade('#aaa')).toBe('light')
expect(getColorShade('#9e9e9e')).toBe('light')
expect(getColorShade('#5fa5f7')).toBe('light')
expect(getColorShade('#9c9c9c')).toBe('light')
expect(getColorShade('#777')).toBe('light')
expect(getColorShade('#2dc09f')).toBe('light')
expect(getColorShade('#56c288')).toBe('light')
expect(getColorShade('#ffc646')).toBe('light')
expect(getColorShade('#ff9139')).toBe('light')
})

test('Returns "dark" for dark colors', () => {
expect(getColorShade('#aaa')).toBe('dark')
expect(getColorShade('#9e9e9e')).toBe('dark')
expect(getColorShade('#2ec1a0')).toBe('dark')
expect(getColorShade('#60a6f8')).toBe('dark')
expect(getColorShade('#9c9c9c')).toBe('dark')
expect(getColorShade('#999')).toBe('dark')
expect(getColorShade('#888')).toBe('dark')
expect(getColorShade('#777')).toBe('dark')
expect(getColorShade('#666')).toBe('dark')
expect(getColorShade('#555')).toBe('dark')
expect(getColorShade('#444')).toBe('dark')
expect(getColorShade('#333')).toBe('dark')
expect(getColorShade('#282828')).toBe('dark')
expect(getColorShade('#c50aa7')).toBe('dark')
expect(getColorShade('#027caf')).toBe('dark')
expect(getColorShade('#8e5dd0')).toBe('dark')
expect(getColorShade('#0077cc')).toBe('dark')
expect(getColorShade('#e6261c')).toBe('dark')
expect(getColorShade('#556575')).toBe('dark')
expect(getColorShade('#2dc09f')).toBe('dark')
expect(getColorShade('#5fa5f7')).toBe('dark')
expect(getColorShade('#8db058')).toBe('dark')
expect(getColorShade('#f144ff')).toBe('dark')
expect(getColorShade('#6eb4ff')).toBe('dark')
})

test('Returns "darkest" for light colors', () => {
Expand All @@ -62,6 +61,6 @@ test('Can provide custom RGB prop values', () => {
g: 999,
b: 999,
}
expect(getColorShade('#767676', darkValues)).toEqual('dark')
expect(getColorShade('#767676', lightValues)).toEqual('light')
expect(getColorShade('#ff6688', darkValues)).toEqual('dark')
expect(getColorShade('#ff6688', lightValues)).toEqual('light')
})
8 changes: 0 additions & 8 deletions src/utilities/__tests__/color/luminance.test.js

This file was deleted.

12 changes: 1 addition & 11 deletions src/utilities/__tests__/color/optimalTextColor.test.js
Expand Up @@ -13,26 +13,16 @@ test('Returns white, if backgroundColor is too dark', () => {
expect(optimalTextColor('#340000')).toEqual('white')
expect(optimalTextColor('#340000')).toEqual('white')
expect(optimalTextColor('#566')).toEqual('white')
expect(optimalTextColor('#ff6688')).toEqual('white')
})

test('Returns black, if backgroundColor is too bright', () => {
expect(optimalTextColor('#ff6688')).toEqual('black')
expect(optimalTextColor('#fff')).toEqual('black')
expect(optimalTextColor('#eee')).toEqual('black')
expect(optimalTextColor('#d9d9dd')).toEqual('black')
expect(optimalTextColor('#c1cbd4')).toEqual('black')
})

test('Returns black, if backgroundColor is dark, but contrast with white is poor', () => {
expect(optimalTextColor('#42c881')).toEqual('black')
expect(optimalTextColor('#eaac79')).toEqual('black')
})

test('Returns white, if backgroundColor is bright, but contrast with black is poor', () => {
expect(optimalTextColor('#666')).toEqual('white')
expect(optimalTextColor('#555')).toEqual('white')
})

test('Can provide custom RGB prop values', () => {
const customValues = {
r: 999,
Expand Down
48 changes: 9 additions & 39 deletions src/utilities/color.js
Expand Up @@ -3,9 +3,9 @@ const isNumber = value => typeof value === 'number'

const lightThreshold = 0.61
const optimalTextColorValues = {
r: 299,
g: 587,
b: 114,
r: 129,
g: 522,
b: 49,
}

// Source
Expand Down Expand Up @@ -49,53 +49,23 @@ export const hexToHsl = hex => {
return rgbToHsl(rgb.r, rgb.g, rgb.b)
}

// Source
// https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-procedure
export const luminance = rgb => {
const a = [rgb.r, rgb.g, rgb.b].map(function (v) {
v /= 255
return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4)
})
return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722
}

export const contrast = (rgb1, rgb2) => {
const lum1 = luminance(rgb1)
const lum2 = luminance(rgb2)
const brightest = Math.max(lum1, lum2)
const darkest = Math.min(lum1, lum2)

return (brightest + 0.05) / (darkest + 0.05)
}

export const optimalTextColor = (
backgroundHex,
propValues = optimalTextColorValues
) => {
if (!isHex(backgroundHex)) return null

// Defaults from original formula:
// r: 299
// g: 587
// b: 114
const defaultPropValues = optimalTextColorValues
const { r, g, b } = Object.assign({}, defaultPropValues, propValues)
const backgroundRgb = hexToRgb(backgroundHex)
const shade = Math.round(
(backgroundRgb.r * r + backgroundRgb.g * g + backgroundRgb.b * b) / 1000
)

const contrastWithBlack = contrast(backgroundRgb, { r: 0, g: 0, b: 0 })
const contrastWithWhite = contrast(backgroundRgb, { r: 255, g: 255, b: 255 })

if (shade >= 128) {
// if background shade suggests black, but it does not pass
// text contrast accessibility guidelines, check if white feels better
return contrastWithBlack < 4.5 && contrastWithWhite > contrastWithBlack
? 'white'
: 'black'
}

// if shade suggests white, but it does not pass, check if black is better
return contrastWithWhite < 4.5 && contrastWithBlack > contrastWithWhite
? 'black'
: 'white'
return shade >= 128 ? 'black' : 'white'
}

export const rgbToHsl = (red, green, blue) => {
Expand Down Expand Up @@ -186,7 +156,7 @@ export const getColorShade = (hex, propValues = optimalTextColorValues) => {
const l = hsl.l
const isDarkText = optimalTextColor(hex, propValues) === 'black'

if (l >= 0.85) {
if (l >= 0.9) {
return 'lightest'
} else if (l >= lightThreshold) {
return isDarkText ? 'light' : 'dark'
Expand Down

0 comments on commit 57a5ee5

Please sign in to comment.