Fix ARIA grid structure violations for WCAG 1.3.1 compliance#16823
Conversation
Co-authored-by: ChronosSF <2188411+ChronosSF@users.noreply.github.com>
Co-authored-by: ChronosSF <2188411+ChronosSF@users.noreply.github.com>
The ARIA spec for grid/treegrid composites defines a strict role hierarchy: grid -> rowgroup -> row -> gridcell/columnheader. This commit aligns the grid templates and components with that structure while preserving the existing keyboard navigation model. - Move role="rowgroup" from outer tbody/tfoot layout divs to the inner focus-host divs; outer wrappers receive role="presentation" — applies to grid, tree-grid, hierarchical-grid and pivot-grid - Add role="gridcell" to row-selector and drag-indicator wrappers in data rows (grid-row, tree-grid-row, hierarchical-row, groupby-row) - Add role="columnheader" to the equivalent wrappers in grid-header-row - Add role="row" to IgxGridGroupByRowComponent host (previously absent) and role="gridcell" to its toggle, content and selector children - Add role="row" to igx-grid-filtering-row host; wrap its children (input template, scroll arrows, chips area, action buttons) in role="gridcell" — scroll-arrow wrappers use display:contents to remain layout-transparent Known limitations (deferred — require structural refactoring): igx-grid-toolbar, igx-group-by-area and igx-paginator are projected via ng-content inside the grid host (role="grid"), making them owned children of the grid in the accessibility tree. Full compliance would require them to be siblings of role="grid".
|
The ARIA spec for grid/treegrid composites defines a strict role
Known limitations (deferred — require structural refactoring): |
There was a problem hiding this comment.
Pull request overview
This PR addresses WCAG 1.3.1 / aria-required-children violations by reshaping the ARIA grid ownership tree so that role="grid" elements own only row/rowgroup descendants, and non-grid UI is marked presentational.
Changes:
- Move grid header row semantics to the header-row component host (
role="rowgroup") and adjust header “action” cell roles. - Mark non-grid UI areas (toolbar, group-by area, scroll containers, footer) as
role="presentation"across grid variants. - Ensure various row “action” UI wrappers participate as proper grid cells (
role="gridcell"), and adjust body/footer rowgroup placement.
Reviewed changes
Copilot reviewed 15 out of 16 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| projects/igniteui-angular/grids/tree-grid/src/tree-grid.component.html | Adjusts body/tfoot/scroll/footer roles to avoid invalid grid-owned roles. |
| projects/igniteui-angular/grids/tree-grid/src/tree-grid-row.component.html | Adds role="gridcell" to row action wrappers (drag/selector). |
| projects/igniteui-angular/grids/tree-grid/src/tree-grid-group-by-area.component.ts | Sets group-by area host role="presentation". |
| projects/igniteui-angular/grids/pivot-grid/src/pivot-grid.component.html | Adjusts body/scroll/tfoot/footer roles for pivot grid. |
| projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-row.component.html | Adds role="gridcell" to row action wrappers (drag/selector). |
| projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.component.html | Adjusts body/tfoot/scroll/footer roles to avoid invalid grid-owned roles. |
| projects/igniteui-angular/grids/grid/src/groupby-row.component.ts | Adds host role="row" and changes where expanded state is exposed. |
| projects/igniteui-angular/grids/grid/src/groupby-row.component.html | Adds role="gridcell" wrappers and relocates aria-expanded. |
| projects/igniteui-angular/grids/grid/src/grid.component.html | Adjusts body/tfoot/scroll/footer roles and moves rowgroup responsibility to tbody-content. |
| projects/igniteui-angular/grids/grid/src/grid-row.component.html | Adds role="gridcell" to row action wrappers (drag/selector). |
| projects/igniteui-angular/grids/core/src/toolbar/grid-toolbar.component.ts | Sets toolbar host role="presentation". |
| projects/igniteui-angular/grids/core/src/headers/grid-header-row.component.ts | Sets header-row host role="rowgroup". |
| projects/igniteui-angular/grids/core/src/headers/grid-header-row.component.html | Removes inner rowgroup role and adds header action cell roles. |
| projects/igniteui-angular/grids/core/src/grouping/grid-group-by-area.component.ts | Sets group-by area host role="presentation". |
| projects/igniteui-angular/grids/core/src/filtering/base/grid-filtering-cell.component.ts | Sets filtering cell host role="gridcell". |
| package-lock.json | Lockfile metadata changes (appears unrelated to ARIA work). |
You can also share your feedback on Copilot code review. Take the survey.
|
@viktorkombov , thank you! Please clean up the PR (resolve conflicts) and address or dismiss Copilot comments then I can verify it and communicate with the user who reported it. |
…into copilot/fix-accessibility-issues
…tion or class' Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
| * @internal | ||
| */ | ||
| @HostBinding('attr.role') | ||
| public role = 'presentation'; |
There was a problem hiding this comment.
can be added to IgxGroupByAreaDirective instead
There was a problem hiding this comment.
Done. Moved role="presentation" binding to IgxGroupByAreaDirective base class in commit 6d571a0.
| * @internal | ||
| */ | ||
| @HostBinding('attr.role') | ||
| public role = 'presentation'; |
There was a problem hiding this comment.
can be added to IgxGroupByAreaDirective instead
There was a problem hiding this comment.
Done. Moved role="presentation" binding to IgxGroupByAreaDirective base class in commit 6d571a0.
Co-authored-by: ChronosSF <2188411+ChronosSF@users.noreply.github.com>
Fix ARIA accessibility issues in igx-grid component
Summary
This PR fixes WCAG 1.3.1 accessibility violations (aria-required-children) in all grid components. The changes ensure that elements with
role="grid"only have direct children with allowed ARIA roles (roworrowgroup) per the ARIA specification.Changes:
role="rowgroup"to header row componentsrole="presentation"to baseIgxGroupByAreaDirective(inherited by grid and tree-grid variants)role="presentation"to toolbar componentrole="presentation"to scroll and footer containersOriginal prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.