From 69270efb7ed0741968a03a5093528a49a0c56483 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Tue, 23 Jan 2018 16:50:55 +0100 Subject: [PATCH] fix(select): handle keyboard events from inside panel (#9361) After the switch to using `aria-describedby` for managing the highlights in `mat-select`, all of the keyboard handling was moved to the select trigger, however this doesn't account for the cases where focus makes it inside the panel (e.g. when toggling options in `multiple` mode). --- src/lib/select/select.html | 3 ++- src/lib/select/select.spec.ts | 19 +++++++++++++++---- src/lib/select/select.ts | 2 ++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/lib/select/select.html b/src/lib/select/select.html index ebe94cefc8c..e245663e433 100644 --- a/src/lib/select/select.html +++ b/src/lib/select/select.html @@ -37,7 +37,8 @@ (@transformPanel.done)="_onPanelDone()" [style.transformOrigin]="_transformOrigin" [class.mat-select-panel-done-animating]="_panelDoneAnimating" - [style.font-size.px]="_triggerFontSize"> + [style.font-size.px]="_triggerFontSize" + (keydown)="_handleKeydown($event)">
{ expect(pane.style.minWidth).toBe('200px'); })); - - it('should not attempt to open a select that does not have any options', fakeAsync(() => { fixture.componentInstance.foods = []; fixture.detectChanges(); @@ -771,8 +769,6 @@ describe('MatSelect', () => { expect(fixture.componentInstance.select.panelOpen).toBe(false); })); - - it('should close the panel when tabbing out', fakeAsync(() => { trigger.click(); fixture.detectChanges(); @@ -787,6 +783,21 @@ describe('MatSelect', () => { expect(fixture.componentInstance.select.panelOpen).toBe(false); })); + it('should close when tabbing out from inside the panel', fakeAsync(() => { + trigger.click(); + fixture.detectChanges(); + flush(); + + expect(fixture.componentInstance.select.panelOpen).toBe(true); + + const panel = overlayContainerElement.querySelector('.mat-select-panel')!; + dispatchKeyboardEvent(panel, 'keydown', TAB); + fixture.detectChanges(); + flush(); + + expect(fixture.componentInstance.select.panelOpen).toBe(false); + })); + it('should focus the first option when pressing HOME', fakeAsync(() => { fixture.componentInstance.control.setValue('pizza-1'); fixture.detectChanges(); diff --git a/src/lib/select/select.ts b/src/lib/select/select.ts index 8a5ca8def27..5e8b8b76f20 100644 --- a/src/lib/select/select.ts +++ b/src/lib/select/select.ts @@ -469,6 +469,8 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit, _parentFormGroup, ngControl); if (this.ngControl) { + // Note: we provide the value accessor through here, instead of + // the `providers` to avoid running into a circular import. this.ngControl.valueAccessor = this; }