Skip to content

Commit 93fdb00

Browse files
crisbetommalerba
authored andcommitted
fix(select): select active item when tabbing away (#17592)
Currently `mat-select` closes the panel when the user tabs away, however the native select picks the currently-highlighted option. These changes add the same functionality to the `mat-select` in single selection mode. Fixes #17442.
1 parent 1a2befa commit 93fdb00

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

src/material/select/select.spec.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3075,6 +3075,58 @@ describe('MatSelect', () => {
30753075
expect(spy).toHaveBeenCalledWith('steak-0');
30763076
}));
30773077

3078+
it('should set the value when options are clicked', fakeAsync(() => {
3079+
const fixture = TestBed.createComponent(BasicSelectWithoutForms);
3080+
fixture.detectChanges();
3081+
const select = fixture.nativeElement.querySelector('.mat-select');
3082+
3083+
expect(fixture.componentInstance.selectedFood).toBeFalsy();
3084+
3085+
const trigger = fixture.nativeElement.querySelector('.mat-select-trigger');
3086+
3087+
trigger.click();
3088+
fixture.detectChanges();
3089+
flush();
3090+
3091+
dispatchKeyboardEvent(select, 'keydown', DOWN_ARROW);
3092+
fixture.detectChanges();
3093+
dispatchKeyboardEvent(select, 'keydown', DOWN_ARROW);
3094+
fixture.detectChanges();
3095+
3096+
dispatchKeyboardEvent(select, 'keydown', TAB);
3097+
fixture.detectChanges();
3098+
flush();
3099+
3100+
expect(fixture.componentInstance.selectedFood).toBe('sandwich-2');
3101+
expect(fixture.componentInstance.select.value).toBe('sandwich-2');
3102+
expect(trigger.textContent).toContain('Sandwich');
3103+
}));
3104+
3105+
it('should not change the multiple value selection when tabbing away', fakeAsync(() => {
3106+
const fixture = TestBed.createComponent(BasicSelectWithoutFormsMultiple);
3107+
fixture.detectChanges();
3108+
3109+
expect(fixture.componentInstance.selectedFoods).toBeFalsy('Expected no value on init.');
3110+
3111+
const select = fixture.nativeElement.querySelector('.mat-select');
3112+
const trigger = fixture.nativeElement.querySelector('.mat-select-trigger');
3113+
trigger.click();
3114+
fixture.detectChanges();
3115+
3116+
dispatchKeyboardEvent(select, 'keydown', DOWN_ARROW);
3117+
fixture.detectChanges();
3118+
dispatchKeyboardEvent(select, 'keydown', DOWN_ARROW);
3119+
fixture.detectChanges();
3120+
3121+
dispatchKeyboardEvent(select, 'keydown', TAB);
3122+
fixture.detectChanges();
3123+
flush();
3124+
3125+
expect(fixture.componentInstance.selectedFoods)
3126+
.toBeFalsy('Expected no value after tabbing away.');
3127+
}));
3128+
3129+
30783130
});
30793131

30803132
describe('with option centering disabled', () => {

src/material/select/select.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,12 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
899899
.withAllowedModifierKeys(['shiftKey']);
900900

901901
this._keyManager.tabOut.pipe(takeUntil(this._destroy)).subscribe(() => {
902+
// Select the active item when tabbing away. This is consistent with how the native
903+
// select behaves. Note that we only want to do this in single selection mode.
904+
if (!this.multiple && this._keyManager.activeItem) {
905+
this._keyManager.activeItem._selectViaInteraction();
906+
}
907+
902908
// Restore focus to the trigger before closing. Ensures that the focus
903909
// position won't be lost if the user got focus into the overlay.
904910
this.focus();

0 commit comments

Comments
 (0)