Skip to content

Commit 5596040

Browse files
fix: sync multi-select-combo-box top group on data change (#10445) (#10460)
Co-authored-by: Tomi Virkki <tomivirkki@users.noreply.github.com>
1 parent 62e5c1f commit 5596040

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ export const MultiSelectComboBoxMixin = (superClass) =>
7676
items: {
7777
type: Array,
7878
sync: true,
79+
observer: '__itemsChanged',
7980
},
8081

8182
/**
@@ -252,6 +253,7 @@ export const MultiSelectComboBoxMixin = (superClass) =>
252253
dataProvider: {
253254
type: Object,
254255
sync: true,
256+
observer: '__dataProviderChanged',
255257
},
256258

257259
/**
@@ -451,13 +453,30 @@ export const MultiSelectComboBoxMixin = (superClass) =>
451453
announce(this.i18n.cleared);
452454
}
453455

456+
/** @private */
457+
__syncTopGroup() {
458+
this._topGroup = this.selectedItemsOnTop ? [...this.selectedItems] : [];
459+
}
460+
454461
/**
455462
* Clears the cached pages and reloads data from data provider when needed.
456463
*/
457464
clearCache() {
458465
if (this.$ && this.$.comboBox) {
459466
this.$.comboBox.clearCache();
460467
}
468+
469+
this.__syncTopGroup();
470+
}
471+
472+
/** @private */
473+
__itemsChanged() {
474+
this.__syncTopGroup();
475+
}
476+
477+
/** @private */
478+
__dataProviderChanged() {
479+
this.__syncTopGroup();
461480
}
462481

463482
/**

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

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,28 @@ describe('selecting items', () => {
287287
comboBox.opened = true;
288288
expectItems(['apple', 'banana', 'lemon', 'orange']);
289289
});
290+
291+
it('should not include ghost items in the dropdown after items change', async () => {
292+
comboBox.opened = true;
293+
await nextRender();
294+
295+
comboBox.selectedItems = ['lemon'];
296+
comboBox.items = ['apple', 'banana', 'lemon'];
297+
await nextRender();
298+
299+
expectItems(['lemon', 'apple', 'banana']);
300+
});
301+
302+
it('should not update topgroup when deselecting while dropdown is opened', async () => {
303+
comboBox.opened = true;
304+
await nextRender();
305+
306+
// Clear selection
307+
comboBox.selectedItems = [];
308+
await nextRender();
309+
310+
expectItems(['lemon', 'orange', 'apple', 'banana']);
311+
});
290312
});
291313

292314
describe('object items', () => {
@@ -370,6 +392,36 @@ describe('selecting items', () => {
370392
comboBox.opened = true;
371393
expectItems(['apple', 'banana', 'lemon', 'orange']);
372394
});
395+
396+
it('should not include ghost items in the dropdown after clearing data provider cache', async () => {
397+
const allItems = ['apple', 'banana', 'lemon', 'orange'];
398+
comboBox.dataProvider = (_params, callback) => {
399+
callback(allItems, allItems.length);
400+
};
401+
402+
comboBox.opened = true;
403+
await nextRender();
404+
405+
allItems.pop(); // remove 'orange'
406+
comboBox.selectedItems = ['lemon'];
407+
expectItems(['lemon', 'orange', 'apple', 'banana']);
408+
409+
comboBox.clearCache();
410+
await nextRender();
411+
412+
expectItems(['lemon', 'apple', 'banana']);
413+
});
414+
415+
it('should not include ghost items in the dropdown after data provider change', async () => {
416+
comboBox.opened = true;
417+
await nextRender();
418+
419+
comboBox.selectedItems = ['lemon'];
420+
comboBox.dataProvider = getDataProvider(['apple', 'banana', 'lemon']);
421+
await nextRender();
422+
423+
expectItems(['lemon', 'apple', 'banana']);
424+
});
373425
});
374426

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

0 commit comments

Comments
 (0)