From 9f0d3f3cf4dc4222415c32b9580e1ad2c8369bd1 Mon Sep 17 00:00:00 2001 From: Deluan Date: Tue, 2 Dec 2025 16:14:01 -0500 Subject: [PATCH] fix(ui): sync body background color with theme Set document.body.style.backgroundColor to match the current theme's background color whenever the theme changes. This fixes the white background that appeared during pull-to-refresh gestures on mobile or overscroll on desktop, where the browser reveals the area behind the app content. The background color is determined by the theme's palette.background.default value if defined, otherwise falls back to Material-UI defaults (#303030 for dark themes, #fafafa for light themes). Signed-off-by: Deluan --- ui/src/themes/useCurrentTheme.js | 6 ++++ ui/src/themes/useCurrentTheme.test.jsx | 44 ++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/ui/src/themes/useCurrentTheme.js b/ui/src/themes/useCurrentTheme.js index 9793d1e15..0d986033d 100644 --- a/ui/src/themes/useCurrentTheme.js +++ b/ui/src/themes/useCurrentTheme.js @@ -42,6 +42,12 @@ const useCurrentTheme = () => { document.head.removeChild(style) } } + + // Set body background color to match theme (fixes white background on pull-to-refresh) + const isDark = theme.palette?.type === 'dark' + const bgColor = + theme.palette?.background?.default || (isDark ? '#303030' : '#fafafa') + document.body.style.backgroundColor = bgColor }, [theme]) return theme diff --git a/ui/src/themes/useCurrentTheme.test.jsx b/ui/src/themes/useCurrentTheme.test.jsx index 03775d34f..65c3be8c6 100644 --- a/ui/src/themes/useCurrentTheme.test.jsx +++ b/ui/src/themes/useCurrentTheme.test.jsx @@ -15,6 +15,10 @@ function createMatchMedia(theme) { }) } +beforeEach(() => { + document.body.style.backgroundColor = '' +}) + describe('useCurrentTheme', () => { describe('with user preference theme as light', () => { beforeAll(() => { @@ -117,4 +121,44 @@ describe('useCurrentTheme', () => { expect(result.current.themeName).toMatch('Spotify-ish') }) }) + describe('body background color', () => { + beforeAll(() => { + window.matchMedia = createMatchMedia('dark') + }) + it('sets body background for dark theme', () => { + renderHook(() => useCurrentTheme(), { + wrapper: ({ children }) => ( + + {children} + + ), + }) + // Dark theme uses MUI default dark background + expect(document.body.style.backgroundColor).toBe('rgb(48, 48, 48)') + }) + it('sets body background for light theme', () => { + renderHook(() => useCurrentTheme(), { + wrapper: ({ children }) => ( + + {children} + + ), + }) + // Light theme uses MUI default light background + expect(document.body.style.backgroundColor).toBe('rgb(250, 250, 250)') + }) + it('sets body background for theme with custom background', () => { + renderHook(() => useCurrentTheme(), { + wrapper: ({ children }) => ( + + {children} + + ), + }) + // Spotify theme has explicit background.default: #121212 + expect(document.body.style.backgroundColor).toBe('rgb(18, 18, 18)') + }) + }) })