Accessibility in Apex Grid
The Apex grid ships ARIA semantics and keyboard affordances that follow the WCAG 2.2 AA grid pattern. Screen readers see the component as a tabular structure (or a tree-grid in tree-data mode); keyboard users can navigate, sort, expand, select, and edit without reaching for a pointer.
ARIA semantics
The host element advertises:
role="grid"(orrole="treegrid"in tree-data mode).aria-rowcountandaria-colcountreflecting the live shape: counts include the header row, the filter row when enabled, and any auto-added selection or expansion columns.
Header, filter, and body rows carry role="row" with aria-rowindex. Column headers carry role="columnheader" with aria-colindex plus aria-sort reflecting the per-column sort state. Cells carry role="gridcell" with aria-colindex and aria-current on the active cell. Body rows reflect aria-selected when selection is enabled and aria-expanded when row expansion or tree-data is enabled.
The grid host also gets a localized aria-label ("Data grid") unless you supply your own aria-label / aria-labelledby, and reflects aria-multiselectable when multi-row selection is enabled. The filter condition trigger advertises aria-haspopup="listbox" with aria-expanded; the sort indicator is a real <button> with a descriptive aria-label and focus-visible styling.
Roving-tabindex focus model
The grid body is a single tab stop: Tab enters the grid, and the active cell holds real focus (a roving tabindex), so screen readers follow the cursor as it moves cell to cell. A keyboard-driven commit or cancel returns focus to the cell host, so navigation continues from where you were, and pointer exits never steal focus from the click target. Dialogs and menus (the AI panel, context menu) remember the deep-focused element across shadow roots and restore focus on close.
Polite live announcements
The grid renders a polite aria-live region. Sorting, filtering, selection, paging, row pinning, row reorder, expansion, and undo / redo all announce themselves through it, and every announcement (plus the header control labels and sort-state descriptions) is localizable through the announce.* and header.* locale keys. The status bar is itself a polite live region. Custom UI can post messages to the same channel:
grid.announce('Filter applied, 12 rows visible');
announce(message) debounces consecutive messages and prevents duplicates from overlapping the user's own actions.
Keyboard navigation
The grid follows the WCAG 2.2 AA grid keyboard pattern:
- Arrow keys move the active cell.
- Home / End jump to the first / last cell in the row; Ctrl/Cmd+Home / Ctrl/Cmd+End jump to the corner of the grid.
- PageUp / PageDown move by a viewport page.
- Space toggles the focused row's selection; Shift+Space extends from the anchor; Ctrl+A selects all in multiple-selection mode.
- Enter or F2 opens the active cell's inline editor.
- Escape cancels an open editor; Tab commits and moves focus out of the cell.
- Ctrl/Cmd+Z / Ctrl/Cmd+Y undo / redo when editing history is enabled.
Changed in 3.4.0: Home / End used to jump to the first / last row; they now stay within the row (the common data-grid convention). Use Ctrl/Cmd+Home / Ctrl/Cmd+End for the grid corners. Enter / F2 keyboard editing is new in 3.4.0 (editing was previously pointer-only).
Touch targets
Sort buttons, expansion chevrons, and filter chip-remove controls are sized to at least 24×24 CSS pixels to satisfy WCAG 2.5.8 (Target Size: Minimum).