Skip to content

Commit 5250dd9

Browse files
authored
fix: sync multi-select-combo-box top group on data change (#10445)
1 parent 65514f3 commit 5250dd9

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

packages/multi-select-combo-box/src/vaadin-multi-select-combo-box-mixin.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,11 @@ export const MultiSelectComboBoxMixin = (superClass) =>
392392
announce(this.__effectiveI18n.cleared);
393393
}
394394

395+
/** @private */
396+
__syncTopGroup() {
397+
this._topGroup = this.selectedItemsOnTop ? [...this.selectedItems] : [];
398+
}
399+
395400
/**
396401
* Clears the cached pages and reloads data from data provider when needed.
397402
* @override
@@ -403,6 +408,18 @@ export const MultiSelectComboBoxMixin = (superClass) =>
403408
}
404409

405410
super.clearCache();
411+
412+
this.__syncTopGroup();
413+
}
414+
415+
/**
416+
* @private
417+
* @override
418+
*/
419+
_itemsChanged(items, oldItems) {
420+
super._itemsChanged(items, oldItems);
421+
422+
this.__syncTopGroup();
406423
}
407424

408425
/**

packages/multi-select-combo-box/test/selecting-items.test.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,28 @@ describe('selecting items', () => {
305305
comboBox.opened = true;
306306
expectItems(['apple', 'banana', 'lemon', 'orange']);
307307
});
308+
309+
it('should not include ghost items in the dropdown after items change', async () => {
310+
comboBox.opened = true;
311+
await nextRender();
312+
313+
comboBox.selectedItems = ['lemon'];
314+
comboBox.items = ['apple', 'banana', 'lemon'];
315+
await nextRender();
316+
317+
expectItems(['lemon', 'apple', 'banana']);
318+
});
319+
320+
it('should not update topgroup when deselecting while dropdown is opened', async () => {
321+
comboBox.opened = true;
322+
await nextRender();
323+
324+
// Clear selection
325+
comboBox.selectedItems = [];
326+
await nextRender();
327+
328+
expectItems(['lemon', 'orange', 'apple', 'banana']);
329+
});
308330
});
309331

310332
describe('object items', () => {
@@ -388,6 +410,36 @@ describe('selecting items', () => {
388410
comboBox.opened = true;
389411
expectItems(['apple', 'banana', 'lemon', 'orange']);
390412
});
413+
414+
it('should not include ghost items in the dropdown after clearing data provider cache', async () => {
415+
const allItems = ['apple', 'banana', 'lemon', 'orange'];
416+
comboBox.dataProvider = (_params, callback) => {
417+
callback(allItems, allItems.length);
418+
};
419+
420+
comboBox.opened = true;
421+
await nextRender();
422+
423+
allItems.pop(); // remove 'orange'
424+
comboBox.selectedItems = ['lemon'];
425+
expectItems(['lemon', 'orange', 'apple', 'banana']);
426+
427+
comboBox.clearCache();
428+
await nextRender();
429+
430+
expectItems(['lemon', 'apple', 'banana']);
431+
});
432+
433+
it('should not include ghost items in the dropdown after data provider change', async () => {
434+
comboBox.opened = true;
435+
await nextRender();
436+
437+
comboBox.selectedItems = ['lemon'];
438+
comboBox.dataProvider = getDataProvider(['apple', 'banana', 'lemon']);
439+
await nextRender();
440+
441+
expectItems(['lemon', 'apple', 'banana']);
442+
});
391443
});
392444

393445
describe('lazy loading', () => {

0 commit comments

Comments
 (0)