Skip to content

Commit c1f9b05

Browse files
committed
fix(mat-selection-list): do not allow ctrl + a when mat-selection-list/mat-list-option is disabled
1 parent 1e1751f commit c1f9b05

File tree

2 files changed

+46
-8
lines changed

2 files changed

+46
-8
lines changed

src/lib/list/selection-list.spec.ts

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -331,10 +331,10 @@ describe('MatSelectionList without forms', () => {
331331
dispatchEvent(selectionList.nativeElement, event);
332332
fixture.detectChanges();
333333

334-
expect(listOptions.every(option => option.componentInstance.selected)).toBe(true);
334+
expect(listOptions.filter(option => option.componentInstance.selected).length).toBe(3);
335335
});
336336

337-
it('should select all items using ctrl + a if some items are selected', () => {
337+
it('should select all items using ctrl + a if some options are selected', () => {
338338
const event = createKeyboardEvent('keydown', A, selectionList.nativeElement);
339339
Object.defineProperty(event, 'ctrlKey', {get: () => true});
340340

@@ -364,6 +364,23 @@ describe('MatSelectionList without forms', () => {
364364
expect(listOptions.every(option => option.componentInstance.selected)).toBe(false);
365365
});
366366

367+
it('should select only non-disabled options when using ctrl + a', () => {
368+
const event = createKeyboardEvent('keydown', A, selectionList.nativeElement);
369+
Object.defineProperty(event, 'ctrlKey', {get: () => true});
370+
371+
const selectList =
372+
selectionList.injector.get<MatSelectionList>(MatSelectionList).selectedOptions;
373+
374+
expect(selectList.selected.length).toBe(0);
375+
expect(listOptions[0].componentInstance.selected).toBe(false);
376+
377+
dispatchEvent(selectionList.nativeElement, event);
378+
fixture.detectChanges();
379+
380+
expect(selectList.selected.length).toBe(3);
381+
expect(listOptions[0].componentInstance.selected).toBe(false);
382+
});
383+
367384
it('should be able to jump focus down to an item by typing', fakeAsync(() => {
368385
const listEl = selectionList.nativeElement;
369386
const manager = selectionList.componentInstance._keyManager;
@@ -391,7 +408,7 @@ describe('MatSelectionList without forms', () => {
391408
list.selectAll();
392409
fixture.detectChanges();
393410

394-
expect(list.options.toArray().every(option => option.selected)).toBe(true);
411+
expect(list.options.toArray().filter(option => option.selected).length).toBe(3);
395412
});
396413

397414
it('should be able to deselect all options', () => {
@@ -628,6 +645,21 @@ describe('MatSelectionList without forms', () => {
628645
expect(selectList.selected.length).toBe(0);
629646
});
630647

648+
it('should not allow select all using ctrl + a on disabled selection-list', () => {
649+
const event = createKeyboardEvent('keydown', A, selectionList.nativeElement);
650+
Object.defineProperty(event, 'ctrlKey', {get: () => true});
651+
652+
const selectList =
653+
selectionList.injector.get<MatSelectionList>(MatSelectionList).selectedOptions;
654+
655+
expect(selectList.selected.length).toBe(0);
656+
657+
dispatchEvent(selectionList.nativeElement, event);
658+
fixture.detectChanges();
659+
660+
expect(selectList.selected.length).toBe(0);
661+
});
662+
631663
it('should update state of options if list state has changed', () => {
632664
// To verify that the template of the list options has been re-rendered after the disabled
633665
// property of the selection list has been updated, the ripple directive can be used.

src/lib/list/selection-list.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -518,11 +518,17 @@ export class MatSelectionList extends _MatSelectionListMixinBase implements Focu
518518
// emit the changed event when something actually changed.
519519
let hasChanged = false;
520520

521-
this.options.forEach(option => {
522-
if (option._setSelected(isSelected)) {
523-
hasChanged = true;
524-
}
525-
});
521+
// Don't change selected state if MatSelectionList is disabled
522+
if (!this.disabled) {
523+
this.options.forEach(option => {
524+
// Don't change selected state if MatListOption is disabled.
525+
if (!option.disabled) {
526+
if (option._setSelected(isSelected)) {
527+
hasChanged = true;
528+
}
529+
}
530+
});
531+
}
526532

527533
if (hasChanged) {
528534
this._reportValueChange();

0 commit comments

Comments
 (0)