diff --git a/apps/website/app/fixtures/tab-wrap-rows/page.tsx b/apps/website/app/fixtures/tab-wrap-rows/page.tsx new file mode 100644 index 00000000..513143d0 --- /dev/null +++ b/apps/website/app/fixtures/tab-wrap-rows/page.tsx @@ -0,0 +1,112 @@ +"use client"; + +import { PretableSurface, type PretableColumn } from "@pretable/react"; +import { useMemo } from "react"; + +/** + * Test fixture for `apps/website/e2e/grid-tab-wrap-rows.spec.ts`. + * + * `tabBehavior="wrap-rows"` was a WCAG 2.1.2 keyboard trap: it consumed Tab + * and Shift+Tab unconditionally and clamped at the two corners, so 120 + * consecutive presses never left the grid in either engine. The fix was to + * RELEASE at the corners. Every claim the docs make about that release — that + * Tab eventually leaves forward, that Shift+Tab leaves backward, that a header + * cell leaves in one press — is a claim about a real browser's sequential + * focus order, and nothing on the docs site renders a `wrap-rows` grid to + * drive it in one. + * + * jsdom cannot stand in. It has no sequential focus order at all: `Tab` is an + * ordinary keydown there and nothing traverses unless a handler moves it by + * hand, so `packages/react/src/__tests__/tab-behavior.test.tsx` can only assert + * which presses the surface calls `preventDefault()` on. "Not prevented" and + * "focus actually left the grid" are different statements, and only the second + * one is the absence of a trap. + * + * ## Why it is laid out this way + * + * **Text inputs, not buttons, as the sentinels either side.** The exit tests + * assert *which element* focus landed on, and a bare `