Skip to content

Commit ae6e930

Browse files
authored
feat(material/list): return selected options from selection list selectAll/deselectAll (#21358)
Returns an array of the changed options from the list's `selectAll` and `deselectAll`. This is information we have already so exposing it is trivial and makes some use cases slightly easier. Fixes #21356.
1 parent 9dbf49b commit ae6e930

File tree

5 files changed

+31
-23
lines changed

5 files changed

+31
-23
lines changed

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -418,10 +418,11 @@ describe('MDC-based MatSelectionList without forms', () => {
418418

419419
expect(list.options.toArray().every(option => option.selected)).toBe(false);
420420

421-
list.selectAll();
421+
const result = list.selectAll();
422422
fixture.detectChanges();
423423

424424
expect(list.options.toArray().every(option => option.selected)).toBe(true);
425+
expect(result).toEqual(list.options.toArray());
425426
});
426427

427428
it('should be able to select all options, even if they are disabled', () => {
@@ -444,10 +445,11 @@ describe('MDC-based MatSelectionList without forms', () => {
444445
list.options.forEach(option => option.toggle());
445446
expect(list.options.toArray().every(option => option.selected)).toBe(true);
446447

447-
list.deselectAll();
448+
const result = list.deselectAll();
448449
fixture.detectChanges();
449450

450451
expect(list.options.toArray().every(option => option.selected)).toBe(false);
452+
expect(result).toEqual(list.options.toArray());
451453
});
452454

453455
it('should be able to deselect all options, even if they are disabled', () => {

src/material-experimental/mdc-list/selection-list.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -192,14 +192,14 @@ export class MatSelectionList extends MatInteractiveListBase<MatListOption>
192192
this._element.nativeElement.focus(options);
193193
}
194194

195-
/** Selects all of the options. */
196-
selectAll() {
197-
this._setAllOptionsSelected(true);
195+
/** Selects all of the options. Returns the options that changed as a result. */
196+
selectAll(): MatListOption[] {
197+
return this._setAllOptionsSelected(true);
198198
}
199199

200-
/** Deselects all of the options. */
201-
deselectAll() {
202-
this._setAllOptionsSelected(false);
200+
/** Deselects all of the options. Returns the options that changed as a result. */
201+
deselectAll(): MatListOption[] {
202+
return this._setAllOptionsSelected(false);
203203
}
204204

205205
/** Reports a value change to the ControlValueAccessor */
@@ -306,20 +306,22 @@ export class MatSelectionList extends MatInteractiveListBase<MatListOption>
306306
* Sets the selected state on all of the options
307307
* and emits an event if anything changed.
308308
*/
309-
private _setAllOptionsSelected(isSelected: boolean, skipDisabled?: boolean) {
309+
private _setAllOptionsSelected(isSelected: boolean, skipDisabled?: boolean): MatListOption[] {
310310
// Keep track of whether anything changed, because we only want to
311311
// emit the changed event when something actually changed.
312-
let hasChanged = false;
312+
const changedOptions: MatListOption[] = [];
313313

314314
this.options.forEach(option => {
315315
if ((!skipDisabled || !option.disabled) && option._setSelected(isSelected)) {
316-
hasChanged = true;
316+
changedOptions.push(option);
317317
}
318318
});
319319

320-
if (hasChanged) {
320+
if (changedOptions.length) {
321321
this._reportValueChange();
322322
}
323+
324+
return changedOptions;
323325
}
324326

325327
// Note: This getter exists for backwards compatibility. The `_items` query list

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -655,10 +655,11 @@ describe('MatSelectionList without forms', () => {
655655

656656
expect(list.options.toArray().every(option => option.selected)).toBe(false);
657657

658-
list.selectAll();
658+
const result = list.selectAll();
659659
fixture.detectChanges();
660660

661661
expect(list.options.toArray().every(option => option.selected)).toBe(true);
662+
expect(result).toEqual(list.options.toArray());
662663
});
663664

664665
it('should be able to select all options, even if they are disabled', () => {
@@ -681,10 +682,11 @@ describe('MatSelectionList without forms', () => {
681682
list.options.forEach(option => option.toggle());
682683
expect(list.options.toArray().every(option => option.selected)).toBe(true);
683684

684-
list.deselectAll();
685+
const result = list.deselectAll();
685686
fixture.detectChanges();
686687

687688
expect(list.options.toArray().every(option => option.selected)).toBe(false);
689+
expect(result).toEqual(list.options.toArray());
688690
});
689691

690692
it('should be able to deselect all options, even if they are disabled', () => {

src/material/list/selection-list.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -517,14 +517,14 @@ export class MatSelectionList extends _MatSelectionListMixinBase implements CanD
517517
this._element.nativeElement.focus(options);
518518
}
519519

520-
/** Selects all of the options. */
521-
selectAll() {
522-
this._setAllOptionsSelected(true);
520+
/** Selects all of the options. Returns the options that changed as a result. */
521+
selectAll(): MatListOption[] {
522+
return this._setAllOptionsSelected(true);
523523
}
524524

525-
/** Deselects all of the options. */
526-
deselectAll() {
527-
this._setAllOptionsSelected(false);
525+
/** Deselects all of the options. Returns the options that changed as a result. */
526+
deselectAll(): MatListOption[] {
527+
return this._setAllOptionsSelected(false);
528528
}
529529

530530
/** Sets the focused option of the selection-list. */
@@ -672,7 +672,7 @@ export class MatSelectionList extends _MatSelectionListMixinBase implements CanD
672672
private _setAllOptionsSelected(
673673
isSelected: boolean,
674674
skipDisabled?: boolean,
675-
isUserInput?: boolean) {
675+
isUserInput?: boolean): MatListOption[] {
676676
// Keep track of whether anything changed, because we only want to
677677
// emit the changed event when something actually changed.
678678
const changedOptions: MatListOption[] = [];
@@ -690,6 +690,8 @@ export class MatSelectionList extends _MatSelectionListMixinBase implements CanD
690690
this._emitChangeEvent(changedOptions);
691691
}
692692
}
693+
694+
return changedOptions;
693695
}
694696

695697
/**

tools/public_api_guard/material/list.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,14 @@ export declare class MatSelectionList extends _MatSelectionListMixinBase impleme
123123
_removeOptionFromList(option: MatListOption): MatListOption | null;
124124
_reportValueChange(): void;
125125
_setFocusedOption(option: MatListOption): void;
126-
deselectAll(): void;
126+
deselectAll(): MatListOption[];
127127
focus(options?: FocusOptions): void;
128128
ngAfterContentInit(): void;
129129
ngOnChanges(changes: SimpleChanges): void;
130130
ngOnDestroy(): void;
131131
registerOnChange(fn: (value: any) => void): void;
132132
registerOnTouched(fn: () => void): void;
133-
selectAll(): void;
133+
selectAll(): MatListOption[];
134134
setDisabledState(isDisabled: boolean): void;
135135
writeValue(values: string[]): void;
136136
static ngAcceptInputType_disableRipple: BooleanInput;

0 commit comments

Comments
 (0)