From bb7b5bd6d833ea1252f4d8a530c738067d7568e5 Mon Sep 17 00:00:00 2001 From: nmemmert <67961292+nmemmert@users.noreply.github.com> Date: Tue, 29 Sep 2026 11:32:26 -0400 Subject: [PATCH] Start every page at the top The scroll position of the previous page used to carry over, which on iPad makes the system blur the app bar when content is scrolled under it. Co-Authored-By: Claude Sonnet 5.5 --- src/App.jsx | 6 ++++++ src/App.test.jsx | 16 ++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/App.jsx b/src/App.jsx index 6cb7586..bb1793c 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -60,6 +60,12 @@ const App = () => { const reader = useBibleReader(currentPage, readerPlanProgress?.translation ?? null); const audio = useAudio(reader.readerBookAbbrev, reader.readerChapter, reader.readerTranslation); useEffect(() => { if (currentPage !== 'reader') setReaderPlan(null); }, [currentPage]); + // A new page starts at the top. Without this the scroll position of the previous page carries over, and on + // iPad content scrolled under the top edge makes the system blur the app bar. + useEffect(() => { + const scroller = document.scrollingElement ?? document.documentElement; + if (scroller) scroller.scrollTop = 0; + }, [currentPage]); // Keep the browser/OS chrome (status bar area, overscroll, scrollbars) in the chosen theme useEffect(() => { applySystemChrome(reader.readerTheme); }, [reader.readerTheme]); const { authUser, setAuthUser, authServerDown, signIn, logout } = useAuth({ diff --git a/src/App.test.jsx b/src/App.test.jsx index c4548ac..50fc767 100644 --- a/src/App.test.jsx +++ b/src/App.test.jsx @@ -1420,3 +1420,19 @@ describe('System chrome follows the theme', () => { expect(document.documentElement.style.colorScheme).toBe('light'); }); }); + +describe('New pages start at the top', () => { + test('moving to another page resets the scroll position', async () => { + const user = userEvent.setup(); + await renderApp(); + const scroller = document.scrollingElement ?? document.documentElement; + scroller.scrollTop = 480; // scrolled down on the dashboard + await user.click(screen.getByRole('button', { name: /reading plans/i })); + await screen.findByRole('heading', { name: /^reading plans$/i }); + expect(scroller.scrollTop).toBe(0); + scroller.scrollTop = 300; + await user.click(screen.getByRole('button', { name: /back to home/i })); + await screen.findByText('My Studies'); + expect(scroller.scrollTop).toBe(0); + }); +});