mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(select): handle home and end keys on closed select (#13278)
Moves the selection to the first/last item when pressing home/end on a closed `mat-select`, similarly to a native `select`.
This commit is contained in:
committed by
vivian-hu
parent
01b18c04d0
commit
d6ba25fb1a
@@ -293,6 +293,29 @@ describe('MatSelect', () => {
|
||||
'Expected value from second option to have been set on the model.');
|
||||
}));
|
||||
|
||||
it('should select first/last options via the HOME/END keys on a closed select',
|
||||
fakeAsync(() => {
|
||||
const formControl = fixture.componentInstance.control;
|
||||
const firstOption = fixture.componentInstance.options.first;
|
||||
const lastOption = fixture.componentInstance.options.last;
|
||||
|
||||
expect(formControl.value).toBeFalsy('Expected no initial value.');
|
||||
|
||||
const endEvent = dispatchKeyboardEvent(select, 'keydown', END);
|
||||
|
||||
expect(endEvent.defaultPrevented).toBe(true);
|
||||
expect(lastOption.selected).toBe(true, 'Expected last option to be selected.');
|
||||
expect(formControl.value).toBe(lastOption.value,
|
||||
'Expected value from last option to have been set on the model.');
|
||||
|
||||
const homeEvent = dispatchKeyboardEvent(select, 'keydown', HOME);
|
||||
|
||||
expect(homeEvent.defaultPrevented).toBe(true);
|
||||
expect(firstOption.selected).toBe(true, 'Expected first option to be selected.');
|
||||
expect(formControl.value).toBe(firstOption.value,
|
||||
'Expected value from first option to have been set on the model.');
|
||||
}));
|
||||
|
||||
it('should resume focus from selected item after selecting via click', fakeAsync(() => {
|
||||
const formControl = fixture.componentInstance.control;
|
||||
const options = fixture.componentInstance.options.toArray();
|
||||
|
||||
@@ -691,15 +691,21 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
|
||||
private _handleClosedKeydown(event: KeyboardEvent): void {
|
||||
const keyCode = event.keyCode;
|
||||
const isArrowKey = keyCode === DOWN_ARROW || keyCode === UP_ARROW ||
|
||||
keyCode === LEFT_ARROW || keyCode === RIGHT_ARROW;
|
||||
keyCode === LEFT_ARROW || keyCode === RIGHT_ARROW;
|
||||
const isOpenKey = keyCode === ENTER || keyCode === SPACE;
|
||||
const manager = this._keyManager;
|
||||
|
||||
// Open the select on ALT + arrow key to match the native <select>
|
||||
if (isOpenKey || ((this.multiple || event.altKey) && isArrowKey)) {
|
||||
event.preventDefault(); // prevents the page from scrolling down when pressing space
|
||||
this.open();
|
||||
} else if (!this.multiple) {
|
||||
this._keyManager.onKeydown(event);
|
||||
if (keyCode === HOME || keyCode === END) {
|
||||
keyCode === HOME ? manager.setFirstItemActive() : manager.setLastItemActive();
|
||||
event.preventDefault();
|
||||
} else {
|
||||
manager.onKeydown(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user