scripts/update-styles.mjs (46 lines of code) (raw):
import fs from 'fs';
import path from 'path';
import {fileURLToPath} from 'node:url';
import tokens from '../design-tokens.json' with {type: 'json'};
// eslint-disable-next-line no-underscore-dangle
const __filename = fileURLToPath(import.meta.url);
// eslint-disable-next-line no-underscore-dangle
const __dirname = path.dirname(__filename);
// https://stackoverflow.com/a/5624139
function hexToRgb(hex) {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result
? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16),
}
: null;
}
for (const {mode, color} of tokens[0].values) {
const filename = `src/global/variables${mode.name === 'Dark' ? '_dark' : ''}.css`;
const source = fs.readFileSync(path.resolve(__dirname, `../${filename}`), 'utf-8');
let result = source;
const newStyles = [];
for (const {name, value} of color) {
if (/^ring-.*-color$/.test(name)) {
const components = name.replace('-color', '-components');
const {r, g, b} = hexToRgb(value);
if (!source.includes(`--${name}:`)) {
newStyles.push(` --${components}: ${r}, ${g}, ${b};`);
newStyles.push(` --${name}: rgb(var(--${components})); /* ${value.toUpperCase()} */`);
} else {
result = result
.replace(new RegExp(`--${components}: .+;`), `--${components}: ${r}, ${g}, ${b};`)
.replace(new RegExp(`(--${name}: .+;) /\\* .+? \\*/`), `$1 /* ${value.toUpperCase()} */`);
}
}
}
if (result !== source) {
fs.writeFileSync(path.resolve(__dirname, `../${filename}`), result);
}
if (newStyles.length > 0) {
// eslint-disable-next-line no-console
console.log(`New variables detected. Please add them to ${filename}:\n${newStyles.join('\n')}`);
}
}