From 3e1607471b1b9f48a380debd9df93ac7d9affdb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Sun, 10 May 2026 10:16:56 +0200 Subject: [PATCH] fix(admin): suppress painted scrollbar on mobile section strip Production probe at /admin/api-tokens on a Pixel-5 viewport pinned the scrollbar that kept showing up after two earlier fixes: it lives in the AdminShell mobile section strip (13 entries, scrollWidth ~1700 vs clientWidth ~360), not in the api-tokens table. The strip sits right above the api-tokens card, which is why every previous attempt targeted the table while the bar stayed put. Adds a `no-scrollbar` utility in globals.css (scrollbar-width: none + ::-webkit-scrollbar { display: none }) and applies it to the strip in both AdminShell and SettingsShell. Swipe and keyboard-arrow scrolling keep working; the painted bar simply doesn't draw. New AdminShell unit suite locks in the class so a future refactor can't silently regress it; settings-shell test gets the matching assertion. The api-tokens e2e spec gains a regression check that the strip declares `no-scrollbar` and overflow-x-auto together. Co-Authored-By: Claude Opus 4.7 (1M context) --- e2e/admin-api-tokens-mobile.spec.ts | 44 ++++++++ src/app/globals.css | 23 ++++ .../admin/__tests__/admin-shell.test.tsx | 100 ++++++++++++++++++ src/components/admin/admin-shell.tsx | 10 +- .../__tests__/settings-shell.test.tsx | 14 +++ src/components/settings/settings-shell.tsx | 10 +- 6 files changed, 197 insertions(+), 4 deletions(-) create mode 100644 src/components/admin/__tests__/admin-shell.test.tsx diff --git a/e2e/admin-api-tokens-mobile.spec.ts b/e2e/admin-api-tokens-mobile.spec.ts index 2dc10878d..edddc1e8f 100644 --- a/e2e/admin-api-tokens-mobile.spec.ts +++ b/e2e/admin-api-tokens-mobile.spec.ts @@ -74,4 +74,48 @@ test.describe("/admin/api-tokens mobile no-overflow", () => { `scrollWidth=${dims.scrollWidth}, innerWidth=${dims.innerWidth}`, ).toBeLessThanOrEqual(dims.innerWidth + 1); }); + + // v1.4.18 phase A2 — production probe at Pixel-5 viewport pinned the + // visible "scrollbar" Marc reported for the third time as the + // `` mobile section strip, NOT the api-tokens table. The + // strip carries 13 admin sections so its scrollWidth (~1700 CSS px) + // permanently exceeds clientWidth (~360 CSS px). Adding the + // `no-scrollbar` utility class (`globals.css`) suppresses the + // painted bar while preserving swipe + keyboard-arrow scrolling. + // This regression guard fails if a future refactor drops the class. + test("Pixel-5 viewport: admin section strip suppresses its painted scrollbar", async ({ + page, + }) => { + await page.route("**/api/admin/tokens", (route) => + route.fulfill({ + status: 200, + contentType: "application/json", + body: JSON.stringify({ data: [], error: null }), + }), + ); + + await page.goto("/admin/api-tokens", { waitUntil: "domcontentloaded" }); + await page.waitForLoadState("networkidle"); + + // Find the mobile strip (`