Skip to content

Commit 7400746

Browse files
committed
fix(material/tabs): prevent default keyboard actions on disabled links (#27274)
Fixes that while we were preventing clicks on disabled links using `pointer-events`, we didn't prevent keyboard events. Fixes #27270. (cherry picked from commit 2fbb81d)
1 parent 053099f commit 7400746

File tree

2 files changed

+19
-28
lines changed

2 files changed

+19
-28
lines changed

src/material/tabs/tab-nav-bar/tab-nav-bar.spec.ts

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {SPACE} from '@angular/cdk/keycodes';
1+
import {ENTER, SPACE} from '@angular/cdk/keycodes';
22
import {waitForAsync, ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/testing';
33
import {Component, QueryList, ViewChild, ViewChildren} from '@angular/core';
44
import {MAT_RIPPLE_GLOBAL_OPTIONS, RippleGlobalOptions} from '@angular/material/core';
@@ -73,31 +73,6 @@ describe('MDC-based MatTabNavBar', () => {
7373
expect(tabLinkElements[1].classList.contains('mdc-tab--active')).toBeTruthy();
7474
});
7575

76-
it('should add the disabled class if disabled', () => {
77-
const tabLinkElements = fixture.debugElement
78-
.queryAll(By.css('a'))
79-
.map(tabLinkDebugEl => tabLinkDebugEl.nativeElement);
80-
81-
expect(
82-
tabLinkElements.every(tabLinkEl => {
83-
return !tabLinkEl.classList.contains('mat-mdc-tab-disabled');
84-
}),
85-
)
86-
.withContext('Expected every tab link to not have the disabled class initially')
87-
.toBe(true);
88-
89-
fixture.componentInstance.disabled = true;
90-
fixture.detectChanges();
91-
92-
expect(
93-
tabLinkElements.every(tabLinkEl => {
94-
return tabLinkEl.classList.contains('mat-mdc-tab-disabled');
95-
}),
96-
)
97-
.withContext('Expected every tab link to have the disabled class if set through binding')
98-
.toBe(true);
99-
});
100-
10176
it('should update aria-disabled if disabled', () => {
10277
const tabLinkElements = fixture.debugElement
10378
.queryAll(By.css('a'))
@@ -143,6 +118,20 @@ describe('MDC-based MatTabNavBar', () => {
143118
expect(tabLinkElement.classList).toContain('mat-mdc-tab-disabled');
144119
});
145120

121+
it('should prevent default keyboard actions on disabled links', () => {
122+
const link = fixture.debugElement.query(By.css('a')).nativeElement;
123+
fixture.componentInstance.disabled = true;
124+
fixture.detectChanges();
125+
126+
const spaceEvent = dispatchKeyboardEvent(link, 'keydown', SPACE);
127+
fixture.detectChanges();
128+
expect(spaceEvent.defaultPrevented).toBe(true);
129+
130+
const enterEvent = dispatchKeyboardEvent(link, 'keydown', ENTER);
131+
fixture.detectChanges();
132+
expect(enterEvent.defaultPrevented).toBe(true);
133+
});
134+
146135
it('should re-align the ink bar when the direction changes', fakeAsync(() => {
147136
const inkBar = fixture.componentInstance.tabNavBar._inkBar;
148137

src/material/tabs/tab-nav-bar/tab-nav-bar.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ import {MatInkBar, MatInkBarItem, mixinInkBarItem} from '../ink-bar';
4848
import {BooleanInput, coerceBooleanProperty, NumberInput} from '@angular/cdk/coercion';
4949
import {BehaviorSubject, Subject} from 'rxjs';
5050
import {startWith, takeUntil} from 'rxjs/operators';
51-
import {SPACE} from '@angular/cdk/keycodes';
51+
import {ENTER, SPACE} from '@angular/cdk/keycodes';
5252
import {MAT_TABS_CONFIG, MatTabsConfig} from '../tab-config';
5353
import {MatPaginatedTabHeader, MatPaginatedTabHeaderItem} from '../paginated-tab-header';
5454

@@ -261,7 +261,9 @@ export class _MatTabLinkBase
261261
}
262262

263263
_handleKeydown(event: KeyboardEvent) {
264-
if (this._tabNavBar.tabPanel && event.keyCode === SPACE) {
264+
if (this.disabled && (event.keyCode === SPACE || event.keyCode === ENTER)) {
265+
event.preventDefault();
266+
} else if (this._tabNavBar.tabPanel && event.keyCode === SPACE) {
265267
this.elementRef.nativeElement.click();
266268
}
267269
}

0 commit comments

Comments
 (0)