129 lines
5.1 KiB
JavaScript
129 lines
5.1 KiB
JavaScript
import fs from 'fs/promises';
|
|
import path from 'path';
|
|
|
|
async function walk(dir) {
|
|
const files = await fs.readdir(dir, { withFileTypes: true });
|
|
let results = [];
|
|
for (const file of files) {
|
|
const res = path.resolve(dir, file.name);
|
|
if (file.isDirectory()) {
|
|
results = results.concat(await walk(res));
|
|
} else if (file.name.endsWith('.vue')) {
|
|
results.push(res);
|
|
}
|
|
}
|
|
return results;
|
|
}
|
|
|
|
async function fixColors() {
|
|
const dirs = [path.resolve('app', 'components'), path.resolve('app', 'pages'), path.resolve('app', 'layouts')];
|
|
let files = [];
|
|
for (const dir of dirs) {
|
|
try {
|
|
files = files.concat(await walk(dir));
|
|
} catch (e) {
|
|
// Ignore if dir doesn't exist
|
|
}
|
|
}
|
|
|
|
for (const file of files) {
|
|
let content = await fs.readFile(file, 'utf-8');
|
|
let original = content;
|
|
|
|
// Generic regex for hardcoded grayscales in styles
|
|
const grayscales = {
|
|
'#000000': 'var(--bg-primary, #111111)',
|
|
'#000': 'var(--bg-primary, #111111)',
|
|
'#111111': 'var(--bg-primary, #111111)',
|
|
'#111': 'var(--bg-primary, #111111)',
|
|
'#1a1a1a': 'var(--bg-secondary, #1a1a1a)',
|
|
'#222222': 'var(--bg-tertiary, #222222)',
|
|
'#222': 'var(--bg-tertiary, #222222)',
|
|
'#2a2a2a': 'var(--bg-tertiary, #2a2a2a)',
|
|
'#333333': 'var(--bg-quaternary, #333333)',
|
|
'#333': 'var(--bg-quaternary, #333333)',
|
|
'#3a3a3a': 'var(--bg-quaternary, #3a3a3a)',
|
|
'#444444': 'var(--text-disabled, #444444)',
|
|
'#444': 'var(--text-disabled, #444444)',
|
|
'#666666': 'var(--text-quaternary, #666666)',
|
|
'#666': 'var(--text-quaternary, #666666)',
|
|
'#888888': 'var(--text-tertiary, #888888)',
|
|
'#888': 'var(--text-tertiary, #888888)',
|
|
'#999999': 'var(--text-tertiary, #999999)',
|
|
'#999': 'var(--text-tertiary, #999999)',
|
|
'#aaaaaa': 'var(--text-secondary, #aaaaaa)',
|
|
'#aaa': 'var(--text-secondary, #aaaaaa)',
|
|
'#cccccc': 'var(--text-secondary, #cccccc)',
|
|
'#ccc': 'var(--text-secondary, #cccccc)',
|
|
'#dddddd': 'var(--border-secondary, #dddddd)',
|
|
'#ddd': 'var(--border-secondary, #dddddd)',
|
|
'#eeeeee': 'var(--border-primary, #eeeeee)',
|
|
'#eee': 'var(--border-primary, #eeeeee)',
|
|
'#ffffff': 'var(--text-primary, #ffffff)',
|
|
'#fff': 'var(--text-primary, #ffffff)'
|
|
};
|
|
|
|
// We only want to replace inside <style> blocks.
|
|
const styleBlocks = content.match(/<style[^>]*>[\s\S]*?<\/style>/gi);
|
|
if (styleBlocks) {
|
|
for (const block of styleBlocks) {
|
|
let newBlock = block;
|
|
|
|
// Match CSS properties like background: #1a1a1a;
|
|
newBlock = newBlock.replace(/(background(-color)?|color|border(-color)?|border-(top|right|bottom|left)(-color)?|fill|stroke):\s*([^;}]*?)(#[0-9a-fA-F]{3,6})/gi, (match, p1, p2, p3, p4, p5, p6, hex) => {
|
|
const hexLower = hex.toLowerCase();
|
|
|
|
// Don't replace if it's already inside a var()
|
|
if (p6.includes('var(')) return match;
|
|
|
|
let replacement = hex;
|
|
|
|
if (grayscales[hexLower]) {
|
|
// Determine if it's a background, border, or text color
|
|
if (p1.startsWith('border')) {
|
|
replacement = `var(--border-secondary, ${hexLower})`;
|
|
} else if (p1.startsWith('background')) {
|
|
if (hexLower === '#ffffff' || hexLower === '#fff') {
|
|
replacement = `var(--card-bg, ${hexLower})`; // White background is usually a card
|
|
} else {
|
|
replacement = grayscales[hexLower].replace('text', 'bg'); // Force bg variables for background
|
|
}
|
|
} else if (p1 === 'color') {
|
|
if (['#000000', '#000', '#111111', '#111', '#1a1a1a', '#222222', '#222', '#2a2a2a'].includes(hexLower)) {
|
|
replacement = `var(--text-primary, ${hexLower})`;
|
|
} else {
|
|
replacement = grayscales[hexLower].replace('bg', 'text'); // Force text variables for color
|
|
}
|
|
} else {
|
|
replacement = grayscales[hexLower];
|
|
}
|
|
} else {
|
|
// Heuristic for unknown grayscales or dark colors
|
|
// Check if it's a dark shade (e.g. #040e15, #242f38)
|
|
if (p1.startsWith('background') && match.match(/#0[0-9a-f]{5}/i)) {
|
|
replacement = `var(--bg-secondary, ${hexLower})`;
|
|
} else if (p1.startsWith('background') && match.match(/#1[0-9a-f]{5}/i)) {
|
|
replacement = `var(--bg-secondary, ${hexLower})`;
|
|
} else if (p1.startsWith('background') && match.match(/#2[0-9a-f]{5}/i)) {
|
|
replacement = `var(--bg-tertiary, ${hexLower})`;
|
|
} else if (p1.startsWith('border') && match.match(/#[1-4][0-9a-f]{5}/i)) {
|
|
replacement = `var(--border-secondary, ${hexLower})`;
|
|
}
|
|
}
|
|
|
|
return `${p1}: ${p6}${replacement}`;
|
|
});
|
|
|
|
content = content.replace(block, newBlock);
|
|
}
|
|
}
|
|
|
|
if (content !== original) {
|
|
await fs.writeFile(file, content, 'utf-8');
|
|
console.log('Fixed', file);
|
|
}
|
|
}
|
|
}
|
|
|
|
fixColors().catch(console.error);
|