/** * A sideways-scrolling table wrapper is a positioned box. * * Screen-reader text (`sr-only`) is absolutely positioned. Inside a scroll * container that is not positioned, its containing block is an ancestor * outside the container, so it escapes the container's clipping, and a cell * panned past the phone's edge widens the whole page: the admin login * overview scrolled sideways at 390 px once its IP button gained screen-reader * text. Every `overflow-x-auto` wrapper around a table therefore carries * `relative`, which makes it the containing block of what it scrolls. */ import { join } from "node:path"; import { describe, expect, it } from "vitest"; import { readSourceText, walkSourceFiles } from "./helpers/source-files"; const SRC = join(process.cwd(), "src"); /** `file:line` of each table wrapper that scrolls without being positioned. */ function offenders(rel: string, text: string): string[] { if (!text.includes(" { if (!/"[^"]*\boverflow-x-auto\b[^"]*"/.test(line)) return; if (/^\s*(\*|\/\/)/.test(line)) return; const window = lines.slice(index, index + 8).join("\n"); if (window.includes(" { const files = walkSourceFiles(SRC, { floor: 1500 }).filter( (rel) => rel.endsWith(".tsx") && !rel.includes("__tests__") && !rel.startsWith("generated/"), ); it("reads the wrappers it claims to check", () => { const wrappers = files.filter((rel) => { const text = readSourceText(join(SRC, rel)); return text.includes(" { const found = files.flatMap((rel) => offenders(rel, readSourceText(join(SRC, rel))), ); expect(found).toEqual([]); }); it("catches the shape it guards against", () => { const bad = ['
', " "].join("\n"); expect(offenders("x.tsx", bad)).toEqual(["x.tsx:1"]); const good = ['
', "
"].join( "\n", ); expect(offenders("x.tsx", good)).toEqual([]); }); });