Skip to content

Commit 85a7e45

Browse files
authored
fix(material-experimental/mdc-paginator): target page size label with aria-labelledby (#23172)
Fixes a screenrader bug on the mdc-paginator for the page size combobox ("Items per page: [combo]"). On Firefox, JAWS and NVDA do not read the value of the combobox, and only read the label. This happens because the mdc-paginator explicitly sets an `aria-label` on the `mdc-select` for the page size label. This causes the mdc-select to not apply an aria-labelledby, which would reference the value of the combobox. This leaves us with only relying on inner text to read the value of the combobox and not having an aria-label or labelledby to read it. This PR corrects that behavior by refering the existing page size label using `aria-labelledby`, and not setting an `aria-label`. The mdc-select will append a reference to the value of the combobox to the aria-lablledby. This gives us a list of ids of both the label and the value of the combobox. That way we can be sure that all screenreaders (including Windows screenreaders) will read both the value and label of the combobox.
1 parent 30e9205 commit 85a7e45

File tree

3 files changed

+15
-4
lines changed

3 files changed

+15
-4
lines changed

src/material-experimental/mdc-paginator/paginator.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<div class="mat-mdc-paginator-outer-container">
22
<div class="mat-mdc-paginator-container">
33
<div class="mat-mdc-paginator-page-size" *ngIf="!hidePageSize">
4-
<div class="mat-mdc-paginator-page-size-label">
4+
<div class="mat-mdc-paginator-page-size-label" id="{{_pageSizeLabelId}}">
55
{{_intl.itemsPerPageLabel}}
66
</div>
77

@@ -13,7 +13,7 @@
1313
<mat-select
1414
[value]="pageSize"
1515
[disabled]="disabled"
16-
[aria-label]="_intl.itemsPerPageLabel"
16+
[aria-labelledby]="_pageSizeLabelId"
1717
(selectionChange)="_changePageSize($event.value)">
1818
<mat-option *ngFor="let pageSizeOption of _displayedPageSizeOptions" [value]="pageSizeOption">
1919
{{pageSizeOption}}

src/material-experimental/mdc-paginator/paginator.spec.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,16 @@ describe('MDC-based MatPaginator', () => {
7373

7474
it('should show right aria-labels for select and buttons', () => {
7575
const fixture = createComponent(MatPaginatorApp);
76-
const select = fixture.nativeElement.querySelector('.mat-mdc-select');
77-
expect(select.getAttribute('aria-label')).toBe('Items per page:');
7876

7977
expect(getPreviousButton(fixture).getAttribute('aria-label')).toBe('Previous page');
8078
expect(getNextButton(fixture).getAttribute('aria-label')).toBe('Next page');
79+
80+
const select = fixture.nativeElement.querySelector('.mat-mdc-select');
81+
const selectLabelIds = select.getAttribute('aria-labelledby')?.split(/\s/g) as string[];
82+
const selectLabelTexts = selectLabelIds?.map(labelId => {
83+
return fixture.nativeElement.querySelector(`#${labelId}`)?.textContent?.trim();
84+
});
85+
expect(selectLabelTexts).toContain('Items per page:');
8186
});
8287

8388
it('should re-render when the i18n labels change', () => {

src/material-experimental/mdc-paginator/paginator.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ export interface MatPaginatorDefaultOptions {
4444
export const MAT_PAGINATOR_DEFAULT_OPTIONS =
4545
new InjectionToken<MatPaginatorDefaultOptions>('MAT_PAGINATOR_DEFAULT_OPTIONS');
4646

47+
let nextUniqueId = 0;
48+
4749
/**
4850
* Component to provide navigation between paged information. Displays the size of the current
4951
* page, user-selectable options to change that size, what items are being shown, and
@@ -66,6 +68,10 @@ export class MatPaginator extends _MatPaginatorBase<MatPaginatorDefaultOptions>
6668
/** If set, styles the "page size" form field with the designated style. */
6769
_formFieldAppearance?: MatFormFieldAppearance;
6870

71+
/** ID for the DOM node containing the pagiators's items per page label. */
72+
readonly _pageSizeLabelId = `mat-paginator-page-size-label-${nextUniqueId++}`;
73+
74+
6975
constructor(intl: MatPaginatorIntl,
7076
changeDetectorRef: ChangeDetectorRef,
7177
@Optional() @Inject(MAT_PAGINATOR_DEFAULT_OPTIONS) defaults?: MatPaginatorDefaultOptions) {

0 commit comments

Comments
 (0)