Skip to content

Commit a8e2a66

Browse files
committed
Merge pull request #1325 from bcgov/bugs/ecer-3444
ECER-3444: Set colours and prevent regression with validate-colors husky pre-commit
1 parent caef013 commit a8e2a66

File tree

8 files changed

+259
-34
lines changed

8 files changed

+259
-34
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
npm run validate-colors

src/ECER.Clients.RegistryPortal/ecer.clients.registryportal.client/package-lock.json

Lines changed: 61 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/ECER.Clients.RegistryPortal/ecer.clients.registryportal.client/package.json

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
"cy-run": "cypress run",
1717
"e2e-chrome": "cypress run --browser chrome --headed",
1818
"storybook": "storybook dev -p 6006",
19-
"build-storybook": "storybook build"
19+
"build-storybook": "storybook build",
20+
"prepare": "husky",
21+
"validate-colors": "tsx scripts/validate-colors.ts"
2022
},
2123
"dependencies": {
2224
"@mdi/font": "^7.3.67",
@@ -35,9 +37,9 @@
3537
},
3638
"devDependencies": {
3739
"@chromatic-com/storybook": "^4.0.1",
40+
"@storybook/addon-docs": "^9.0.17",
3841
"@storybook/addon-vitest": "^9.0.17",
3942
"@storybook/vue3-vite": "^9.0.17",
40-
"@storybook/addon-docs": "^9.0.17",
4143
"@tsconfig/node18": "^18.2.4",
4244
"@types/lodash": "^4.17.20",
4345
"@types/luxon": "^3.6.2",
@@ -58,13 +60,15 @@
5860
"eslint-plugin-storybook": "^9.0.17",
5961
"eslint-plugin-unused-imports": "^4.1.4",
6062
"eslint-plugin-vue": "^10.3.0",
63+
"husky": "^9.1.7",
6164
"openapicmd": "^2.6.1",
6265
"playwright": "^1.53.1",
63-
"storybook": "^9.0.17",
64-
"vitest": "^3.2.4",
6566
"sass": "^1.86.3",
67+
"storybook": "^9.0.17",
68+
"tsx": "^4.20.3",
6669
"typescript": "~5.8.3",
6770
"vite": "^7.0.2",
71+
"vitest": "^3.2.4",
6872
"vue-eslint-parser": "^10.2.0",
6973
"vue-tsc": "^3.0.3"
7074
},
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
#!/usr/bin/env node
2+
3+
import fs from "fs";
4+
import path from "path";
5+
6+
interface ColorMap {
7+
[key: string]: string;
8+
}
9+
10+
function extractColorsFromTheme(filePath: string): ColorMap {
11+
const content = fs.readFileSync(filePath, "utf-8");
12+
const colors: ColorMap = {};
13+
14+
const colorMatches = content.match(/(["']?)([^"'\s]+)\1\s*:\s*"#([A-Fa-f0-9]{6})"/g);
15+
16+
if (colorMatches) {
17+
colorMatches.forEach((match) => {
18+
const [, , key, value] = match.match(/(["']?)([^"'\s]+)\1\s*:\s*"#([A-Fa-f0-9]{6})"/) || [];
19+
if (key && value) {
20+
colors[key] = value.toLowerCase();
21+
}
22+
});
23+
}
24+
25+
return colors;
26+
}
27+
28+
function extractColorsFromScss(filePath: string): ColorMap {
29+
const content = fs.readFileSync(filePath, "utf-8");
30+
const colors: ColorMap = {};
31+
32+
// Extract colors from SCSS file
33+
const colorMatches = content.match(/\$([^:]+):\s*#([A-Fa-f0-9]{6})/g);
34+
35+
if (colorMatches) {
36+
colorMatches.forEach((match) => {
37+
const [, key, value] = match.match(/\$([^:]+):\s*#([A-Fa-f0-9]{6})/) || [];
38+
if (key && value) {
39+
colors[key] = value.toLowerCase();
40+
}
41+
});
42+
}
43+
44+
return colors;
45+
}
46+
47+
function compareColors(
48+
themeColors: ColorMap,
49+
scssColors: ColorMap,
50+
): {
51+
missingInScss: string[];
52+
missingInTheme: string[];
53+
mismatched: Array<{ key: string; themeValue: string; scssValue: string }>;
54+
} {
55+
const missingInScss: string[] = [];
56+
const missingInTheme: string[] = [];
57+
const mismatched: Array<{ key: string; themeValue: string; scssValue: string }> = [];
58+
59+
// Check for colors in theme but not in SCSS
60+
Object.keys(themeColors).forEach((key) => {
61+
if (!scssColors[key]) {
62+
missingInScss.push(key);
63+
} else if (themeColors[key] !== scssColors[key]) {
64+
mismatched.push({
65+
key,
66+
themeValue: themeColors[key],
67+
scssValue: scssColors[key],
68+
});
69+
}
70+
});
71+
72+
// Check for colors in SCSS but not in theme
73+
Object.keys(scssColors).forEach((key) => {
74+
if (!themeColors[key]) {
75+
missingInTheme.push(key);
76+
}
77+
});
78+
79+
return { missingInScss, missingInTheme, mismatched };
80+
}
81+
82+
function main() {
83+
const themePath = path.join(process.cwd(), "src/styles/ecer-theme.ts");
84+
const scssPath = path.join(process.cwd(), "src/styles/_colors.scss");
85+
86+
if (!fs.existsSync(themePath)) {
87+
console.error("❌ Theme file not found:", themePath);
88+
process.exit(1);
89+
}
90+
91+
if (!fs.existsSync(scssPath)) {
92+
console.error("❌ SCSS colors file not found:", scssPath);
93+
process.exit(1);
94+
}
95+
96+
console.log("🔍 Validating color consistency...\n");
97+
98+
const themeColors = extractColorsFromTheme(themePath);
99+
const scssColors = extractColorsFromScss(scssPath);
100+
101+
console.log(`📊 Found ${Object.keys(themeColors).length} colors in theme file`);
102+
console.log(`📊 Found ${Object.keys(scssColors).length} colors in SCSS file\n`);
103+
104+
const comparison = compareColors(themeColors, scssColors);
105+
106+
let hasErrors = false;
107+
108+
if (comparison.missingInScss.length > 0) {
109+
console.log("❌ Colors missing in SCSS file:");
110+
comparison.missingInScss.forEach((color) => {
111+
console.log(` - ${color}: #${themeColors[color]}`);
112+
});
113+
console.log("");
114+
hasErrors = true;
115+
}
116+
117+
if (comparison.missingInTheme.length > 0) {
118+
console.log("❌ Colors missing in theme file:");
119+
comparison.missingInTheme.forEach((color) => {
120+
console.log(` - ${color}: #${scssColors[color]}`);
121+
});
122+
console.log("");
123+
hasErrors = true;
124+
}
125+
126+
if (comparison.mismatched.length > 0) {
127+
console.log("❌ Colors with mismatched values:");
128+
comparison.mismatched.forEach(({ key, themeValue, scssValue }) => {
129+
console.log(` - ${key}: theme=#${themeValue}, scss=#${scssValue}`);
130+
});
131+
console.log("");
132+
hasErrors = true;
133+
}
134+
135+
if (hasErrors) {
136+
console.log("💡 To fix these issues:");
137+
console.log(" 1. Add missing colors to the appropriate file");
138+
console.log(" 2. Update mismatched color values to match");
139+
console.log(" 3. Run this script again to verify\n");
140+
process.exit(1);
141+
} else {
142+
console.log("✅ All colors are consistent between theme and SCSS files!");
143+
}
144+
}
145+
146+
if (require.main === module) {
147+
main();
148+
}

src/ECER.Clients.RegistryPortal/ecer.clients.registryportal.client/src/components/AcknowledgementBanner.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<v-divider :thickness="3" color="warning" class="border-opacity-100"></v-divider>
44
<v-card :rounded="'0'" flat :color="backgroundColour" :style="{ 'min-height': '100px' }" class="d-flex justify-center border-xl">
55
<v-container>
6-
<p class="align-self-center">{{ title }}</p>
6+
<p class="align-self-center white">{{ title }}</p>
77
</v-container>
88
</v-card>
99
<v-divider :thickness="3" color="warning" class="border-opacity-100"></v-divider>
Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
1-
$surface: "#38598A";
2-
$primary: "#013366";
3-
$alternate: "#1976D2";
4-
$secondary: "#38598A";
5-
$grey-dark: "#3B3A39";
6-
$grey-light: "#A19F9D";
7-
$grey-lightest: "#D2D0CE";
8-
$grey-darkest: "#5F6368";
9-
$grey-stepper: "#4F4F4F";
10-
$ash-grey: "#ADB5BD";
11-
$white-smoke: "#f8f8f8";
12-
$background-light: "#FAF9F8";
13-
$background-light-success: "#F6FFF8";
14-
$hawkes-blue: "#d9eafd";
15-
$links: "#1A5A96";
16-
$info: "#1A5A96";
17-
$error: "#D8292F";
18-
$success: "#2E8540";
19-
$warning: "#FFC72C";
20-
$warning-border: "#F8BB47";
21-
$alert-info: "#D4EAFF";
22-
$alert-warning: "#FEF1D8";
23-
$alert-error: "#F4E1E2";
24-
$alert-success: "#99ff99";
1+
$surface: #ffffff;
2+
$primary: #013366;
3+
$alternate: #1976d2;
4+
$secondary: #38598a;
5+
$grey-dark: #313231;
6+
$grey-light: #757575;
7+
$grey-lightest: #dee2e6;
8+
$grey-darkest: #5f6368;
9+
$grey-stepper: #4f4f4f;
10+
$grey-pale-background: #f2f2f2;
11+
$ash-grey: #adb5bd;
12+
$white-smoke: #f8f8f8;
13+
$background-light: #faf9f8;
14+
$background-light-success: #f6fff8;
15+
$hawkes-blue: #d9eafd;
16+
$links: #1a5a96;
17+
$info: #003366;
18+
$error: #d8292f;
19+
$success: #2e8540;
20+
$warning: #ffc72c;
21+
$warning-border: #f8bb47;
22+
$alert-info: #d4eaff;
23+
$alert-warning: #fef1d8;
24+
$alert-error: #f4e1e2;
25+
$alert-success: #99ff99;

src/ECER.Clients.RegistryPortal/ecer.clients.registryportal.client/src/styles/ecer-theme.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ const ecerTheme: ThemeDefinition = {
66
primary: "#013366",
77
alternate: "#1976D2",
88
secondary: "#38598A",
9+
surface: "#ffffff",
910
"grey-dark": "#313231",
1011
"grey-light": "#757575",
1112
"grey-lightest": "#dee2e6",
1213
"grey-darkest": "#5F6368",
14+
"grey-stepper": "#4F4F4F",
1315
"grey-pale-background": "#F2F2F2",
1416
"ash-grey": "#ADB5BD",
1517
"white-smoke": "#f8f8f8",

0 commit comments

Comments
 (0)