Skip to content

Commit d996abd

Browse files
crisbetommalerba
authored andcommitted
fix(select): highlighted option not updated if value is reset while closed (#17213)
Currently we support the same feature as the native `select` where users can change the value and the focused option while the panel is closed using the arrow keys. The problem is that if the user changes the selected option and the value gets reset, the active option doesn't get updated so next time they interact with the control, it'll pick up from the previous position. These changes add an extra call to reset the highlighted option if the value is reset. Fixes #17212. (cherry picked from commit d453d06)
1 parent 13363e6 commit d996abd

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

src/material/select/select.spec.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,34 @@ describe('MatSelect', () => {
296296
flush();
297297
}));
298298

299+
it('should go back to first option if value is reset after interacting using the' +
300+
'arrow keys on a closed select', fakeAsync(() => {
301+
const formControl = fixture.componentInstance.control;
302+
const options = fixture.componentInstance.options.toArray();
303+
304+
expect(formControl.value).toBeFalsy('Expected no initial value.');
305+
306+
dispatchKeyboardEvent(select, 'keydown', DOWN_ARROW);
307+
flush();
308+
309+
expect(options[0].selected).toBe(true, 'Expected first option to be selected.');
310+
expect(formControl.value).toBe(options[0].value,
311+
'Expected value from first option to have been set on the model.');
312+
313+
formControl.reset();
314+
fixture.detectChanges();
315+
316+
expect(options[0].selected).toBe(false, 'Expected first option to be deselected.');
317+
expect(formControl.value).toBeFalsy('Expected value to be reset.');
318+
319+
dispatchKeyboardEvent(select, 'keydown', DOWN_ARROW);
320+
flush();
321+
322+
expect(options[0].selected).toBe(true, 'Expected first option to be selected again.');
323+
expect(formControl.value).toBe(options[0].value,
324+
'Expected value from first option to have been set on the model again.');
325+
}));
326+
299327
it('should select first/last options via the HOME/END keys on a closed select',
300328
fakeAsync(() => {
301329
const formControl = fixture.componentInstance.control;

src/material/select/select.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,10 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
858858
// mode, because we don't know what option the user interacted with last.
859859
if (correspondingOption) {
860860
this._keyManager.setActiveItem(correspondingOption);
861+
} else if (!this.panelOpen) {
862+
// Otherwise reset the highlighted option. Note that we only want to do this while
863+
// closed, because doing it while open can shift the user's focus unnecessarily.
864+
this._keyManager.setActiveItem(-1);
861865
}
862866
}
863867

0 commit comments

Comments
 (0)