Skip to content

Commit

Permalink
fix(button-toggle): forward tabindex to underlying button (#12538)
Browse files Browse the repository at this point in the history
  • Loading branch information
crisbeto authored and josephperrott committed Aug 7, 2018
1 parent 5623c5b commit 7dff5f8
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/lib/button-toggle/button-toggle.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<button #button class="mat-button-toggle-button"
type="button"
[id]="buttonId"
[attr.tabindex]="disabled ? -1 : tabIndex"
[attr.aria-pressed]="checked"
[disabled]="disabled || null"
[attr.name]="name || null"
Expand Down
28 changes: 28 additions & 0 deletions src/lib/button-toggle/button-toggle.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ describe('MatButtonToggle without forms', () => {
ButtonToggleWithAriaLabel,
ButtonToggleWithAriaLabelledby,
RepeatedButtonTogglesWithPreselectedValue,
ButtonToggleWithTabindex,
],
});

Expand Down Expand Up @@ -686,6 +687,26 @@ describe('MatButtonToggle without forms', () => {
});
});

describe('with tabindex ', () => {
it('should forward the tabindex to the underlying button', () => {
const fixture = TestBed.createComponent(ButtonToggleWithTabindex);
fixture.detectChanges();

const button = fixture.nativeElement.querySelector('.mat-button-toggle button');

expect(button.getAttribute('tabindex')).toBe('3');
});

it('should clear the tabindex from the host element', () => {
const fixture = TestBed.createComponent(ButtonToggleWithTabindex);
fixture.detectChanges();

const host = fixture.nativeElement.querySelector('.mat-button-toggle');

expect(host.hasAttribute('tabindex')).toBe(false);
});
});

it('should not throw on init when toggles are repeated and there is an initial value', () => {
const fixture = TestBed.createComponent(RepeatedButtonTogglesWithPreselectedValue);

Expand Down Expand Up @@ -855,3 +876,10 @@ class RepeatedButtonTogglesWithPreselectedValue {
possibleValues = ['One', 'Two', 'Three'];
value = 'Two';
}


@Component({
template: `<mat-button-toggle tabindex="3"></mat-button-toggle>`
})
class ButtonToggleWithTabindex {}

12 changes: 11 additions & 1 deletion src/lib/button-toggle/button-toggle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
QueryList,
ViewChild,
ViewEncapsulation,
Attribute,
} from '@angular/core';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
import {
Expand Down Expand Up @@ -330,6 +331,8 @@ export const _MatButtonToggleMixinBase = mixinDisableRipple(MatButtonToggleBase)
'[class.mat-button-toggle-checked]': 'checked',
'[class.mat-button-toggle-disabled]': 'disabled',
'class': 'mat-button-toggle',
// Clear out the native tabindex here since we forward it to the underlying button
'[attr.tabindex]': 'null',
'[attr.id]': 'id',
}
})
Expand Down Expand Up @@ -370,6 +373,9 @@ export class MatButtonToggle extends _MatButtonToggleMixinBase implements OnInit
/** MatButtonToggleGroup reads this to assign its own value. */
@Input() value: any;

/** Tabindex for the toggle. */
@Input() tabIndex: number | null;

/** Whether the button is checked. */
@Input()
get checked(): boolean {
Expand Down Expand Up @@ -404,9 +410,13 @@ export class MatButtonToggle extends _MatButtonToggleMixinBase implements OnInit
constructor(@Optional() toggleGroup: MatButtonToggleGroup,
private _changeDetectorRef: ChangeDetectorRef,
private _elementRef: ElementRef<HTMLElement>,
private _focusMonitor: FocusMonitor) {
private _focusMonitor: FocusMonitor,
// @breaking-change 8.0.0 `defaultTabIndex` to be made a required parameter.
@Attribute('tabindex') defaultTabIndex: string) {
super();

const parsedTabIndex = Number(defaultTabIndex);
this.tabIndex = (parsedTabIndex || parsedTabIndex === 0) ? parsedTabIndex : null;
this.buttonToggleGroup = toggleGroup;
}

Expand Down

0 comments on commit 7dff5f8

Please sign in to comment.