diff --git a/packages/main/cypress/specs/ComboBox.cy.tsx b/packages/main/cypress/specs/ComboBox.cy.tsx
index 3b241da6809b4..81ebd3acc83b4 100644
--- a/packages/main/cypress/specs/ComboBox.cy.tsx
+++ b/packages/main/cypress/specs/ComboBox.cy.tsx
@@ -4274,3 +4274,95 @@ describe("ComboBoxItemCustom - Accessibility", () => {
cy.get("[ui5-cb-item-custom]").shadow().find("li").should("not.have.attr", "tabindex", "0");
});
});
+
+describe("Newline normalization in item text", () => {
+ it("should fire change event twice when selecting two different items with newlines via keyboard", () => {
+ cy.mount(
+
+
+
+
+ );
+
+ cy.get("[ui5-combobox]")
+ .as("combobox")
+ .invoke("on", "ui5-change", cy.spy().as("changeSpy"));
+
+ cy.get("@combobox")
+ .shadow()
+ .find("[ui5-icon]")
+ .realClick();
+
+ cy.get("@combobox")
+ .shadow()
+ .find("[ui5-responsive-popover]")
+ .should("have.attr", "open");
+
+ cy.get("@combobox").realPress("ArrowDown");
+ cy.get("@combobox").realPress("Enter");
+
+ cy.get("@changeSpy").should("have.been.calledOnce");
+
+ cy.get("@combobox")
+ .shadow()
+ .find("[ui5-icon]")
+ .realClick();
+
+ cy.get("@combobox")
+ .shadow()
+ .find("[ui5-responsive-popover]")
+ .should("have.attr", "open");
+
+ cy.get("@combobox").realPress("ArrowDown");
+ cy.get("@combobox").realPress("ArrowDown");
+ cy.get("@combobox").realPress("Enter");
+
+ cy.get("@changeSpy").should("have.been.calledTwice");
+ });
+
+ it("should fire change event when selecting items with identical normalized display text but different values", () => {
+ cy.mount(
+
+
+
+
+ );
+
+ cy.get("[ui5-combobox]")
+ .as("combobox")
+ .invoke("on", "ui5-change", cy.spy().as("changeSpy"));
+
+ cy.get("[ui5-cb-item]").should("have.length", 2);
+
+ cy.get("@combobox")
+ .shadow()
+ .find("[ui5-icon]")
+ .realClick();
+
+ cy.get("@combobox")
+ .shadow()
+ .find("[ui5-responsive-popover]")
+ .should("have.attr", "open");
+
+ cy.get("@combobox").realPress("ArrowDown");
+ cy.get("@combobox").realPress("Enter");
+
+ cy.get("@changeSpy").should("have.been.calledOnce");
+
+ cy.get("@combobox")
+ .shadow()
+ .find("[ui5-icon]")
+ .realClick();
+
+ cy.get("@combobox")
+ .shadow()
+ .find("[ui5-responsive-popover]")
+ .should("have.attr", "open");
+
+ cy.get("@combobox").realPress("ArrowDown");
+ cy.get("@combobox").realPress("ArrowDown");
+ cy.get("@combobox").realPress("Enter");
+
+ cy.get("@changeSpy").should("have.been.calledTwice");
+ });
+});
diff --git a/packages/main/src/ComboBox.ts b/packages/main/src/ComboBox.ts
index 4924702d5ac99..af122d5e4feed 100644
--- a/packages/main/src/ComboBox.ts
+++ b/packages/main/src/ComboBox.ts
@@ -519,6 +519,7 @@ class ComboBox extends UI5Element implements IFormInputElement {
_selectionPerformed = false;
_selectionTrigger?: ComboBoxSelectionChangeTrigger;
_lastValue: string;
+ _lastSelectedValue?: string;
_selectedItemText = "";
_userTypedValue = "";
_useSelectedValue = false;
@@ -650,6 +651,7 @@ class ComboBox extends UI5Element implements IFormInputElement {
if (!e.relatedTarget || (e.relatedTarget !== this.shadowRoot!.querySelector(".ui5-input-clear-icon"))) {
this._lastValue = this.value;
+ this._lastSelectedValue = this.selectedValue;
}
!isPhone() && (e.target as HTMLInputElement).setSelectionRange(0, this.value.length);
@@ -713,6 +715,7 @@ class ComboBox extends UI5Element implements IFormInputElement {
if (this._selectionPerformed) {
this._lastValue = this.value;
+ this._lastSelectedValue = this.selectedValue;
this._selectionPerformed = false;
}
@@ -782,6 +785,7 @@ class ComboBox extends UI5Element implements IFormInputElement {
if (isPhone() && this.value && !this._lastValue) {
this._lastValue = this.value;
+ this._lastSelectedValue = this.selectedValue;
}
this._toggleRespPopover();
@@ -1400,9 +1404,13 @@ class ComboBox extends UI5Element implements IFormInputElement {
}
_fireChangeEvent() {
- if (this.value !== this._lastValue) {
+ const valueChanged = this.value !== this._lastValue;
+ const selectedValueChanged = this._useSelectedValue && this.selectedValue !== this._lastSelectedValue;
+
+ if (valueChanged || selectedValueChanged) {
this.fireDecoratorEvent("change");
this._lastValue = this.value;
+ this._lastSelectedValue = this.selectedValue;
}
}
@@ -1500,6 +1508,7 @@ class ComboBox extends UI5Element implements IFormInputElement {
if (this._isPhone) {
this._lastValue = "";
+ this._lastSelectedValue = undefined;
this.fireDecoratorEvent("change");
} else {
this.focus();
diff --git a/packages/main/test/pages/ComboBox.html b/packages/main/test/pages/ComboBox.html
index 96b7eb59f53e5..dae7010c1efc3 100644
--- a/packages/main/test/pages/ComboBox.html
+++ b/packages/main/test/pages/ComboBox.html
@@ -890,6 +890,37 @@
ComboBox with Mixed Items
+
+
Newline Normalization Test
+
Items with newlines in text that normalize to same display. Use Arrow keys + Enter to test.
+
+
+
Change events: 0
+
+
+
+