Skip to content

Commit f3352bc

Browse files
committed
fix(autocomplete): don't block default arrow keys when using modifiers
Currently we hijack all up/down arrow key events, however this interferes with keyboard shortcuts such as shift + up arrow for marking all of the text. These changes stop intercepting the arrow keys, if they're used with a modifier. These changes also fix an issue where all the mocked out key events had the `metaKey` set to `true` on some browsers.
1 parent 6a7fc81 commit f3352bc

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

src/material/autocomplete/autocomplete-trigger.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -393,15 +393,16 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnChanges,
393393
event.preventDefault();
394394
} else if (this.autocomplete) {
395395
const prevActiveItem = this.autocomplete._keyManager.activeItem;
396-
const isArrowKey = keyCode === UP_ARROW || keyCode === DOWN_ARROW;
396+
const isVerticalArrowKey = keyCode === UP_ARROW || keyCode === DOWN_ARROW;
397+
const hasModifier = event.ctrlKey || event.altKey || event.metaKey || event.shiftKey;
397398

398-
if (this.panelOpen || keyCode === TAB) {
399+
if ((isVerticalArrowKey && !hasModifier) || keyCode === TAB) {
399400
this.autocomplete._keyManager.onKeydown(event);
400-
} else if (isArrowKey && this._canOpen()) {
401+
} else if (isVerticalArrowKey && this._canOpen()) {
401402
this.openPanel();
402403
}
403404

404-
if (isArrowKey || this.autocomplete._keyManager.activeItem !== prevActiveItem) {
405+
if (isVerticalArrowKey || this.autocomplete._keyManager.activeItem !== prevActiveItem) {
405406
this._scrollToOption();
406407
}
407408
}

src/material/autocomplete/autocomplete.spec.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,6 +1199,18 @@ describe('MatAutocomplete', () => {
11991199
expect(!!trigger.activeOption).toBe(false, 'Expected no active options.');
12001200
}));
12011201

1202+
it('should not prevent the default action when a modifier key is pressed', () => {
1203+
['metaKey', 'ctrlKey', 'altKey', 'shiftKey'].forEach(name => {
1204+
const event = createKeyboardEvent('keydown', DOWN_ARROW);
1205+
Object.defineProperty(event, name, {get: () => true});
1206+
1207+
fixture.componentInstance.trigger._handleKeydown(event);
1208+
fixture.detectChanges();
1209+
1210+
expect(event.defaultPrevented).toBe(false, `Expected autocompete not to block ${name} key`);
1211+
});
1212+
});
1213+
12021214
});
12031215

12041216
describe('option groups', () => {

0 commit comments

Comments
 (0)