Skip to content

Commit c1f7b5d

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 03485cd commit c1f7b5d

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
@@ -141,7 +141,7 @@ export const MAT_ANCHOR_HOST = {
141141
// Note that we ignore the user-specified tabindex when it's disabled for
142142
// consistency with the `mat-button` applied on native buttons where even
143143
// though they have an index, they're not tabbable.
144-
'[attr.tabindex]': 'disabled ? -1 : (tabIndex || 0)',
144+
'[attr.tabindex]': 'disabled ? -1 : tabIndex',
145145
'[attr.aria-disabled]': 'disabled.toString()',
146146
// MDC automatically applies the primary theme color to the button, but we want to support
147147
// 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
@@ -169,11 +169,13 @@ describe('MDC-based MatButton', () => {
169169
let fixture = TestBed.createComponent(TestApp);
170170
let testComponent = fixture.debugElement.componentInstance;
171171
let buttonDebugElement = fixture.debugElement.query(By.css('a'))!;
172-
expect(buttonDebugElement.nativeElement.getAttribute('tabIndex')).toBe(null);
172+
fixture.detectChanges();
173+
174+
expect(buttonDebugElement.nativeElement.hasAttribute('tabindex')).toBe(false);
173175

174176
testComponent.isDisabled = true;
175177
fixture.detectChanges();
176-
expect(buttonDebugElement.nativeElement.getAttribute('tabIndex')).toBe('-1');
178+
expect(buttonDebugElement.nativeElement.getAttribute('tabindex')).toBe('-1');
177179
});
178180

179181
it('should add aria-disabled attribute if disabled', () => {
@@ -218,17 +220,25 @@ describe('MDC-based MatButton', () => {
218220
fixture.componentInstance.tabIndex = 3;
219221
fixture.detectChanges();
220222

221-
expect(buttonElement.getAttribute('tabIndex'))
223+
expect(buttonElement.getAttribute('tabindex'))
222224
.withContext('Expected custom tabindex to be set')
223225
.toBe('3');
224226

225227
testComponent.isDisabled = true;
226228
fixture.detectChanges();
227229

228-
expect(buttonElement.getAttribute('tabIndex'))
230+
expect(buttonElement.getAttribute('tabindex'))
229231
.withContext('Expected custom tabindex to be overwritten when disabled.')
230232
.toBe('-1');
231233
});
234+
235+
it('should not set a default tabindex on enabled links', () => {
236+
const fixture = TestBed.createComponent(TestApp);
237+
const buttonElement = fixture.debugElement.query(By.css('a'))!.nativeElement;
238+
fixture.detectChanges();
239+
240+
expect(buttonElement.hasAttribute('tabindex')).toBe(false);
241+
});
232242
});
233243

234244
// Ripple tests.

src/material/button/button.spec.ts

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

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

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

193193
it('should add aria-disabled attribute if disabled', () => {
@@ -232,17 +232,25 @@ describe('MatButton', () => {
232232
fixture.componentInstance.tabIndex = 3;
233233
fixture.detectChanges();
234234

235-
expect(buttonElement.getAttribute('tabIndex'))
235+
expect(buttonElement.getAttribute('tabindex'))
236236
.withContext('Expected custom tabindex to be set')
237237
.toBe('3');
238238

239239
testComponent.isDisabled = true;
240240
fixture.detectChanges();
241241

242-
expect(buttonElement.getAttribute('tabIndex'))
242+
expect(buttonElement.getAttribute('tabindex'))
243243
.withContext('Expected custom tabindex to be overwritten when disabled.')
244244
.toBe('-1');
245245
});
246+
247+
it('should not set a default tabindex on enabled links', () => {
248+
const fixture = TestBed.createComponent(TestApp);
249+
const buttonElement = fixture.debugElement.query(By.css('a'))!.nativeElement;
250+
fixture.detectChanges();
251+
252+
expect(buttonElement.hasAttribute('tabindex')).toBe(false);
253+
});
246254
});
247255

248256
// Ripple tests.

src/material/button/button.ts

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

0 commit comments

Comments
 (0)