Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: calculate initially focused index based on _dropdownItems #6979

Merged
merged 1 commit into from
Dec 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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