Skip to content

Commit 4307837

Browse files
crisbetojelbourn
authored andcommitted
fix(select): don't select active item when tabbing away while closed (#18797)
When the user tabs away from a select, we pick out the active option automatically. The problem is that we weren't checking that the select is open so in some cases the user might be tabbing through and selecting something by accident. Fixes #18784. (cherry picked from commit 4e6083b)
1 parent 087ed4a commit 4307837

File tree

2 files changed

+40
-10
lines changed

2 files changed

+40
-10
lines changed

src/material/select/select.spec.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
TAB,
1111
UP_ARROW,
1212
A,
13+
ESCAPE,
1314
} from '@angular/cdk/keycodes';
1415
import {OverlayContainer} from '@angular/cdk/overlay';
1516
import {Platform} from '@angular/cdk/platform';
@@ -3102,7 +3103,7 @@ describe('MatSelect', () => {
31023103
expect(spy).toHaveBeenCalledWith('steak-0');
31033104
}));
31043105

3105-
it('should set the value when options are clicked', fakeAsync(() => {
3106+
it('should select the active option when tabbing away while open', fakeAsync(() => {
31063107
const fixture = TestBed.createComponent(BasicSelectWithoutForms);
31073108
fixture.detectChanges();
31083109
const select = fixture.nativeElement.querySelector('.mat-select');
@@ -3129,6 +3130,33 @@ describe('MatSelect', () => {
31293130
expect(trigger.textContent).toContain('Sandwich');
31303131
}));
31313132

3133+
it('should not select the active option when tabbing away while close', fakeAsync(() => {
3134+
const fixture = TestBed.createComponent(BasicSelectWithoutForms);
3135+
fixture.detectChanges();
3136+
const select = fixture.nativeElement.querySelector('.mat-select');
3137+
3138+
expect(fixture.componentInstance.selectedFood).toBeFalsy();
3139+
3140+
const trigger = fixture.nativeElement.querySelector('.mat-select-trigger');
3141+
3142+
trigger.click();
3143+
fixture.detectChanges();
3144+
flush();
3145+
3146+
dispatchKeyboardEvent(select, 'keydown', DOWN_ARROW);
3147+
fixture.detectChanges();
3148+
dispatchKeyboardEvent(select, 'keydown', DOWN_ARROW);
3149+
fixture.detectChanges();
3150+
dispatchKeyboardEvent(select, 'keydown', ESCAPE);
3151+
fixture.detectChanges();
3152+
3153+
dispatchKeyboardEvent(select, 'keydown', TAB);
3154+
fixture.detectChanges();
3155+
flush();
3156+
3157+
expect(fixture.componentInstance.selectedFood).toBeFalsy();
3158+
}));
3159+
31323160
it('should not change the multiple value selection when tabbing away', fakeAsync(() => {
31333161
const fixture = TestBed.createComponent(BasicSelectWithoutFormsMultiple);
31343162
fixture.detectChanges();

src/material/select/select.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -936,16 +936,18 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
936936
.withAllowedModifierKeys(['shiftKey']);
937937

938938
this._keyManager.tabOut.pipe(takeUntil(this._destroy)).subscribe(() => {
939-
// Select the active item when tabbing away. This is consistent with how the native
940-
// select behaves. Note that we only want to do this in single selection mode.
941-
if (!this.multiple && this._keyManager.activeItem) {
942-
this._keyManager.activeItem._selectViaInteraction();
943-
}
939+
if (this.panelOpen) {
940+
// Select the active item when tabbing away. This is consistent with how the native
941+
// select behaves. Note that we only want to do this in single selection mode.
942+
if (!this.multiple && this._keyManager.activeItem) {
943+
this._keyManager.activeItem._selectViaInteraction();
944+
}
944945

945-
// Restore focus to the trigger before closing. Ensures that the focus
946-
// position won't be lost if the user got focus into the overlay.
947-
this.focus();
948-
this.close();
946+
// Restore focus to the trigger before closing. Ensures that the focus
947+
// position won't be lost if the user got focus into the overlay.
948+
this.focus();
949+
this.close();
950+
}
949951
});
950952

951953
this._keyManager.change.pipe(takeUntil(this._destroy)).subscribe(() => {

0 commit comments

Comments
 (0)