FN-8269: replace raw white component colors with tokens
Replace component-level white literals with semantic dashboard tokens and protect the pattern with a hygiene regression scan. - Add semantic tokens for workflow chip foregrounds and HTML preview canvases - Apply the tokens to workflow and artifact gallery component CSS - Extend CSS hygiene coverage and add a patch changeset Files changed: .changeset/fn-8269-fff-tokens.md | 7 +++++++ .../dashboard/app/__tests__/css-hygiene-scan.test.ts | 20 +++++++++++++++++++- .../dashboard/app/components/ArtifactsGallery.css | 4 ++-- .../app/components/WorkflowAddStepModal.css | 3 ++- .../app/components/WorkflowSimpleCanvas.css | 3 ++- packages/dashboard/app/styles.css | 13 +++++++++++++ 6 files changed, 45 insertions(+), 5 deletions(-) Fusion-Task-Id: FN-8269 Fusion-Task-Lineage: 5128286d-cdcf-4c9b-b097-e7eaed7d1713 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
This commit is contained in:
7
.changeset/fn-8269-fff-tokens.md
Normal file
7
.changeset/fn-8269-fff-tokens.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
"@runfusion/fusion": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
summary: Keep workflow chips and HTML mockup previews visually consistent across themes.
|
||||||
|
category: fix
|
||||||
|
dev: Replace component-level raw white values with explicit workflow-chip and preview-page semantic tokens, protected by the dashboard CSS hygiene scan.
|
||||||
@@ -3,6 +3,7 @@ import { readFileSync } from "node:fs";
|
|||||||
import { join, resolve } from "node:path";
|
import { join, resolve } from "node:path";
|
||||||
|
|
||||||
const componentsDir = resolve(__dirname, "../components");
|
const componentsDir = resolve(__dirname, "../components");
|
||||||
|
const stylesPath = resolve(__dirname, "../styles.css");
|
||||||
|
|
||||||
const recentlyLandedResponsiveFiles = [
|
const recentlyLandedResponsiveFiles = [
|
||||||
"PluginManager.css",
|
"PluginManager.css",
|
||||||
@@ -20,10 +21,20 @@ const recentlyLandedHygieneFiles = [
|
|||||||
"TaskFieldsSection.css",
|
"TaskFieldsSection.css",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const tokenizedWhiteFiles = [
|
||||||
|
"ArtifactsGallery.css",
|
||||||
|
"WorkflowSimpleCanvas.css",
|
||||||
|
"WorkflowAddStepModal.css",
|
||||||
|
];
|
||||||
|
|
||||||
function readComponentCss(name: string): string {
|
function readComponentCss(name: string): string {
|
||||||
return readFileSync(join(componentsDir, name), "utf-8");
|
return readFileSync(join(componentsDir, name), "utf-8");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function readStylesCss(): string {
|
||||||
|
return readFileSync(stylesPath, "utf-8");
|
||||||
|
}
|
||||||
|
|
||||||
function linesWith(source: string, predicate: (line: string) => boolean): string[] {
|
function linesWith(source: string, predicate: (line: string) => boolean): string[] {
|
||||||
return source
|
return source
|
||||||
.split("\n")
|
.split("\n")
|
||||||
@@ -90,9 +101,16 @@ describe("component CSS hygiene scan regressions", () => {
|
|||||||
expect(findings).toEqual([]);
|
expect(findings).toEqual([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("defines semantic tokens for always-white workflow chips and preview canvases", () => {
|
||||||
|
const styles = readStylesCss();
|
||||||
|
|
||||||
|
expect(styles).toContain("--workflow-chip-foreground: #ffffff;");
|
||||||
|
expect(styles).toContain("--preview-page-bg: #ffffff;");
|
||||||
|
});
|
||||||
|
|
||||||
it("does not use hardcoded hex colors outside token fallback patterns in scanned recent CSS", () => {
|
it("does not use hardcoded hex colors outside token fallback patterns in scanned recent CSS", () => {
|
||||||
const hexPattern = /#[0-9a-fA-F]{3,8}\b/;
|
const hexPattern = /#[0-9a-fA-F]{3,8}\b/;
|
||||||
const findings = recentlyLandedHygieneFiles.flatMap((file) =>
|
const findings = [...recentlyLandedHygieneFiles, ...tokenizedWhiteFiles].flatMap((file) =>
|
||||||
linesWith(
|
linesWith(
|
||||||
readComponentCss(file),
|
readComponentCss(file),
|
||||||
(line) => hexPattern.test(line) && !line.includes("var(--")
|
(line) => hexPattern.test(line) && !line.includes("var(--")
|
||||||
|
|||||||
@@ -429,14 +429,14 @@ The artifacts viewer is a headerless FloatingWindow, so this header is the deleg
|
|||||||
background: var(--surface);
|
background: var(--surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* HTML mockup live preview; white canvas because agent mockups usually assume a page background. */
|
/* FNXC:DashboardPreviewCanvas 2026-07-18-04:07: HTML mockup previews retain a white canvas across themes because agent mockups assume a light page background. */
|
||||||
.artifacts-gallery-viewer-html {
|
.artifacts-gallery-viewer-html {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
min-height: 20rem;
|
min-height: 20rem;
|
||||||
border: thin solid var(--border);
|
border: thin solid var(--border);
|
||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
background: #fff;
|
background: var(--preview-page-bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.artifacts-gallery-viewer-doc {
|
.artifacts-gallery-viewer-doc {
|
||||||
|
|||||||
@@ -137,7 +137,8 @@ the same dialog serves both breakpoints.
|
|||||||
width: 30px;
|
width: 30px;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
border-radius: var(--radius-md);
|
border-radius: var(--radius-md);
|
||||||
color: #fff;
|
/* FNXC:DashboardTokenHygiene 2026-07-18-04:07: Colored workflow-status chips require an always-white foreground, not theme-variant --accent-text. */
|
||||||
|
color: var(--workflow-chip-foreground);
|
||||||
background: var(--surface-emphasis);
|
background: var(--surface-emphasis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,8 @@ Simplified workflow view styling. Requirements encoded here:
|
|||||||
width: 32px;
|
width: 32px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
border-radius: var(--radius-md);
|
border-radius: var(--radius-md);
|
||||||
color: #fff;
|
/* FNXC:DashboardTokenHygiene 2026-07-18-04:07: Colored workflow-status chips require an always-white foreground, not theme-variant --accent-text. */
|
||||||
|
color: var(--workflow-chip-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Node family accents (icon chip background + a subtle left accent). */
|
/* Node family accents (icon chip background + a subtle left accent). */
|
||||||
|
|||||||
@@ -497,6 +497,19 @@ svg.spinning {
|
|||||||
/* Foreground for content rendered on `--accent` (e.g., user chat bubble, primary FAB icon). Choose a value with WCAG AA contrast against the paired `--accent` in the same block. */
|
/* Foreground for content rendered on `--accent` (e.g., user chat bubble, primary FAB icon). Choose a value with WCAG AA contrast against the paired `--accent` in the same block. */
|
||||||
--accent-text: #ffffff;
|
--accent-text: #ffffff;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FNXC:DashboardTokenHygiene 2026-07-18-04:07:
|
||||||
|
* Workflow-status step chips use --ws-*, --color-merged, and --triage backgrounds.
|
||||||
|
* Their foreground must remain white across themes, unlike --accent-text, which only pairs with --accent and may be theme-variant.
|
||||||
|
*/
|
||||||
|
--workflow-chip-foreground: #ffffff;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FNXC:DashboardPreviewCanvas 2026-07-18-04:07:
|
||||||
|
* Agent HTML mockups assume a light page background, so this canvas stays white in every theme.
|
||||||
|
*/
|
||||||
|
--preview-page-bg: #ffffff;
|
||||||
|
|
||||||
/* === Log Entry Background Tokens === */
|
/* === Log Entry Background Tokens === */
|
||||||
--log-tool-bg: color-mix(in srgb, var(--accent) 8%, transparent);
|
--log-tool-bg: color-mix(in srgb, var(--accent) 8%, transparent);
|
||||||
--log-success-bg: color-mix(in srgb, var(--color-success) 6%, transparent);
|
--log-success-bg: color-mix(in srgb, var(--color-success) 6%, transparent);
|
||||||
|
|||||||
Reference in New Issue
Block a user