From cea4d9fa32093159140c2fbcce50b36ec99697d3 Mon Sep 17 00:00:00 2001 From: mmalerba Date: Tue, 8 Aug 2017 23:21:53 -0700 Subject: [PATCH] fix(radio): forward focus to native input (#6274) * fix(radio): forward focus to native input * add comment --- src/lib/radio/radio.spec.ts | 27 +++++++++++++++++++++++++++ src/lib/radio/radio.ts | 4 ++++ 2 files changed, 31 insertions(+) diff --git a/src/lib/radio/radio.spec.ts b/src/lib/radio/radio.spec.ts index c06f760be315..55e5bbf0de47 100644 --- a/src/lib/radio/radio.spec.ts +++ b/src/lib/radio/radio.spec.ts @@ -15,6 +15,7 @@ describe('MdRadio', () => { TestBed.configureTestingModule({ imports: [MdRadioModule, FormsModule, ReactiveFormsModule], declarations: [ + FocusableRadioButton, RadiosInsideRadioGroup, RadioGroupWithNgModel, RadioGroupWithFormControl, @@ -640,6 +641,27 @@ describe('MdRadio', () => { } }); }); + + describe('with tabindex', () => { + let fixture: ComponentFixture; + + beforeEach(() => { + fixture = TestBed.createComponent(FocusableRadioButton); + fixture.detectChanges(); + }); + + it('should forward focus to native input', () => { + let radioButtonEl = fixture.debugElement.query(By.css('.mat-radio-button')).nativeElement; + 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. + dispatchFakeEvent(radioButtonEl, 'focus'); + fixture.detectChanges(); + + expect(document.activeElement).toBe(inputEl); + }); + }); }); @@ -728,3 +750,8 @@ class RadioGroupWithNgModel { class RadioGroupWithFormControl { formControl = new FormControl(); } + +@Component({ + template: `` +}) +class FocusableRadioButton {} diff --git a/src/lib/radio/radio.ts b/src/lib/radio/radio.ts index e22877646358..3d9fbe38d454 100644 --- a/src/lib/radio/radio.ts +++ b/src/lib/radio/radio.ts @@ -332,6 +332,10 @@ export const _MdRadioButtonMixinBase = mixinColor(mixinDisableRipple(MdRadioButt '[class.mat-radio-checked]': 'checked', '[class.mat-radio-disabled]': 'disabled', '[attr.id]': 'id', + // Note: under normal conditions focus shouldn't land on this element, however it may be + // programmatically set, for example inside of a focus trap, in this case we want to forward + // the focus to the native element. + '(focus)': '_inputElement.nativeElement.focus()', }, changeDetection: ChangeDetectionStrategy.OnPush, })