diff --git a/styles/css/core/custom-media-breakpoints.css b/styles/css/core/custom-media-breakpoints.css index 65a01067ab..f44a846dc8 100644 --- a/styles/css/core/custom-media-breakpoints.css +++ b/styles/css/core/custom-media-breakpoints.css @@ -1,7 +1,7 @@ /** * IMPORTANT: This file is the result of assembling design tokens * Do not edit directly - * Generated on Thu, 01 Jun 2023 14:00:29 GMT + * Generated on Sat, 03 Jun 2023 13:27:55 GMT */ @custom-media --min-pgn-size-breakpoint-xs (min-width: 0); diff --git a/styles/css/core/variables.css b/styles/css/core/variables.css index 5a672e7860..c1f0d11aa0 100644 --- a/styles/css/core/variables.css +++ b/styles/css/core/variables.css @@ -1,7 +1,7 @@ /** * IMPORTANT: This file is the result of assembling design tokens * Do not edit directly - * Generated on Thu, 01 Jun 2023 14:00:29 GMT + * Generated on Sat, 03 Jun 2023 13:27:55 GMT */ :root { diff --git a/styles/css/themes/light/utility-classes.css b/styles/css/themes/light/utility-classes.css index 27d19180b5..f3a6270e8f 100644 --- a/styles/css/themes/light/utility-classes.css +++ b/styles/css/themes/light/utility-classes.css @@ -1,7 +1,7 @@ /** * IMPORTANT: This file is the result of assembling design tokens * Do not edit directly - * Generated on Thu, 01 Jun 2023 14:00:29 GMT + * Generated on Sat, 03 Jun 2023 13:27:55 GMT */ .bg-accent-a { diff --git a/styles/css/themes/light/variables.css b/styles/css/themes/light/variables.css index 6aaa33a64d..a1ac3d06fb 100644 --- a/styles/css/themes/light/variables.css +++ b/styles/css/themes/light/variables.css @@ -1,7 +1,7 @@ /** * IMPORTANT: This file is the result of assembling design tokens * Do not edit directly - * Generated on Thu, 01 Jun 2023 14:00:29 GMT + * Generated on Sat, 03 Jun 2023 13:27:55 GMT */ :root { diff --git a/tokens/sass-helpers.js b/tokens/sass-helpers.js index 5d99d2f75c..70c159d181 100644 --- a/tokens/sass-helpers.js +++ b/tokens/sass-helpers.js @@ -6,14 +6,24 @@ const chroma = require('chroma-js'); * Javascript version of bootstrap's color-yiq function. Decides whether to return light color variant or dark one * based on contrast value of the input color * - * @param color - chroma-js color instance - * @param {String} [themeVariant] - theme variant name that will be used to find default contrast colors - * @param {String} [light] - light color variant from ./src/themes/{themeVariant}/global/other.json - * @param {String} [dark] - dark color variant from ./src/themes/{themeVariant}/global/other.json - * @param {Number} [threshold] - contrast threshold from ./src/core/global/other.json + * @param {Object} args + * @param {Object} args.tokenName - Name of design token, used to log warnings + * @param {Object} args.color - chroma-js color instance + * @param {String} args.light - light color variant from ./src/themes/{themeVariant}/global/other.json + * @param {String} args.dark - dark color variant from ./src/themes/{themeVariant}/global/other.json + * @param {Number} args.threshold - contrast threshold from ./src/core/global/other.json + * @param {String} [args.themeVariant] - theme variant name that will be used to find default contrast colors + * * @return chroma-js color instance (one of dark or light variants) */ -function colorYiq(color, light, dark, threshold, themeVariant = 'light') { +function colorYiq({ + tokenName, + originalColor, + light, + dark, + threshold, + themeVariant = 'light', +}) { const defaultThresholdFile = fs.readFileSync(path.resolve(__dirname, 'src/core/global', 'other.json'), 'utf8'); const defaultThreshold = JSON.parse(defaultThresholdFile)['yiq-contrasted-threshold']; @@ -27,24 +37,37 @@ function colorYiq(color, light, dark, threshold, themeVariant = 'light') { const lightColor = light || defaultLight; const darkColor = dark || defaultDark; - const [r, g, b] = color.rgb(); + const [r, g, b] = originalColor.rgb(); const yiq = ((r * 299) + (g * 587) + (b * 114)) * 0.001; let result = yiq >= contrastThreshold ? chroma(darkColor) : chroma(lightColor); + const maxAttempts = 10; // maximum number of attempts to darken/brighten color to pass contrast ratio if (yiq >= contrastThreshold) { // check whether the resulting combination of colors passes a11y contrast ratio of 4:5:1 - // if not - darken resulting color until it does - while (chroma.contrast(color, result) < 4.5) { + // if not - darken resulting color until it does until maxAttempts is reached. + let numDarkenAttempts = 1; + while (chroma.contrast(originalColor, result) < 4.5 && numDarkenAttempts <= maxAttempts) { result = result.darken(0.1); + numDarkenAttempts += 1; + if (numDarkenAttempts === maxAttempts) { + // eslint-disable-next-line no-console + console.warn(`WARNING: Failed to darken ${tokenName} to pass contrast ratio of 4.5:1 (Original: ${originalColor.hex()}; Attempted: ${result.hex()}).`); + } } return result; } // check whether the resulting combination of colors passes a11y contrast ratio of 4:5:1 - // if not - brighten resulting color until it does - while (chroma.contrast(color, result) < 4.5) { + // if not - brighten resulting color until it does until maxAttempts is reached. + let numBrightenAttempts = 1; + while (chroma.contrast(originalColor, result) < 4.5 && numBrightenAttempts <= maxAttempts) { result = result.brighten(0.1); + numBrightenAttempts += 1; + if (numBrightenAttempts === maxAttempts) { + // eslint-disable-next-line no-console + console.warn(`WARNING: Failed to brighten ${tokenName} () to pass contrast ratio of 4.5:1 (Original: ${originalColor.hex()}; Attempted: ${result.hex()}).`); + } } return result; } diff --git a/tokens/style-dictionary.js b/tokens/style-dictionary.js index 33e11bf020..217abf832d 100644 --- a/tokens/style-dictionary.js +++ b/tokens/style-dictionary.js @@ -9,7 +9,12 @@ const cssUtilities = require('./css-utilities'); const { fileHeader, sortByReference } = StyleDictionary.formatHelpers; const colorTransform = (token, theme) => { - const { value, modify = [], original } = token; + const { + name: tokenName, + value, + original, + modify = [], + } = token; const reservedColorValues = ['inherit', 'initial', 'revert', 'unset', 'currentColor']; if (reservedColorValues.includes(original.value)) { @@ -27,7 +32,14 @@ const colorTransform = (token, theme) => { break; case 'color-yiq': { const { light, dark, threshold } = modifier; - color = colorYiq(color, light, dark, threshold, theme); + color = colorYiq({ + tokenName, + originalColor: color, + light, + dark, + threshold, + theme, + }); break; } case 'darken': diff --git a/www/src/components/Menu.scss b/www/src/components/Menu.scss index 8c2a2abfc1..2561756db8 100644 --- a/www/src/components/Menu.scss +++ b/www/src/components/Menu.scss @@ -37,7 +37,7 @@ } &-items { - margin-bottom: $spacer; + margin-bottom: var(--pgn-spacing-spacer-base); .pgn_collapsible { font-size: var(--pgn-typography-font-size-xs);