diff --git a/packages/main/src/ComboBox.ts b/packages/main/src/ComboBox.ts index c7bc268c62c0..3c67cd6b8c07 100644 --- a/packages/main/src/ComboBox.ts +++ b/packages/main/src/ComboBox.ts @@ -122,8 +122,11 @@ enum ValueStateIconMapping { Information = "information", } +type SelectionTrigger = "typeahead" | "keyboard" | "click"; + type ComboBoxSelectionChangeEventDetail = { item: ComboBoxItem | null, + trigger: SelectionTrigger, }; /** @@ -506,6 +509,7 @@ class ComboBox extends UI5Element implements IFormInputElement { _autocomplete = false; _isKeyNavigation = false; _selectionPerformed = false; + _selectionTrigger?: SelectionTrigger; _lastValue: string; _selectedItemText = ""; _userTypedValue = ""; @@ -962,6 +966,7 @@ class ComboBox extends UI5Element implements IFormInputElement { } _handleArrowDown(e: KeyboardEvent, indexOfItem: number) { + this._selectionTrigger = "keyboard"; const isOpen = this.open; if (this.focused && indexOfItem === -1 && isOpen) { @@ -983,6 +988,7 @@ class ComboBox extends UI5Element implements IFormInputElement { } _handleArrowUp(e: KeyboardEvent, indexOfItem: number) { + this._selectionTrigger = "keyboard"; const isOpen = this.open; if (indexOfItem === 0) { @@ -1002,6 +1008,7 @@ class ComboBox extends UI5Element implements IFormInputElement { } _handlePageUp(e: KeyboardEvent, indexOfItem: number) { + this._selectionTrigger = "keyboard"; const allItems = this._getItems(); const isProposedIndexValid = indexOfItem - SKIP_ITEMS_SIZE > -1; indexOfItem = isProposedIndexValid ? indexOfItem - SKIP_ITEMS_SIZE : 0; @@ -1011,6 +1018,7 @@ class ComboBox extends UI5Element implements IFormInputElement { } _handlePageDown(e: KeyboardEvent, indexOfItem: number) { + this._selectionTrigger = "keyboard"; const allItems = this._getItems(); const itemsLength = allItems.length; const isProposedIndexValid = indexOfItem + SKIP_ITEMS_SIZE < itemsLength; @@ -1022,12 +1030,14 @@ class ComboBox extends UI5Element implements IFormInputElement { } _handleHome(e: KeyboardEvent) { + this._selectionTrigger = "keyboard"; const shouldMoveForward = isInstanceOfComboBoxItemGroup(this._filteredItems[0]) && !this.open; this._handleItemNavigation(e, 0, shouldMoveForward); } _handleEnd(e: KeyboardEvent) { + this._selectionTrigger = "keyboard"; this._handleItemNavigation(e, this._getItems().length - 1, true /* isForward */); } @@ -1047,6 +1057,7 @@ class ComboBox extends UI5Element implements IFormInputElement { } if (isEnter(e)) { + this._selectionPerformed = true; let focusedItem: IComboBoxItem | undefined; this._filteredItems.forEach(item => { @@ -1351,22 +1362,23 @@ class ComboBox extends UI5Element implements IFormInputElement { } const noUserInteraction = !this.focused && !this._isKeyNavigation && !this._selectionPerformed && !this._iconPressed; - // Skip firing "selection-change" event if this is initial rendering or if there has been no user interaction yet if (this._initialRendering || noUserInteraction) { return; } - // Fire selection-change event only when selection actually changes if (previouslySelectedItem !== itemToBeSelected) { + const trigger = this._selectionTrigger || "typeahead"; + this._selectionTrigger = undefined; + if (itemToBeSelected) { - // New item selected this.fireDecoratorEvent("selection-change", { item: itemToBeSelected as ComboBoxItem, + trigger, }); } else if (previouslySelectedItem) { - // Selection cleared - fire event with 'null' this.fireDecoratorEvent("selection-change", { item: null, + trigger, }); } } @@ -1427,6 +1439,7 @@ class ComboBox extends UI5Element implements IFormInputElement { if (!item.selected) { this.fireDecoratorEvent("selection-change", { item, + trigger: "click", }); } diff --git a/packages/main/test/pages/ComboBox.html b/packages/main/test/pages/ComboBox.html index 0d2e49ee54cf..4c5a6ef28efe 100644 --- a/packages/main/test/pages/ComboBox.html +++ b/packages/main/test/pages/ComboBox.html @@ -517,6 +517,102 @@
The selection-change event includes a trigger property: "typeahead", "enter", "click", or "keyboard"