Skip to content

Commit 668a2b4

Browse files
authored
fix(cdk-experimental/ui-patterns): deselectAll unavailable items (angular#31734)
* Change deselectAll to deselect values that are not accounted for in the items array.
1 parent c5f1705 commit 668a2b4

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

src/cdk-experimental/ui-patterns/behaviors/list-selection/list-selection.spec.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,13 @@ describe('List Selection', () => {
168168
selection.deselectAll(); // []
169169
expect(selection.inputs.value().length).toBe(0);
170170
});
171+
172+
it('should deselect items that are not in the list', () => {
173+
const selection = getSelection({multi: signal(true)});
174+
selection.inputs.value.update(() => [5]);
175+
selection.deselectAll();
176+
expect(selection.inputs.value().length).toBe(0);
177+
});
171178
});
172179

173180
describe('#toggleAll', () => {

src/cdk-experimental/ui-patterns/behaviors/list-selection/list-selection.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,25 @@ export class ListSelection<T extends ListSelectionItem<V>, V> {
102102

103103
/** Deselects all items in the list. */
104104
deselectAll() {
105-
for (const item of this.inputs.items()) {
106-
this.deselect(item);
105+
// If an item is not in the list, it forcefully gets deselected.
106+
// This actually creates a bug for the following edge case:
107+
//
108+
// Setup: An item is not in the list (maybe it's lazily loaded), and it is disabled & selected.
109+
// Expected: If deselectAll() is called, it should NOT get deselected (because it is disabled).
110+
// Actual: Calling deselectAll() will still deselect the item.
111+
//
112+
// Why? Because we can't check if the item is disabled if it's not in the list.
113+
//
114+
// Alternatively, we could NOT deselect items that are not in the list, but this has the
115+
// inverse (and more common) effect of keeping enabled items selected when they aren't in the
116+
// list.
117+
118+
for (const value of this.inputs.value()) {
119+
const item = this.inputs.items().find(i => i.value() === value);
120+
121+
item
122+
? this.deselect(item)
123+
: this.inputs.value.update(values => values.filter(v => v !== value));
107124
}
108125
}
109126

0 commit comments

Comments
 (0)