fix(select): support ctrl+a shortcut for multi-select (#11799)

This commit is contained in:
Kristiyan Kostadinov
2018-06-29 18:12:22 +02:00
committed by Joey Perrott
parent 8dfce58e2b
commit d5de711639
2 changed files with 96 additions and 0 deletions
+91
View File
@@ -9,6 +9,7 @@ import {
SPACE,
TAB,
UP_ARROW,
A,
} from '@angular/cdk/keycodes';
import {OverlayContainer} from '@angular/cdk/overlay';
import {Platform} from '@angular/cdk/platform';
@@ -3901,6 +3902,96 @@ describe('MatSelect', () => {
expect(testInstance.control.value).toEqual([null, 'pizza-1', null]);
}));
it('should select all options when pressing ctrl + a', () => {
const selectElement = fixture.nativeElement.querySelector('mat-select');
const options = fixture.componentInstance.options.toArray();
expect(testInstance.control.value).toBeFalsy();
expect(options.every(option => option.selected)).toBe(false);
fixture.componentInstance.select.open();
fixture.detectChanges();
const event = createKeyboardEvent('keydown', A, selectElement);
Object.defineProperty(event, 'ctrlKey', {get: () => true});
dispatchEvent(selectElement, event);
fixture.detectChanges();
expect(options.every(option => option.selected)).toBe(true);
expect(testInstance.control.value).toEqual([
'steak-0',
'pizza-1',
'tacos-2',
'sandwich-3',
'chips-4',
'eggs-5',
'pasta-6',
'sushi-7'
]);
});
it('should select all options when pressing ctrl + a when some options are selected', () => {
const selectElement = fixture.nativeElement.querySelector('mat-select');
const options = fixture.componentInstance.options.toArray();
options[0].select();
fixture.detectChanges();
expect(testInstance.control.value).toEqual(['steak-0']);
expect(options.some(option => option.selected)).toBe(true);
fixture.componentInstance.select.open();
fixture.detectChanges();
const event = createKeyboardEvent('keydown', A, selectElement);
Object.defineProperty(event, 'ctrlKey', {get: () => true});
dispatchEvent(selectElement, event);
fixture.detectChanges();
expect(options.every(option => option.selected)).toBe(true);
expect(testInstance.control.value).toEqual([
'steak-0',
'pizza-1',
'tacos-2',
'sandwich-3',
'chips-4',
'eggs-5',
'pasta-6',
'sushi-7'
]);
});
it('should deselect all options with ctrl + a if all options are selected', () => {
const selectElement = fixture.nativeElement.querySelector('mat-select');
const options = fixture.componentInstance.options.toArray();
options.forEach(option => option.select());
fixture.detectChanges();
expect(testInstance.control.value).toEqual([
'steak-0',
'pizza-1',
'tacos-2',
'sandwich-3',
'chips-4',
'eggs-5',
'pasta-6',
'sushi-7'
]);
expect(options.every(option => option.selected)).toBe(true);
fixture.componentInstance.select.open();
fixture.detectChanges();
const event = createKeyboardEvent('keydown', A, selectElement);
Object.defineProperty(event, 'ctrlKey', {get: () => true});
dispatchEvent(selectElement, event);
fixture.detectChanges();
expect(options.some(option => option.selected)).toBe(false);
expect(testInstance.control.value).toEqual([]);
});
});
});
+5
View File
@@ -19,6 +19,7 @@ import {
RIGHT_ARROW,
SPACE,
UP_ARROW,
A,
} from '@angular/cdk/keycodes';
import {
CdkConnectedOverlay,
@@ -705,6 +706,10 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
} else if ((keyCode === ENTER || keyCode === SPACE) && manager.activeItem) {
event.preventDefault();
manager.activeItem._selectViaInteraction();
} else if (this._multiple && keyCode === A && event.ctrlKey) {
event.preventDefault();
const hasDeselectedOptions = this.options.some(option => !option.selected);
this.options.forEach(option => hasDeselectedOptions ? option.select() : option.deselect());
} else {
const previouslyFocusedIndex = manager.activeItemIndex;