Skip to content

Commit

Permalink
calculate contrast for wp type and show border if low (#176)
Browse files Browse the repository at this point in the history
Co-authored-by: PKiran <39373750+kiranparajuli589@users.noreply.github.com>
  • Loading branch information
individual-it and kiranparajuli589 committed Jul 29, 2022
1 parent 5d5af38 commit 1ce2ad7
Show file tree
Hide file tree
Showing 3 changed files with 186 additions and 20 deletions.
178 changes: 172 additions & 6 deletions src/components/tab/WorkPackage.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<template>
<div class="workpackage">
<div class="workpackage" @mouseover="resetColorsOnHover" @mouseleave="resetColorsOnHover">
<div class="row">
<div class="row__status"
:style="{'background-color':workpackage.statusCol}">
<div class="row__status__title">
:style="{'background-color': getWPStatusColor(), border: wpStatusBorder}">
<div class="row__status__title"
:style="{'color': wpStatusFontColor }">
{{ workpackage.statusTitle }}
</div>
</div>
Expand All @@ -13,7 +14,9 @@
</div>
<div class="row">
<div class="row__subject">
<span class="row__subject__type" :style="{'color':workpackage.typeCol}">
<span :ref="workpackage.typeTitle"
class="row__subject__type"
:style="{'color': workpackage.typeCol, '-webkit-text-stroke': wpTypeTextStroke}">
{{ workpackage.typeTitle }}
</span>
{{ workpackage.subject }}
Expand Down Expand Up @@ -50,6 +53,171 @@ export default {
required: true,
},
},
data: () => ({
wpTypeTextStroke: 'unset',
wpStatusFontColor: '#FFFFFF',
wpStatusBorder: '0',
}),
created() {
this.setWPTypeTextStroke()
this.setWPStatusFontColor()
this.setWPStatusBorder()
},
methods: {
resetColorsOnHover() {
this.setWPTypeTextStroke()
this.setWPStatusBorder()
},
getWPStatusColor() {
if (this.workpackage.statusCol === undefined || this.workpackage.statusCol === '') {
return '#F99601'
}
return this.workpackage.statusCol
},
setWPStatusFontColor() {
this.wpStatusFontColor = '#FFFFFF'
try {
const contrast = this.contrastRatio(
this.wpStatusFontColor,
this.getWPStatusColor()
)
if (contrast <= 2) {
this.wpStatusFontColor = '#000000'
}
} catch (e) {
// something went wrong, leave the values as they are
}
},
setWPStatusBorder() {
try {
let contrast = this.getContrastBetweenStatusColorAndBackground()
if (contrast <= 2) {
contrast = this.contrastRatio(this.getWPStatusColor(), '#000000')
if (contrast <= 2) {
this.wpStatusBorder = 'solid 1px #FFFFFF'
return
}
this.wpStatusBorder = 'solid 1px #000000'
return
}
this.wpStatusBorder = '0'
} catch (e) {
// something went wrong, leave the values as they are
}
},
getContrastBetweenStatusColorAndBackground() {
const backgroundColor = this.getBackgroundColor(this.getWPBackgroundElement())
return this.contrastRatio(this.getWPStatusColor(), backgroundColor)
},
setWPTypeTextStroke() {
this.wpTypeTextStroke = 'unset'
try {
const contrast = this.getContrastBetweenTypeColorAndBackground()
if (contrast <= 2) {
this.wpTypeTextStroke = '0.5px grey'
}
} catch {
// something went wrong, leave the values as they are
}
},
getContrastBetweenTypeColorAndBackground() {
const backgroundColor = this.getBackgroundColor(this.getWPBackgroundElement())
return this.contrastRatio(this.workpackage.typeCol, backgroundColor)
},
getWPBackgroundElement() {
let el = document.getElementById('workpackage-' + this.workpackage.id)
if (el === null) {
el = document.getElementById('tab-open-project')
}
return el
},
hexToRgbA(hex) {
let c
if (/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)) {
c = hex.substring(1).split('')
if (c.length === 3) {
c = [c[0], c[0], c[1], c[1], c[2], c[2]]
}
c = '0x' + c.join('')
return 'rgba(' + [(c >> 16) & 255, (c >> 8) & 255, c & 255].join(',') + ',1)'
}
throw new Error('Bad Hex')
},
// Parse rgb(r, g, b) and rgba(r, g, b, a) strings into an array.
// originated from https://github.com/jasonday/color-contrast/blob/e533684ce5d0c8d28479b3301b184bf88f5b7dd6/color-contrast.js
// Adapted from https://github.com/gka/chroma.js
parseRgb(colorString) {
let i, rgb, _i, _j
try {
colorString = this.hexToRgbA(colorString)
} catch (e) {
// it was not a hex string, so most likely a rgb(a) string
}
const rgbMatch = colorString.match(/rgb\(\s*(-?\d+),\s*(-?\d+)\s*,\s*(-?\d+)\s*\)/)
const rgbaMatch = colorString.match(/rgba\(\s*(-?\d+),\s*(-?\d+)\s*,\s*(-?\d+)\s*,\s*([01]|[01]?\.\d+)\)/)
if (rgbMatch !== null) {
rgb = rgbMatch.slice(1, 4)
for (i = _i = 0; _i <= 2; i = ++_i) {
rgb[i] = +rgb[i]
}
rgb[3] = 1
// eslint-disable-next-line no-cond-assign
} else if (rgbaMatch !== null) {
rgb = rgbaMatch.slice(1, 5)
for (i = _j = 0; _j <= 3; i = ++_j) {
rgb[i] = +rgb[i]
}
} else {
throw new Error('could not parse color')
}
return rgb
},
// originated from https://github.com/jasonday/color-contrast/blob/e533684ce5d0c8d28479b3301b184bf88f5b7dd6/color-contrast.js
// Based on http://www.w3.org/TR/WCAG20/#relativeluminancedef
relativeLuminance(c) {
const lum = []
for (let i = 0; i < 3; i++) {
const v = c[i] / 255
lum.push(v < 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4))
}
return (0.2126 * lum[0]) + (0.7152 * lum[1]) + (0.0722 * lum[2])
},
// originated from https://github.com/jasonday/color-contrast/blob/e533684ce5d0c8d28479b3301b184bf88f5b7dd6/color-contrast.js
// Based on http://www.w3.org/TR/WCAG20/#contrast-ratiodef
contrastRatio(x, y) {
const l1 = this.relativeLuminance(this.parseRgb(x))
const l2 = this.relativeLuminance(this.parseRgb(y))
return (Math.max(l1, l2) + 0.05) / (Math.min(l1, l2) + 0.05)
},
// originated from https://github.com/jasonday/color-contrast/blob/e533684ce5d0c8d28479b3301b184bf88f5b7dd6/color-contrast.js
getBackgroundColor(el) {
const styles = getComputedStyle(el)
const bgColor = styles.backgroundColor
const bgImage = styles.backgroundImage
const rgb = this.parseRgb(bgColor) + ''
const alpha = rgb.split(',')
// if background has alpha transparency, flag manual check
if (alpha[3] < 1 && alpha[3] > 0) {
throw new Error('could not determine background color')
}
// if element has no background image, or transparent background (alpha == 0) return bgColor
if (bgColor !== 'rgba(0, 0, 0, 0)' && bgColor !== 'transparent' && bgImage === 'none' && alpha[3] !== '0') {
return bgColor
} else if (bgImage !== 'none') {
throw new Error('could not determine background color')
}
// retest if not returned above
if (el.tagName === 'HTML') {
return 'rgb(255, 255, 255)'
} else {
return this.getBackgroundColor(el.parentNode)
}
},
},
}
</script>

