From 46185d187feced7310f2a4f075bc0dbf1dc98cc3 Mon Sep 17 00:00:00 2001 From: Pouzor Date: Mon, 29 Jun 2026 01:02:00 +0200 Subject: [PATCH] fix: actually apply white export background over react-flow root The .react-flow root paints its own opaque background via colorMode, so html-to-image's backgroundColor option (which only fills transparent areas) stayed black. Override the root background with an inline style so the chosen export background is visible. Refs #165 --- frontend/src/utils/__tests__/export.test.ts | 16 ++++++++++++++++ frontend/src/utils/export.ts | 10 ++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/frontend/src/utils/__tests__/export.test.ts b/frontend/src/utils/__tests__/export.test.ts index c4dc258..f0c19ce 100644 --- a/frontend/src/utils/__tests__/export.test.ts +++ b/frontend/src/utils/__tests__/export.test.ts @@ -68,6 +68,14 @@ describe('exportToPng', () => { expect(mockToPng).toHaveBeenCalledWith(el, expect.objectContaining({ backgroundColor: '#ffffff' })) }) + it('overrides the react-flow root background via inline style so white is visible', async () => { + await exportToPng(el, 'standard', 'white') + expect(mockToPng).toHaveBeenCalledWith( + el, + expect.objectContaining({ style: expect.objectContaining({ backgroundColor: '#ffffff' }) }), + ) + }) + it('attaches the download anchor to the DOM so Firefox triggers the download', async () => { await exportToPng(el, 'high') expect(appendSpy).toHaveBeenCalled() @@ -109,6 +117,14 @@ describe('exportToSvg', () => { expect(mockToSvg).toHaveBeenCalledWith(el, expect.objectContaining({ backgroundColor: '#ffffff' })) }) + it('overrides the react-flow root background via inline style so white is visible', async () => { + await exportToSvg(el, 'white') + expect(mockToSvg).toHaveBeenCalledWith( + el, + expect.objectContaining({ style: expect.objectContaining({ backgroundColor: '#ffffff' }) }), + ) + }) + it('triggers a download', async () => { await exportToSvg(el) expect(clickSpy).toHaveBeenCalled() diff --git a/frontend/src/utils/export.ts b/frontend/src/utils/export.ts index 35d79de..f2d717b 100644 --- a/frontend/src/utils/export.ts +++ b/frontend/src/utils/export.ts @@ -25,11 +25,15 @@ export async function exportToPng( background: ExportBackground = 'dark', ): Promise { const option = EXPORT_QUALITY_OPTIONS.find((o) => o.value === quality) ?? EXPORT_QUALITY_OPTIONS[1] + const color = backgroundColor(background) const dataUrl = await toPng(element, { - backgroundColor: backgroundColor(background), + backgroundColor: color, pixelRatio: option.pixelRatio, style: { '--xy-controls-display': 'none', + // The .react-flow root paints its own opaque background (colorMode), + // which would hide the canvas backgroundColor above — override it inline. + backgroundColor: color, } as Partial, }) @@ -40,10 +44,12 @@ export async function exportToSvg( element: HTMLElement, background: ExportBackground = 'dark', ): Promise { + const color = backgroundColor(background) const dataUrl = await toSvg(element, { - backgroundColor: backgroundColor(background), + backgroundColor: color, style: { '--xy-controls-display': 'none', + backgroundColor: color, } as Partial, })