Skip to content

Commit b056fc2

Browse files
committed
fix(material/chips): remove button role from editable chips
Removes the button role from editable input chips. Fix accessibility issue in ChipRow where the chip action element is mislabeled as a button (#27106). Remove butotn role by remove DOM node thtat used to have button role and using the gridcell role element for the primary chip action instead. Tested cross-browser with supported screen readers on MacOS and Windows. Tested on "Chips with input" example by verifying that a chip could be added then edited after adding. Also verifying that AT read the chip's aria description. Testing Environment - macOS 13.4 (22F66) / VoiceOver - Chrome Version 114.0.5735.133 (Official Build) (arm64) - Firefox 114.0.1 (64-bit) - windows 10 Enteprise Version 22H2 - JAWS VERSION 2020.2006.12 ILM - NVDA version 2022.3 - Chrome Version 114.0.5735.134 (Official Build) (64-bit) - Firefox 114.0.2 (64-bit) Fix #27106
1 parent 3be0809 commit b056fc2

File tree

2 files changed

+18
-19
lines changed

2 files changed

+18
-19
lines changed

src/material/chips/chip-row.html

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,25 @@
77
</ng-container>
88

99

10-
<span class="mdc-evolution-chip__cell mdc-evolution-chip__cell--primary" role="gridcell">
11-
<span
10+
<span class="mdc-evolution-chip__cell mdc-evolution-chip__cell--primary" role="gridcell"
1211
matChipAction
13-
[attr.role]="editable ? 'button' : null"
1412
[tabIndex]="tabIndex"
1513
[disabled]="disabled"
1614
[attr.aria-label]="ariaLabel"
1715
[attr.aria-describedby]="_ariaDescriptionId">
18-
<span class="mdc-evolution-chip__graphic mat-mdc-chip-graphic" *ngIf="leadingIcon">
19-
<ng-content select="mat-chip-avatar, [matChipAvatar]"></ng-content>
20-
</span>
21-
<span class="mdc-evolution-chip__text-label mat-mdc-chip-action-label" [ngSwitch]="_isEditing">
22-
<ng-container *ngSwitchCase="false"><ng-content></ng-content></ng-container>
16+
<span class="mdc-evolution-chip__graphic mat-mdc-chip-graphic" *ngIf="leadingIcon">
17+
<ng-content select="mat-chip-avatar, [matChipAvatar]"></ng-content>
18+
</span>
19+
<span class="mdc-evolution-chip__text-label mat-mdc-chip-action-label" [ngSwitch]="_isEditing">
20+
<ng-container *ngSwitchCase="false"><ng-content></ng-content></ng-container>
2321

24-
<ng-container *ngSwitchCase="true">
25-
<ng-content *ngIf="contentEditInput; else defaultMatChipEditInput"
26-
select="[matChipEditInput]"></ng-content>
27-
<ng-template #defaultMatChipEditInput><span matChipEditInput></span></ng-template>
28-
</ng-container>
22+
<ng-container *ngSwitchCase="true">
23+
<ng-content *ngIf="contentEditInput; else defaultMatChipEditInput"
24+
select="[matChipEditInput]"></ng-content>
25+
<ng-template #defaultMatChipEditInput><span matChipEditInput></span></ng-template>
26+
</ng-container>
2927

30-
<span class="mat-mdc-chip-primary-focus-indicator mat-mdc-focus-indicator"></span>
31-
</span>
28+
<span class="mat-mdc-chip-primary-focus-indicator mat-mdc-focus-indicator" aria-hidden="true"></span>
3229
</span>
3330
</span>
3431

src/material/chips/chip-row.spec.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -256,14 +256,16 @@ describe('MDC-based Row Chips', () => {
256256
return chipNativeElement.querySelector('.mat-chip-edit-input')!;
257257
}
258258

259-
it('should set the role of the primary action based on whether it is editable', () => {
259+
it('should set the role of the primary action to gridcell', () => {
260260
testComponent.editable = false;
261261
fixture.detectChanges();
262-
expect(primaryAction.hasAttribute('role')).toBe(false);
262+
expect(primaryAction.getAttribute('role')).toBe('gridcell');
263263

264264
testComponent.editable = true;
265265
fixture.detectChanges();
266-
expect(primaryAction.getAttribute('role')).toBe('button');
266+
// Test regression of bug where element is mislabeled as a button role. Element that does not perform its
267+
// action on click event is not a button by ARIA spec (#27106).
268+
expect(primaryAction.getAttribute('role')).toBe('gridcell');
267269
});
268270

269271
it('should not delete the chip on DELETE or BACKSPACE', () => {
@@ -346,7 +348,7 @@ describe('MDC-based Row Chips', () => {
346348
fixture.detectChanges();
347349

348350
const primaryGridCell = (fixture.nativeElement as HTMLElement).querySelector(
349-
'[role="gridcell"].mdc-evolution-chip__cell--primary .mat-mdc-chip-action',
351+
'[role="gridcell"].mdc-evolution-chip__cell--primary.mat-mdc-chip-action',
350352
);
351353
expect(primaryGridCell)
352354
.withContext('expected to find the grid cell for the primary chip action')

0 commit comments

Comments
 (0)