diff --git a/framework/core/js/src/common/helpers/textContrastClass.ts b/framework/core/js/src/common/helpers/textContrastClass.ts index 19fd1004c6..fa1e0aec0b 100644 --- a/framework/core/js/src/common/helpers/textContrastClass.ts +++ b/framework/core/js/src/common/helpers/textContrastClass.ts @@ -1,5 +1,5 @@ import isDark from '../utils/isDark'; -export default function textContrastClass(hexcolor: string): string { +export default function textContrastClass(hexcolor: string | null): string { return isDark(hexcolor) ? 'text-contrast--light' : 'text-contrast--dark'; } diff --git a/framework/core/js/src/common/utils/isDark.ts b/framework/core/js/src/common/utils/isDark.ts index eb49aa85d8..2f870491f8 100644 --- a/framework/core/js/src/common/utils/isDark.ts +++ b/framework/core/js/src/common/utils/isDark.ts @@ -7,19 +7,25 @@ * standards, but we use a custom threshold for each light and dark modes * to preserve design consistency. */ -export default function isDark(hexcolor: string): boolean { +export default function isDark(hexcolor: string | null): boolean { + // return if hexcolor is undefined or shorter than 4 characters, shortest hex form is #333; + // decided against regex hex color validation for performance considerations + if (!hexcolor || hexcolor.length < 4) { + return false; + } + let hexnumbers = hexcolor.replace('#', ''); - if (hexnumbers.length == 3) { + if (hexnumbers.length === 3) { hexnumbers += hexnumbers; } - const r = parseInt(hexnumbers.substr(0, 2), 16); - const g = parseInt(hexnumbers.substr(2, 2), 16); - const b = parseInt(hexnumbers.substr(4, 2), 16); + const r = parseInt(hexnumbers.slice(0, 2), 16); + const g = parseInt(hexnumbers.slice(2, 4), 16); + const b = parseInt(hexnumbers.slice(4, 6), 16); const yiq = (r * 299 + g * 587 + b * 114) / 1000; - const threshold = parseInt(window.getComputedStyle(document.body).getPropertyValue('--yiq-threshold')); + const threshold = parseInt(getComputedStyle(document.body).getPropertyValue('--yiq-threshold').trim()) || 128; return yiq < threshold; }