Skip to content

Commit 1f4d598

Browse files
crisbetowagnermaciel
authored andcommitted
fix(radio): take default tabindex value from attribute (#20453)
This is something that we have everywhere where we deal with `tabindex`, but it was missing on the radio button. Adds some logic that will take the initial `tabindex` value from the attribute through DI. (cherry picked from commit 2c83b40)
1 parent 60a3527 commit 1f4d598

File tree

5 files changed

+45
-11
lines changed

5 files changed

+45
-11
lines changed

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,16 @@ describe('MDC-based MatRadio', () => {
794794
expect(radioButtonEl.getAttribute('tabindex')).toBe('-1');
795795
});
796796

797+
it('should forward a pre-defined tabindex to the underlying input', () => {
798+
const predefinedFixture = TestBed.createComponent(RadioButtonWithPredefinedTabindex);
799+
predefinedFixture.detectChanges();
800+
801+
const radioButtonInput = predefinedFixture.debugElement
802+
.query(By.css('.mat-mdc-radio-button input'))!.nativeElement as HTMLInputElement;
803+
804+
expect(radioButtonInput.getAttribute('tabindex')).toBe('5');
805+
});
806+
797807
it('should remove the aria attributes from the host element', () => {
798808
const predefinedFixture = TestBed.createComponent(RadioButtonWithPredefinedAriaAttributes);
799809
predefinedFixture.detectChanges();
@@ -1016,7 +1026,7 @@ class TranscludingWrapper {}
10161026

10171027

10181028
@Component({
1019-
template: `<mat-radio-button tabindex="0"></mat-radio-button>`
1029+
template: `<mat-radio-button tabindex="5"></mat-radio-button>`
10201030
})
10211031
class RadioButtonWithPredefinedTabindex {}
10221032

src/material-experimental/mdc-radio/radio.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import {
1010
AfterViewInit,
11+
Attribute,
1112
ChangeDetectionStrategy,
1213
ChangeDetectorRef,
1314
Component,
@@ -136,9 +137,10 @@ export class MatRadioButton extends _MatRadioButtonBase implements AfterViewInit
136137
_radioDispatcher: UniqueSelectionDispatcher,
137138
@Optional() @Inject(ANIMATION_MODULE_TYPE) _animationMode?: string,
138139
@Optional() @Inject(MAT_RADIO_DEFAULT_OPTIONS)
139-
_providerOverride?: MatRadioDefaultOptions) {
140+
_providerOverride?: MatRadioDefaultOptions,
141+
@Attribute('tabindex') tabIndex?: string) {
140142
super(radioGroup, elementRef, _changeDetector, _focusMonitor,
141-
_radioDispatcher, _animationMode, _providerOverride);
143+
_radioDispatcher, _animationMode, _providerOverride, tabIndex);
142144
}
143145

144146
ngAfterViewInit() {

src/material/radio/radio.spec.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,16 @@ describe('MatRadio', () => {
787787
expect(radioButtonEl.getAttribute('tabindex')).toBe('-1');
788788
});
789789

790+
it('should forward a pre-defined tabindex to the underlying input', () => {
791+
const predefinedFixture = TestBed.createComponent(RadioButtonWithPredefinedTabindex);
792+
predefinedFixture.detectChanges();
793+
794+
const radioButtonInput = predefinedFixture.debugElement
795+
.query(By.css('.mat-radio-button input'))!.nativeElement as HTMLInputElement;
796+
797+
expect(radioButtonInput.getAttribute('tabindex')).toBe('5');
798+
});
799+
790800
it('should remove the aria attributes from the host element', () => {
791801
const predefinedFixture = TestBed.createComponent(RadioButtonWithPredefinedAriaAttributes);
792802
predefinedFixture.detectChanges();
@@ -999,7 +1009,7 @@ class TranscludingWrapper {}
9991009

10001010

10011011
@Component({
1002-
template: `<mat-radio-button tabindex="0"></mat-radio-button>`
1012+
template: `<mat-radio-button tabindex="5"></mat-radio-button>`
10031013
})
10041014
class RadioButtonWithPredefinedTabindex {}
10051015

src/material/radio/radio.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,17 @@
77
*/
88

99
import {FocusMonitor} from '@angular/cdk/a11y';
10-
import {BooleanInput, coerceBooleanProperty, NumberInput} from '@angular/cdk/coercion';
10+
import {
11+
BooleanInput,
12+
coerceBooleanProperty,
13+
coerceNumberProperty,
14+
NumberInput,
15+
} from '@angular/cdk/coercion';
1116
import {UniqueSelectionDispatcher} from '@angular/cdk/collections';
1217
import {
1318
AfterContentInit,
1419
AfterViewInit,
20+
Attribute,
1521
ChangeDetectionStrategy,
1622
ChangeDetectorRef,
1723
Component,
@@ -489,13 +495,18 @@ export abstract class _MatRadioButtonBase extends _MatRadioButtonMixinBase imple
489495
private _focusMonitor: FocusMonitor,
490496
private _radioDispatcher: UniqueSelectionDispatcher,
491497
public _animationMode?: string,
492-
private _providerOverride?: MatRadioDefaultOptions) {
498+
private _providerOverride?: MatRadioDefaultOptions,
499+
tabIndex?: string) {
493500
super(elementRef);
494501

495502
// Assertions. Ideally these should be stripped out by the compiler.
496503
// TODO(jelbourn): Assert that there's no name binding AND a parent radio group.
497504
this.radioGroup = radioGroup;
498505

506+
if (tabIndex) {
507+
this.tabIndex = coerceNumberProperty(tabIndex, 0);
508+
}
509+
499510
this._removeUniqueSelectionListener =
500511
_radioDispatcher.listen((id: string, name: string) => {
501512
if (id !== this.id && name === this.name) {
@@ -641,8 +652,9 @@ export class MatRadioButton extends _MatRadioButtonBase {
641652
radioDispatcher: UniqueSelectionDispatcher,
642653
@Optional() @Inject(ANIMATION_MODULE_TYPE) animationMode?: string,
643654
@Optional() @Inject(MAT_RADIO_DEFAULT_OPTIONS)
644-
providerOverride?: MatRadioDefaultOptions) {
655+
providerOverride?: MatRadioDefaultOptions,
656+
@Attribute('tabindex') tabIndex?: string) {
645657
super(radioGroup, elementRef, changeDetector, focusMonitor, radioDispatcher,
646-
animationMode, providerOverride);
658+
animationMode, providerOverride, tabIndex);
647659
}
648660
}

tools/public_api_guard/material/radio.d.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export declare abstract class _MatRadioButtonBase extends _MatRadioButtonMixinBa
2222
set required(value: boolean);
2323
get value(): any;
2424
set value(value: any);
25-
constructor(radioGroup: _MatRadioGroupBase<_MatRadioButtonBase>, elementRef: ElementRef, _changeDetector: ChangeDetectorRef, _focusMonitor: FocusMonitor, _radioDispatcher: UniqueSelectionDispatcher, _animationMode?: string | undefined, _providerOverride?: MatRadioDefaultOptions | undefined);
25+
constructor(radioGroup: _MatRadioGroupBase<_MatRadioButtonBase>, elementRef: ElementRef, _changeDetector: ChangeDetectorRef, _focusMonitor: FocusMonitor, _radioDispatcher: UniqueSelectionDispatcher, _animationMode?: string | undefined, _providerOverride?: MatRadioDefaultOptions | undefined, tabIndex?: string);
2626
_isRippleDisabled(): boolean;
2727
_markForCheck(): void;
2828
_onInputChange(event: Event): void;
@@ -84,9 +84,9 @@ export declare const MAT_RADIO_GROUP: InjectionToken<_MatRadioGroupBase<_MatRadi
8484
export declare const MAT_RADIO_GROUP_CONTROL_VALUE_ACCESSOR: any;
8585

8686
export declare class MatRadioButton extends _MatRadioButtonBase {
87-
constructor(radioGroup: MatRadioGroup, elementRef: ElementRef, changeDetector: ChangeDetectorRef, focusMonitor: FocusMonitor, radioDispatcher: UniqueSelectionDispatcher, animationMode?: string, providerOverride?: MatRadioDefaultOptions);
87+
constructor(radioGroup: MatRadioGroup, elementRef: ElementRef, changeDetector: ChangeDetectorRef, focusMonitor: FocusMonitor, radioDispatcher: UniqueSelectionDispatcher, animationMode?: string, providerOverride?: MatRadioDefaultOptions, tabIndex?: string);
8888
static ɵcmp: i0.ɵɵComponentDefWithMeta<MatRadioButton, "mat-radio-button", ["matRadioButton"], { "disableRipple": "disableRipple"; "tabIndex": "tabIndex"; }, {}, never, ["*"]>;
89-
static ɵfac: i0.ɵɵFactoryDef<MatRadioButton, [{ optional: true; }, null, null, null, null, { optional: true; }, { optional: true; }]>;
89+
static ɵfac: i0.ɵɵFactoryDef<MatRadioButton, [{ optional: true; }, null, null, null, null, { optional: true; }, { optional: true; }, { attribute: "tabindex"; }]>;
9090
}
9191

9292
export declare class MatRadioChange {

0 commit comments

Comments
 (0)