fix(a11y): keep a tabbable row in every AG-Grid table after scrolling (#14664)
AG-Grid tables use a roving tabindex: exactly one row carries tabindex="0" so keyboard users can enter the grid. The shared wrapper assigned that tab stop in patchTabbableRow(), but only scheduled the patch on gridReady, firstDataRendered and paginationChanged. Row virtualization is scroll-driven and fires none of those, so once the tab-stop row was recycled out of the DOM nothing reassigned it — the grid ended with zero tabbable descendants and could not be entered from the keyboard at all, and did not recover on scrolling back. - re-run the accessibility patch on viewportChanged (the rendered row window moved) and modelUpdated (sort/filter/data re-renders, which had the same hole); the patch is already rAF-debounced so the scroll path stays cheap - pick the tab stop by the lowest row-index instead of DOM position: ensureDomOrder is the wrapper default but consumers can override it via gridOptions, and without it DOM order stops tracking visual order - grid-tabbable-row.spec.ts: scroll a 250-row grid through its full range and assert the tab stop survives, plus a keyboard-entry and arrow-navigation pass; both fail on release-1.12.0 and pass here - four unit tests for the recycled-window, out-of-order-DOM and missing row-index cases Clears the IBM aria_child_tabbable violation (WCAG 2.1.1) on /settings/messages. Row 2.1.1 also needs the canvas keyboard work, so the compliance form is unchanged.
V
Viktor Avelino committed
eae812a86ee99b163132a045a27f95ac87aa768c
Parent: 8806782
Committed by GitHub <noreply@github.com>
on 8/19/2026, 8:41:49 PM