mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-11 20:08:56 +00:00
Quick proof of concept contrast tests
This commit is contained in:
12
package-lock.json
generated
12
package-lock.json
generated
@@ -34,6 +34,7 @@
|
||||
"chalk": "^5.3.0",
|
||||
"change-case": "^4.1.2",
|
||||
"chokidar": "^3.5.3",
|
||||
"colorjs.io": "^0.6.0-alpha.1",
|
||||
"command-line-args": "^5.2.1",
|
||||
"comment-parser": "^1.4.1",
|
||||
"cspell": "^6.18.1",
|
||||
@@ -5078,6 +5079,17 @@
|
||||
"integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/colorjs.io": {
|
||||
"version": "0.6.0-alpha.1",
|
||||
"resolved": "https://registry.npmjs.org/colorjs.io/-/colorjs.io-0.6.0-alpha.1.tgz",
|
||||
"integrity": "sha512-c/h/8uAmPydQcriRdX8UTAFHj6SpSHFHBA8LvMikvYWAVApPTwg/pyOXNsGmaCBd6L/EeDlRHSNhTtnIFp/qsg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/color"
|
||||
}
|
||||
},
|
||||
"node_modules/command-line-args": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz",
|
||||
|
||||
@@ -91,6 +91,7 @@
|
||||
"chalk": "^5.3.0",
|
||||
"change-case": "^4.1.2",
|
||||
"chokidar": "^3.5.3",
|
||||
"colorjs.io": "^0.6.0-alpha.1",
|
||||
"command-line-args": "^5.2.1",
|
||||
"comment-parser": "^1.4.1",
|
||||
"cspell": "^6.18.1",
|
||||
|
||||
107
src/styles/color/contrast.test.js
Normal file
107
src/styles/color/contrast.test.js
Normal file
@@ -0,0 +1,107 @@
|
||||
// Get a list of all CSS files in repo
|
||||
import chalk from 'chalk';
|
||||
import Color from 'colorjs.io';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
||||
|
||||
const paletteFiles = fs.readdirSync(__dirname).filter(file => file.endsWith('.css'));
|
||||
|
||||
function parse(contents) {
|
||||
// Regex for each declaration
|
||||
let regex = /^\s*--wa-color-(?<hue>[a-z]+)-(?<level>[0-9]+):\s*(?<color>[^;]+)\s*;$/gm;
|
||||
let matches = [...contents.matchAll(regex)];
|
||||
|
||||
if (matches.length === 0) {
|
||||
throw new Error('Cound not extract colors');
|
||||
}
|
||||
|
||||
let ret = {};
|
||||
|
||||
for (let match of matches) {
|
||||
let { hue, level, color } = match.groups;
|
||||
ret[hue] ??= {};
|
||||
level = level.replace(/^0+/, ''); // Leading zeroes throw off sorting
|
||||
ret[hue][level] = color;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
let targetContrasts = {
|
||||
40: 3,
|
||||
50: 4.5,
|
||||
60: 7,
|
||||
};
|
||||
|
||||
let result = { pass: 0, fail: 0, invalid: 0 };
|
||||
|
||||
for (let file of paletteFiles) {
|
||||
let css = fs.readFileSync(path.join(__dirname, file), 'utf8');
|
||||
let filePrefix = chalk.dim(`[${file}]`);
|
||||
let tokens = parse(css);
|
||||
|
||||
for (let hue in tokens) {
|
||||
let tints = tokens[hue];
|
||||
|
||||
for (let tint = 10; tint <= 50; tint += 10) {
|
||||
let color;
|
||||
|
||||
try {
|
||||
color = new Color(tints[tint]);
|
||||
} catch (e) {
|
||||
console.error(`[${file}] Invalid color ${hue}-${tint}: ${tints[tint]}`);
|
||||
result.invalid++;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (let difference in targetContrasts) {
|
||||
let targetContrast = targetContrasts[difference];
|
||||
let tint2 = tint + Number(difference);
|
||||
if (tint2 > 90) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let color2;
|
||||
try {
|
||||
color2 = new Color(tints[tint2]);
|
||||
} catch (e) {
|
||||
if (tint2 > 50) {
|
||||
// If 50, we'll look at it at some point as color1
|
||||
console.error(`${filePrefix} Invalid color ${hue}-${tint2}: ${tints[tint2]}`);
|
||||
result.invalid++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
let contrast = color.contrast(color2, 'WCAG21');
|
||||
let pass = contrast >= targetContrast;
|
||||
if (pass) {
|
||||
result.pass++;
|
||||
} else {
|
||||
result.fail++;
|
||||
console.log(
|
||||
chalk.red(
|
||||
`${filePrefix} WCAG 2.1 contrast between ${hue}-${tint} and ${hue}-${tint2} is ${contrast.toLocaleString('en')} < ${targetContrast}`,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let testCount = result.pass + result.fail;
|
||||
console.info(
|
||||
`Ran ${testCount} tests: ${chalk.green(`${chalk.bold(result.pass)} passed`)}` +
|
||||
(result.fail ? `, ${chalk.red(`${chalk.bold(result.fail)} failed`)}` : '') +
|
||||
(result.invalid ? `, ${chalk.red(`${chalk.bold(result.invalid)} invalid colors`)}` : ''),
|
||||
);
|
||||
|
||||
if (testCount === result.pass) {
|
||||
process.exit(0);
|
||||
} else {
|
||||
process.exit(1);
|
||||
}
|
||||
Reference in New Issue
Block a user