Expand All @@ -75,13 +243,11 @@ export default {
font-size: 0.75rem;
border-radius: 2px;
margin-right: 4px;
background-color: #F99601;
&__title {
font-size: 0.75rem;
line-height: 14px;
text-align: center;
filter: contrast(0) brightness(0);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
exports[`WorkPackage.vue shows work packages information 1`] = `
<div class="workpackage">
<div class="row">
<div class="row__status" style="background-color: blue;">
<div class="row__status__title">
<div class="row__status" style="background-color: blue; border: 0px;">
<div class="row__status__title" style="color: rgb(255, 255, 255);">
in-progress
</div>
</div>
Expand Down
24 changes: 12 additions & 12 deletions tests/jest/views/__snapshots__/ProjectsTab.spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ exports[`ProjectsTab.vue fetchWorkpackages adds every work-package only once 1`]
<div class="linked-workpackages--workpackage">
<div class="workpackage linked-workpackages--workpackage--item" id="workpackage-123">
<div class="row">
<div class="row__status">
<div class="row__status__title">
<div class="row__status" style="background-color: rgb(249, 150, 1); border: 0px;">
<div class="row__status__title" style="color: rgb(255, 255, 255);">
open
</div>
</div>
Expand Down Expand Up @@ -74,8 +74,8 @@ exports[`ProjectsTab.vue fetchWorkpackages shows the linked workpackages 1`] = `
<div class="linked-workpackages--workpackage">
<div class="workpackage linked-workpackages--workpackage--item" id="workpackage-123">
<div class="row">
<div class="row__status" style="background-color: rgb(165, 216, 255);">
<div class="row__status__title">
<div class="row__status" style="background-color: rgb(165, 216, 255); border: 0px;">
<div class="row__status__title" style="color: rgb(0, 0, 0);">
open
</div>
</div>
Expand Down Expand Up @@ -114,8 +114,8 @@ exports[`ProjectsTab.vue fetchWorkpackages shows the linked workpackages 1`] = `
<div class="linked-workpackages--workpackage">
<div class="workpackage linked-workpackages--workpackage--item" id="workpackage-589">
<div class="row">
<div class="row__status" style="background-color: rgb(165, 216, 255);">
<div class="row__status__title">
<div class="row__status" style="background-color: rgb(165, 216, 255); border: 0px;">
<div class="row__status__title" style="color: rgb(0, 0, 0);">
प्रगति हुदैछ
</div>
</div>
Expand Down Expand Up @@ -162,8 +162,8 @@ exports[`ProjectsTab.vue fetchWorkpackages shows the linked workpackages 2`] = `
<div class="linked-workpackages--workpackage">
<div class="workpackage linked-workpackages--workpackage--item" id="workpackage-123">
<div class="row">
<div class="row__status">
<div class="row__status__title">
<div class="row__status" style="background-color: rgb(249, 150, 1); border: 0px;">
<div class="row__status__title" style="color: rgb(255, 255, 255);">
open
</div>
</div>
Expand Down Expand Up @@ -202,8 +202,8 @@ exports[`ProjectsTab.vue fetchWorkpackages shows the linked workpackages 2`] = `
<div class="linked-workpackages--workpackage">
<div class="workpackage linked-workpackages--workpackage--item" id="workpackage-589">
<div class="row">
<div class="row__status">
<div class="row__status__title">
<div class="row__status" style="background-color: rgb(249, 150, 1); border: 0px;">
<div class="row__status__title" style="color: rgb(255, 255, 255);">
प्रगति हुदैछ
</div>
</div>
Expand Down Expand Up @@ -250,8 +250,8 @@ exports[`ProjectsTab.vue onSave shows the just linked workpackage 1`] = `
<div class="linked-workpackages--workpackage">
<div class="workpackage linked-workpackages--workpackage--item workpackage-transition" id="workpackage-1">
<div class="row">
<div class="row__status" style="background-color: blue;">
<div class="row__status__title">
<div class="row__status" style="background-color: blue; border: 0px;">
<div class="row__status__title" style="color: rgb(255, 255, 255);">
in-progress
</div>
</div>
Expand Down

0 comments on commit 1ce2ad7

Please sign in to comment.