Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/lib/radio/radio.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
[id]="inputId"
[checked]="checked"
[disabled]="disabled"
[tabIndex]="tabIndex"
[attr.name]="name"
[required]="required"
[attr.aria-label]="ariaLabel"
Expand Down
22 changes: 19 additions & 3 deletions src/lib/radio/radio.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -661,12 +661,26 @@ describe('MatRadio', () => {
let inputEl = fixture.debugElement.query(By.css('.mat-radio-input')).nativeElement;

radioButtonEl.focus();
// Focus events don't always fire in tests, so we needc to fake it.
// Focus events don't always fire in tests, so we need to fake it.
dispatchFakeEvent(radioButtonEl, 'focus');
fixture.detectChanges();

expect(document.activeElement).toBe(inputEl);
});

it('should allow specifying an explicit tabindex for a single radio-button', () => {
const radioButtonInput = fixture.debugElement
.query(By.css('.mat-radio-button input')).nativeElement as HTMLInputElement;

expect(radioButtonInput.tabIndex)
.toBe(0, 'Expected the tabindex to be set to "0" by default.');

fixture.componentInstance.tabIndex = 4;
fixture.detectChanges();

expect(radioButtonInput.tabIndex)
.toBe(4, 'Expected the tabindex to be set to "4".');
});
});

describe('group interspersed with other tags', () => {
Expand Down Expand Up @@ -781,9 +795,11 @@ class RadioGroupWithFormControl {
}

@Component({
template: `<mat-radio-button tabindex="-1"></mat-radio-button>`
template: `<mat-radio-button [tabIndex]="tabIndex"></mat-radio-button>`
})
class FocusableRadioButton {}
class FocusableRadioButton {
tabIndex: number;
}

@Component({
template: `
Expand Down
13 changes: 10 additions & 3 deletions src/lib/radio/radio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,12 @@ import {
CanColor,
CanDisable,
CanDisableRipple,
HasTabIndex,
MatRipple,
mixinColor,
mixinDisabled,
mixinDisableRipple,
mixinTabIndex,
RippleConfig,
RippleRef,
} from '@angular/material/core';
Expand Down Expand Up @@ -315,12 +317,17 @@ export class MatRadioGroup extends _MatRadioGroupMixinBase
// Boilerplate for applying mixins to MatRadioButton.
/** @docs-private */
export class MatRadioButtonBase {
// Since the disabled property is manually defined for the MatRadioButton and isn't set up in
// the mixin base class. To be able to use the tabindex mixin, a disabled property must be
// defined to properly work.
disabled: boolean;

constructor(public _elementRef: ElementRef) {}
}
// As per Material design specifications the selection control radio should use the accent color
// palette by default. https://material.io/guidelines/components/selection-controls.html
export const _MatRadioButtonMixinBase =
mixinColor(mixinDisableRipple(MatRadioButtonBase), 'accent');
mixinColor(mixinDisableRipple(mixinTabIndex(MatRadioButtonBase)), 'accent');

/**
* A Material design radio-button. Typically placed inside of `<mat-radio-group>` elements.
Expand All @@ -330,7 +337,7 @@ export const _MatRadioButtonMixinBase =
selector: 'mat-radio-button',
templateUrl: 'radio.html',
styleUrls: ['radio.css'],
inputs: ['color', 'disableRipple'],
inputs: ['color', 'disableRipple', 'tabIndex'],
encapsulation: ViewEncapsulation.None,
preserveWhitespaces: false,
exportAs: 'matRadioButton',
Expand All @@ -347,7 +354,7 @@ export const _MatRadioButtonMixinBase =
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MatRadioButton extends _MatRadioButtonMixinBase
implements OnInit, AfterViewInit, OnDestroy, CanColor, CanDisableRipple {
implements OnInit, AfterViewInit, OnDestroy, CanColor, CanDisableRipple, HasTabIndex {

private _uniqueId: string = `mat-radio-${++nextUniqueId}`;

Expand Down