From bfe52930bf594e7e1978930080a741c9accf2ed5 Mon Sep 17 00:00:00 2001 From: Neil Goldader Date: Sun, 13 Sep 2026 19:17:14 -0400 Subject: [PATCH 1/3] fix: let desktop stats scroll with the page --- e2e/tests/season-schedule.spec.ts | 16 ++++++++++++++++ src/components/dialogs/GameStatsDialog.tsx | 4 ++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/e2e/tests/season-schedule.spec.ts b/e2e/tests/season-schedule.spec.ts index 75bc0b2..8af2321 100644 --- a/e2e/tests/season-schedule.spec.ts +++ b/e2e/tests/season-schedule.spec.ts @@ -184,6 +184,22 @@ test.describe("Season schedules", () => { await expect(page.getByRole("tab", { name: "Stats" })).toBeVisible(); }); + test("scrolls the page over expanded desktop momentum stats", async ({ page }) => { + await page.setViewportSize({ width: 1440, height: 900 }); + await page.goto("/"); + await page.getByTestId("live-dashboard-game-401873297").click(); + const panel = page.getByTestId("game-stats-panel"); + await panel.getByRole("tab", { name: "Momentum" }).click(); + const content = panel.getByRole("tabpanel"); + await expect(content.getByText("Win Probability Over Time")).toBeVisible(); + await content.hover(); + const before = await page.evaluate(() => window.scrollY); + await page.mouse.wheel(0, 500); + await expect.poll(() => page.evaluate(() => window.scrollY)).toBeGreaterThan(before); + await page.mouse.wheel(0, -500); + await expect.poll(() => page.evaluate(() => window.scrollY)).toBeLessThanOrEqual(before); + }); + test("keeps the field visible between drives on wide screens", async ({ page }) => { await page.unroute("**/api/game-stats/**"); await page.route("**/api/game-stats/**", async (route) => { diff --git a/src/components/dialogs/GameStatsDialog.tsx b/src/components/dialogs/GameStatsDialog.tsx index 3723aeb..47e6b73 100644 --- a/src/components/dialogs/GameStatsDialog.tsx +++ b/src/components/dialogs/GameStatsDialog.tsx @@ -349,8 +349,8 @@ export function GameStatsDialog({ id={`tabpanel-${activeTab}`} aria-labelledby={`tab-${activeTab}`} className={cn( - "overflow-y-auto overscroll-contain px-4 py-4 md:px-6 md:py-5", - variant === "dialog" ? "min-h-0 flex-1" : "max-h-[calc(90vh-180px)]", + "px-4 py-4 md:px-6 md:py-5", + variant === "dialog" && "min-h-0 flex-1 overflow-y-auto overscroll-contain", )} > {isLoading && !stats ? ( From dbed712a20171f7192e82e13a4a1d82eed8cf2dc Mon Sep 17 00:00:00 2001 From: Neil Goldader Date: Sun, 13 Sep 2026 19:42:38 -0400 Subject: [PATCH 2/3] fix: preserve sticky sidebar during page scroll --- e2e/tests/season-schedule.spec.ts | 2 ++ src/app/globals.css | 8 ++++---- src/app/page.tsx | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/e2e/tests/season-schedule.spec.ts b/e2e/tests/season-schedule.spec.ts index 8af2321..3a10130 100644 --- a/e2e/tests/season-schedule.spec.ts +++ b/e2e/tests/season-schedule.spec.ts @@ -192,10 +192,12 @@ test.describe("Season schedules", () => { await panel.getByRole("tab", { name: "Momentum" }).click(); const content = panel.getByRole("tabpanel"); await expect(content.getByText("Win Probability Over Time")).toBeVisible(); + const sidebar = page.getByTestId("schedule-sidebar"); await content.hover(); const before = await page.evaluate(() => window.scrollY); await page.mouse.wheel(0, 500); await expect.poll(() => page.evaluate(() => window.scrollY)).toBeGreaterThan(before); + await expect.poll(async () => (await sidebar.boundingBox())!.y).toBeGreaterThanOrEqual(23); await page.mouse.wheel(0, -500); await expect.poll(() => page.evaluate(() => window.scrollY)).toBeLessThanOrEqual(before); }); diff --git a/src/app/globals.css b/src/app/globals.css index 4ff90a8..e929da1 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -121,14 +121,14 @@ @apply border-border outline-ring/50; } html { - /* Prevent horizontal scroll and overscroll bounce on mobile */ - overflow-x: hidden; + /* Clip horizontal overflow without creating a scroll container that breaks sticky layout. */ + overflow-x: clip; overscroll-behavior-x: none; } body { @apply bg-background text-foreground; - /* Prevent horizontal scroll and overscroll bounce on mobile */ - overflow-x: hidden; + /* Clip horizontal overflow without creating a scroll container that breaks sticky layout. */ + overflow-x: clip; overscroll-behavior-x: none; /* Prevent pull-to-refresh and overscroll effects */ overscroll-behavior-y: contain; diff --git a/src/app/page.tsx b/src/app/page.tsx index e5bd45b..c5b2991 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -106,7 +106,7 @@ function BracketApp() {
Date: Sun, 13 Sep 2026 20:50:12 -0400 Subject: [PATCH 3/3] test: position wheel target before page bottom --- e2e/tests/season-schedule.spec.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/e2e/tests/season-schedule.spec.ts b/e2e/tests/season-schedule.spec.ts index 3a10130..898cdad 100644 --- a/e2e/tests/season-schedule.spec.ts +++ b/e2e/tests/season-schedule.spec.ts @@ -193,7 +193,13 @@ test.describe("Season schedules", () => { const content = panel.getByRole("tabpanel"); await expect(content.getByText("Win Probability Over Time")).toBeVisible(); const sidebar = page.getByTestId("schedule-sidebar"); - await content.hover(); + // Hovering the whole tall panel can scroll Firefox to the document bottom. + // Position its top within the viewport, leaving room to wheel downward. + await content.evaluate((element) => { + window.scrollTo(0, element.getBoundingClientRect().top + window.scrollY - 600); + }); + const contentBox = await content.boundingBox(); + await page.mouse.move(contentBox!.x + 20, contentBox!.y + 20); const before = await page.evaluate(() => window.scrollY); await page.mouse.wheel(0, 500); await expect.poll(() => page.evaluate(() => window.scrollY)).toBeGreaterThan(before);