FN-8431: give report menu an opaque background

Make the report action menu render on a defined opaque surface.

- Replace undefined menu color and spacing tokens with defined design tokens.
- Add regression coverage for opaque menu surfaces and token availability.
- Add a patch changeset for the report menu fix.

Files changed:
 .changeset/fn-8431-report-menu-background.md       |  7 ++++
 .../dashboard/app/components/ReportActionMenu.css  | 40 ++++++++++++++++++++--
 .../components/__tests__/ReportActionMenu.test.tsx | 17 +++++++++
 3 files changed, 61 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-8431

Fusion-Task-Lineage: d300b5ae-272c-452d-932d-8efeee30a0d9

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
This commit is contained in:
gsxdsm
2026-07-20 09:46:22 -07:00
parent b621f29747
commit 8d216e628c
3 changed files with 61 additions and 3 deletions

View File

@@ -0,0 +1,7 @@
---
"@runfusion/fusion": patch
---
summary: Give the Report menu an opaque background so page content no longer shows through.
category: fix
dev: Replace undefined --bg-elevated/--text-primary/--bg-hover and numeric space aliases in ReportActionMenu.css with defined --card/--text/--surface-hover/--space-* tokens (FN-6862 class of bug).

View File

@@ -1,7 +1,41 @@
.report-action-menu { position: relative; } .report-action-menu { position: relative; }
.report-action-menu__list { z-index: var(--z-dropdown); display: grid; gap: var(--space-1); min-inline-size: var(--space-48); padding: var(--space-2); border-radius: var(--radius-md); background: var(--bg-elevated); box-shadow: var(--shadow-lg); }
/*
FNXC:ReportPipeline 2026-07-20-09:27:
FN-8431 replaces undefined --bg-elevated, --text-primary, --bg-hover, and numeric
spacing aliases left after FN-8406 portaled this menu. Like FN-6862's EngineControlMenu,
the shared System and Settings portal needs the defined opaque --card surface so page
content cannot show through its guided Report actions.
*/
.report-action-menu__list {
z-index: var(--z-dropdown);
display: grid;
gap: var(--space-xs);
min-inline-size: calc(var(--space-2xl) * 6);
padding: var(--space-sm);
border: 1px solid var(--border);
border-radius: var(--radius-md);
background: var(--card);
box-shadow: var(--shadow-lg);
}
.report-action-menu__list--portal { position: fixed; } .report-action-menu__list--portal { position: fixed; }
.report-action-menu__item { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-3); border: 0; border-radius: var(--radius-sm); color: var(--text-primary); background: transparent; text-align: left; }
.report-action-menu__item:hover, .report-action-menu__item:focus-visible { background: var(--bg-hover); } .report-action-menu__item {
display: flex;
align-items: center;
gap: var(--space-sm);
padding: var(--space-sm) var(--space-md);
border: 0;
border-radius: var(--radius-sm);
color: var(--text);
background: transparent;
text-align: left;
}
.report-action-menu__item:hover,
.report-action-menu__item:focus-visible { background: var(--surface-hover); }
.report-action-menu__item svg { inline-size: 1em; block-size: 1em; } .report-action-menu__item svg { inline-size: 1em; block-size: 1em; }
@media (max-width: 768px) { .report-action-menu__list--portal { right: auto !important; } } @media (max-width: 768px) { .report-action-menu__list--portal { right: auto !important; } }

View File

@@ -15,6 +15,23 @@ describe("ReportActionMenu", () => {
expect(menuStyles).toMatch(/\.report-action-menu__list--portal\s*{[^}]*position:\s*fixed/s); expect(menuStyles).toMatch(/\.report-action-menu__list--portal\s*{[^}]*position:\s*fixed/s);
}); });
it("uses defined opaque surface tokens for both shared render homes", () => {
const styles = readFileSync(join(process.cwd(), "app/styles.css"), "utf8");
const menuStyles = readFileSync(join(process.cwd(), "app/components/ReportActionMenu.css"), "utf8");
for (const token of ["card", "border", "text", "surface-hover", "space-xs", "space-sm", "space-md", "space-2xl"]) {
expect(styles).toMatch(new RegExp(`--${token}:\\s*[^;]+;`));
}
expect(menuStyles).toMatch(/\.report-action-menu__list\s*{[^}]*background:\s*var\(--card\)/s);
expect(menuStyles).toMatch(/\.report-action-menu__list\s*{[^}]*border:\s*1px solid var\(--border\)/s);
expect(menuStyles).toMatch(/\.report-action-menu__item\s*{[^}]*color:\s*var\(--text\)/s);
expect(menuStyles).toMatch(/\.report-action-menu__item:hover,\s*\.report-action-menu__item:focus-visible\s*{[^}]*background:\s*var\(--surface-hover\)/s);
for (const undefinedToken of ["bg-elevated", "text-primary", "bg-hover", "space-1", "space-2", "space-3", "space-48"]) {
expect(menuStyles).not.toMatch(new RegExp(`var\\(--${undefinedToken}\\)`));
}
});
it("exposes all four guided actions without empty controls", () => { it("exposes all four guided actions without empty controls", () => {
const onSelect = vi.fn(); const onSelect = vi.fn();
render(<ReportActionMenu onSelect={onSelect} />); render(<ReportActionMenu onSelect={onSelect} />);