Skip to content

Commit 69cdd5c

Browse files
committed
fix(material/button): avoid setting a tabindex on all link buttons
Fixes that the button component was always setting a `tabindex="0"` when it's placed on a link element. This is unnecessary, because links are in the tab order by default. We actually had a test that has an assertion against this, but it was passing by accident because we weren't running change detection before making the asserting.
1 parent 881edec commit 69cdd5c

File tree

4 files changed

+31
-13
lines changed

4 files changed

+31
-13
lines changed

src/material-experimental/mdc-button/button-base.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ export const MAT_ANCHOR_HOST = {
134134
// Note that we ignore the user-specified tabindex when it's disabled for
135135
// consistency with the `mat-button` applied on native buttons where even
136136
// though they have an index, they're not tabbable.
137-
'[attr.tabindex]': 'disabled ? -1 : (tabIndex || 0)',
137+
'[attr.tabindex]': 'disabled ? -1 : tabIndex',
138138
'[attr.aria-disabled]': 'disabled.toString()',
139139
// MDC automatically applies the primary theme color to the button, but we want to support
140140
// an unthemed version. If color is undefined, apply a CSS class that makes it easy to

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

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,11 +167,13 @@ describe('MDC-based MatButton', () => {
167167
let fixture = TestBed.createComponent(TestApp);
168168
let testComponent = fixture.debugElement.componentInstance;
169169
let buttonDebugElement = fixture.debugElement.query(By.css('a'))!;
170-
expect(buttonDebugElement.nativeElement.getAttribute('tabIndex')).toBe(null);
170+
fixture.detectChanges();
171+
172+
expect(buttonDebugElement.nativeElement.hasAttribute('tabindex')).toBe(false);
171173

172174
testComponent.isDisabled = true;
173175
fixture.detectChanges();
174-
expect(buttonDebugElement.nativeElement.getAttribute('tabIndex')).toBe('-1');
176+
expect(buttonDebugElement.nativeElement.getAttribute('tabindex')).toBe('-1');
175177
});
176178

177179
it('should add aria-disabled attribute if disabled', () => {
@@ -214,15 +216,23 @@ describe('MDC-based MatButton', () => {
214216
fixture.componentInstance.tabIndex = 3;
215217
fixture.detectChanges();
216218

217-
expect(buttonElement.getAttribute('tabIndex'))
219+
expect(buttonElement.getAttribute('tabindex'))
218220
.withContext('Expected custom tabindex to be set').toBe('3');
219221

220222
testComponent.isDisabled = true;
221223
fixture.detectChanges();
222224

223-
expect(buttonElement.getAttribute('tabIndex'))
225+
expect(buttonElement.getAttribute('tabindex'))
224226
.withContext('Expected custom tabindex to be overwritten when disabled.').toBe('-1');
225227
});
228+
229+
it('should not set a default tabindex on enabled links', () => {
230+
const fixture = TestBed.createComponent(TestApp);
231+
const buttonElement = fixture.debugElement.query(By.css('a'))!.nativeElement;
232+
fixture.detectChanges();
233+
234+
expect(buttonElement.hasAttribute('tabindex')).toBe(false);
235+
});
226236
});
227237

228238
// Ripple tests.

src/material/button/button.spec.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -179,14 +179,14 @@ describe('MatButton', () => {
179179
});
180180

181181
it('should remove tabindex if disabled', () => {
182-
const fixture = TestBed.createComponent(TestApp);
183-
const testComponent = fixture.debugElement.componentInstance;
184-
const buttonDebugElement = fixture.debugElement.query(By.css('a'))!;
185-
expect(buttonDebugElement.nativeElement.getAttribute('tabIndex')).toBe(null);
182+
let fixture = TestBed.createComponent(TestApp);
183+
let testComponent = fixture.debugElement.componentInstance;
184+
let buttonDebugElement = fixture.debugElement.query(By.css('a'))!;
185+
expect(buttonDebugElement.nativeElement.hasAttribute('tabindex')).toBe(false);
186186

187187
testComponent.isDisabled = true;
188188
fixture.detectChanges();
189-
expect(buttonDebugElement.nativeElement.getAttribute('tabIndex')).toBe('-1');
189+
expect(buttonDebugElement.nativeElement.getAttribute('tabindex')).toBe('-1');
190190
});
191191

192192
it('should add aria-disabled attribute if disabled', () => {
@@ -229,15 +229,23 @@ describe('MatButton', () => {
229229
fixture.componentInstance.tabIndex = 3;
230230
fixture.detectChanges();
231231

232-
expect(buttonElement.getAttribute('tabIndex'))
232+
expect(buttonElement.getAttribute('tabindex'))
233233
.withContext('Expected custom tabindex to be set').toBe('3');
234234

235235
testComponent.isDisabled = true;
236236
fixture.detectChanges();
237237

238-
expect(buttonElement.getAttribute('tabIndex'))
238+
expect(buttonElement.getAttribute('tabindex'))
239239
.withContext('Expected custom tabindex to be overwritten when disabled.').toBe('-1');
240240
});
241+
242+
it('should not set a default tabindex on enabled links', () => {
243+
const fixture = TestBed.createComponent(TestApp);
244+
const buttonElement = fixture.debugElement.query(By.css('a'))!.nativeElement;
245+
fixture.detectChanges();
246+
247+
expect(buttonElement.hasAttribute('tabindex')).toBe(false);
248+
});
241249
});
242250

243251
// Ripple tests.

src/material/button/button.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ export class MatButton extends _MatButtonBase
156156
// Note that we ignore the user-specified tabindex when it's disabled for
157157
// consistency with the `mat-button` applied on native buttons where even
158158
// though they have an index, they're not tabbable.
159-
'[attr.tabindex]': 'disabled ? -1 : (tabIndex || 0)',
159+
'[attr.tabindex]': 'disabled ? -1 : tabIndex',
160160
'[attr.disabled]': 'disabled || null',
161161
'[attr.aria-disabled]': 'disabled.toString()',
162162
'(click)': '_haltDisabledEvents($event)',

0 commit comments

Comments
 (0)