Skip to content

Commit 503e0eb

Browse files
volvachevEgor Volvachev
authored andcommitted
fix(material/list): add command+A for MacOs "select all" functionality.
Fixes a bug in Angular Material `list` when using MacOs `command`+`a` does not work for 'select all functionality'. Fixes #24781
1 parent 4193037 commit 503e0eb

File tree

2 files changed

+83
-1
lines changed

2 files changed

+83
-1
lines changed

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

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,88 @@ describe('MatSelectionList without forms', () => {
594594
);
595595
});
596596

597+
it('should select all items using command(metaKey) + a', () => {
598+
listOptions.forEach(option => (option.componentInstance.disabled = false));
599+
const event = createKeyboardEvent('keydown', A, undefined, {meta: true});
600+
601+
expect(listOptions.some(option => option.componentInstance.selected)).toBe(false);
602+
603+
dispatchEvent(selectionList.nativeElement, event);
604+
fixture.detectChanges();
605+
606+
expect(listOptions.every(option => option.componentInstance.selected)).toBe(true);
607+
});
608+
609+
it('should not select disabled items when pressing command(metaKey) + a', () => {
610+
const event = createKeyboardEvent('keydown', A, undefined, {meta: true});
611+
612+
listOptions.slice(0, 2).forEach(option => (option.componentInstance.disabled = true));
613+
fixture.detectChanges();
614+
615+
expect(listOptions.map(option => option.componentInstance.selected)).toEqual([
616+
false,
617+
false,
618+
false,
619+
false,
620+
false,
621+
]);
622+
623+
dispatchEvent(selectionList.nativeElement, event);
624+
fixture.detectChanges();
625+
626+
expect(listOptions.map(option => option.componentInstance.selected)).toEqual([
627+
false,
628+
false,
629+
true,
630+
true,
631+
true,
632+
]);
633+
});
634+
635+
it('should select all items using command(metaKey) + a if some items are selected', () => {
636+
const event = createKeyboardEvent('keydown', A, undefined, {meta: true});
637+
638+
listOptions.slice(0, 2).forEach(option => (option.componentInstance.selected = true));
639+
fixture.detectChanges();
640+
641+
expect(listOptions.some(option => option.componentInstance.selected)).toBe(true);
642+
643+
dispatchEvent(selectionList.nativeElement, event);
644+
fixture.detectChanges();
645+
646+
expect(listOptions.every(option => option.componentInstance.selected)).toBe(true);
647+
});
648+
649+
it('should deselect all with command(metaKey) + a if all options are selected', () => {
650+
const event = createKeyboardEvent('keydown', A, undefined, {meta: true});
651+
652+
listOptions.forEach(option => (option.componentInstance.selected = true));
653+
fixture.detectChanges();
654+
655+
expect(listOptions.every(option => option.componentInstance.selected)).toBe(true);
656+
657+
dispatchEvent(selectionList.nativeElement, event);
658+
fixture.detectChanges();
659+
660+
expect(listOptions.every(option => option.componentInstance.selected)).toBe(false);
661+
});
662+
663+
it('should dispatch the selectionChange event when selecting via command(metaKey) + a', () => {
664+
const spy = spyOn(fixture.componentInstance, 'onSelectionChange');
665+
listOptions.forEach(option => (option.componentInstance.disabled = false));
666+
const event = createKeyboardEvent('keydown', A, undefined, {meta: true});
667+
668+
dispatchEvent(selectionList.nativeElement, event);
669+
fixture.detectChanges();
670+
671+
expect(spy).toHaveBeenCalledTimes(1);
672+
expect(spy).toHaveBeenCalledWith(
673+
jasmine.objectContaining({
674+
options: listOptions.map(option => option.componentInstance),
675+
}),
676+
);
677+
});
678+
597679
it('should be able to jump focus down to an item by typing', fakeAsync(() => {
598680
const listEl = selectionList.nativeElement;
599681
const manager = selectionList.componentInstance._keyManager;

src/material/list/selection-list.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ export class MatSelectionList
573573
if (
574574
keyCode === A &&
575575
this.multiple &&
576-
hasModifierKey(event, 'ctrlKey') &&
576+
hasModifierKey(event, 'ctrlKey', 'metaKey') &&
577577
!manager.isTyping()
578578
) {
579579
const shouldSelect = this.options.some(option => !option.disabled && !option.selected);

0 commit comments

Comments
 (0)