Skip to content

Commit

Permalink
refactor: set initially focused index based on _dropdownItems (#6979)
Browse files Browse the repository at this point in the history
  • Loading branch information
vursen authored Dec 18, 2023
1 parent b35cfe1 commit 1c73649
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 33 deletions.
59 changes: 30 additions & 29 deletions packages/combo-box/src/vaadin-combo-box-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -1122,34 +1122,8 @@ export const ComboBoxMixin = (subclass) =>
}

/** @private */
_filteredItemsChanged(filteredItems, oldFilteredItems) {
_filteredItemsChanged(filteredItems) {
this._setDropdownItems(filteredItems);

// Store the currently focused item if any. The focused index preserves
// in the case when more filtered items are loading but it is reset
// when the user types in a filter query.
const focusedItem = oldFilteredItems ? oldFilteredItems[this._focusedIndex] : null;

// Try to sync `selectedItem` based on `value` once a new set of `filteredItems` is available
// (as a result of external filtering or when they have been loaded by the data provider).
// When `value` is specified but `selectedItem` is not, it means that there was no item
// matching `value` at the moment `value` was set, so `selectedItem` has remained unsynced.
const valueIndex = this.__getItemIndexByValue(filteredItems, this.value);
if ((this.selectedItem === null || this.selectedItem === undefined) && valueIndex >= 0) {
this.selectedItem = filteredItems[valueIndex];
}

// Try to first set focus on the item that had been focused before `filteredItems` were updated
// if it is still present in the `filteredItems` array. Otherwise, set the focused index
// depending on the selected item or the filter query.
const focusedItemIndex = this.__getItemIndexByValue(filteredItems, this._getItemValue(focusedItem));
if (focusedItemIndex > -1) {
this._focusedIndex = focusedItemIndex;
} else {
// When the user filled in something that is different from the current value = filtering is enabled,
// set the focused index to the item that matches the filter query.
this._focusedIndex = this.__getItemIndexByLabel(this.filteredItems, this.filter);
}
}

/** @private */
Expand Down Expand Up @@ -1191,8 +1165,35 @@ export const ComboBoxMixin = (subclass) =>
*
* @protected
*/
_setDropdownItems(items) {
this._dropdownItems = items;
_setDropdownItems(newItems) {
const oldItems = this._dropdownItems;
this._dropdownItems = newItems;

// Store the currently focused item if any. The focused index preserves
// in the case when more filtered items are loading but it is reset
// when the user types in a filter query.
const focusedItem = oldItems ? oldItems[this._focusedIndex] : null;

// Try to sync `selectedItem` based on `value` once a new set of `filteredItems` is available
// (as a result of external filtering or when they have been loaded by the data provider).
// When `value` is specified but `selectedItem` is not, it means that there was no item
// matching `value` at the moment `value` was set, so `selectedItem` has remained unsynced.
const valueIndex = this.__getItemIndexByValue(newItems, this.value);
if ((this.selectedItem === null || this.selectedItem === undefined) && valueIndex >= 0) {
this.selectedItem = newItems[valueIndex];
}

// Try to first set focus on the item that had been focused before `newItems` were updated
// if it is still present in the `newItems` array. Otherwise, set the focused index
// depending on the selected item or the filter query.
const focusedItemIndex = this.__getItemIndexByValue(newItems, this._getItemValue(focusedItem));
if (focusedItemIndex > -1) {
this._focusedIndex = focusedItemIndex;
} else {
// When the user filled in something that is different from the current value = filtering is enabled,
// set the focused index to the item that matches the filter query.
this._focusedIndex = this.__getItemIndexByLabel(newItems, this.filter);
}
}

/** @private */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,12 +175,12 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
*/
_setDropdownItems(items) {
if (this.readonly) {
this._dropdownItems = this.selectedItems;
super._setDropdownItems(this.selectedItems);
return;
}

if (this.filter || !this.selectedItemsOnTop) {
this._dropdownItems = items;
super._setDropdownItems(items);
return;
}

Expand All @@ -190,11 +190,11 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
(item) => this._comboBox._findIndex(item, this.topGroup, this.itemIdPath) === -1,
);

this._dropdownItems = this.topGroup.concat(filteredItems);
super._setDropdownItems(this.topGroup.concat(filteredItems));
return;
}

this._dropdownItems = items;
super._setDropdownItems(items);
}

/** @private */
Expand Down

0 comments on commit 1c73649

Please sign in to comment.