diff --git a/packages/main/cypress/specs/MultiComboBox.cy.tsx b/packages/main/cypress/specs/MultiComboBox.cy.tsx
index 2d551bc09259..4fd77461990f 100644
--- a/packages/main/cypress/specs/MultiComboBox.cy.tsx
+++ b/packages/main/cypress/specs/MultiComboBox.cy.tsx
@@ -219,8 +219,10 @@ describe("MultiComboBox RTL/LTR Arrow Navigation", () => {
.find("[ui5-tokenizer]")
.find("[ui5-token]")
.last()
- .should("be.visible")
- .should("be.focused");
+ .as ("lastToken");
+
+ cy.get("@lastToken").should("be.visible");
+ cy.get("@lastToken").should("be.focused");
});
it("should focus last token on arrow left in LTR mode when input is at start", () => {
@@ -263,8 +265,10 @@ describe("MultiComboBox RTL/LTR Arrow Navigation", () => {
.find("[ui5-tokenizer]")
.find("[ui5-token]")
.last()
- .should("be.visible")
- .should("be.focused");
+ .as ("lastToken");
+
+ cy.get("@lastToken").should("be.visible");
+ cy.get("@lastToken").should("be.focused");
});
it("should not focus token when cursor is not at start of input in RTL mode", () => {
@@ -283,7 +287,6 @@ describe("MultiComboBox RTL/LTR Arrow Navigation", () => {
.realClick();
cy.get("@mcb").should("be.focused");
-
cy.get("@mcb")
.shadow()
@@ -297,23 +300,14 @@ describe("MultiComboBox RTL/LTR Arrow Navigation", () => {
cy.get("@mcb").realPress("ArrowRight");
- cy.get("@mcb")
- .shadow()
- .find("input")
- .as("input")
- .realClick();
-
- cy.get("@input")
- .should("be.focused")
- .should(($input) => {
- expect(($input[0] as HTMLInputElement).selectionStart).to.equal(3);
- });
-
cy.get("@mcb")
.shadow()
.find("[ui5-tokenizer]")
.find("[ui5-token]")
- .should("not.be.focused");
+ .as ("lastToken");
+
+ cy.get("@lastToken").should("be.visible");
+ cy.get("@lastToken").should("not.be.focused");
});
it("should not focus token when text is selected in RTL mode", () => {
@@ -350,7 +344,10 @@ describe("MultiComboBox RTL/LTR Arrow Navigation", () => {
.shadow()
.find("[ui5-tokenizer]")
.find("[ui5-token]")
- .should("not.have.focus");
+ .as ("lastToken");
+
+ cy.get("@lastToken").should("be.visible");
+ cy.get("@lastToken").should("not.be.focused");
});
it("should navigate from last token back to input with arrow left in RTL mode", () => {
@@ -378,17 +375,13 @@ describe("MultiComboBox RTL/LTR Arrow Navigation", () => {
.find("[ui5-tokenizer]")
.find("[ui5-token]")
.last()
- .as("lastToken")
- .should("have.focus");
+ .as("lastToken");
- cy.get("@lastToken")
- .should("be.focused")
- .realPress("ArrowLeft");
+ cy.get("@lastToken").should("be.visible");
+ cy.get("@lastToken").should("be.focused");
+ cy.get("@lastToken").realPress("ArrowLeft");
- cy.get("@mcb")
- .shadow()
- .find("input")
- .should("be.focused");
+ cy.get("@mcb").should("be.focused");
});
it("should navigate from last token back to input with arrow right in LTR mode", () => {
@@ -416,15 +409,10 @@ describe("MultiComboBox RTL/LTR Arrow Navigation", () => {
.find("[ui5-tokenizer]")
.find("[ui5-token]")
.last()
- .as("lastToken")
- .should("be.focused");
-
- cy.get("@lastToken").realPress("ArrowRight");
+ .realPress("ArrowRight");
- cy.get("@mcb")
- .shadow()
- .find("input")
- .should("be.focused");
+ cy.get("@mcb").should("be.visible");
+ cy.get("@mcb").should("be.focused");
});
it("should handle empty input case in RTL mode", () => {
@@ -464,7 +452,11 @@ describe("MultiComboBox RTL/LTR Arrow Navigation", () => {
.find("[ui5-tokenizer]")
.find("[ui5-token]")
.last()
- .should("have.focus");
+ .as("lastToken");
+
+ cy.get("@lastToken").should("be.visible");
+ cy.get("@lastToken").should("be.focused");
+
});
});
diff --git a/packages/main/cypress/specs/Tokenizer.cy.tsx b/packages/main/cypress/specs/Tokenizer.cy.tsx
index dbc36b53f1ef..1c46d56e94ec 100644
--- a/packages/main/cypress/specs/Tokenizer.cy.tsx
+++ b/packages/main/cypress/specs/Tokenizer.cy.tsx
@@ -208,3 +208,99 @@ describe("Tokenizer - multi-line and Clear All", () => {
});
});
+describe("Tokenizer - Popover List Item Text Updates", () => {
+ it("updates list item text in popover when token text changes", () => {
+ cy.mount(
+
+
+
+
+
+
+
+
+
+ );
+
+ cy.get("[ui5-tokenizer]")
+ .shadow()
+ .find(".ui5-tokenizer-more-text")
+ .realClick();
+
+ cy.get("[ui5-tokenizer]")
+ .shadow()
+ .find("[ui5-responsive-popover]")
+ .should("be.visible");
+
+ cy.get("[ui5-tokenizer]")
+ .shadow()
+ .find("[ui5-responsive-popover] [ui5-list] [ui5-li]")
+ .eq(0)
+ .should("have.attr", "text", "Original Text");
+
+ cy.get("#token-to-modify").invoke("prop", "text", "Updated Text");
+
+ cy.get("[ui5-tokenizer]")
+ .shadow()
+ .find("[ui5-responsive-popover] [ui5-list] [ui5-li]")
+ .eq(0)
+ .should("have.attr", "text", "Updated Text");
+
+ cy.get("#test-token-text-update")
+ .shadow()
+ .find("[ui5-responsive-popover] [ui5-list] [ui5-li]")
+ .eq(0)
+ .should("not.have.attr", "text", "Original Text");
+ });
+
+ it("updates multiple list items when multiple token texts change", () => {
+ cy.mount(
+
+
+
+
+
+
+
+ );
+
+ cy.get("[ui5-tokenizer]")
+ .shadow()
+ .find(".ui5-tokenizer-more-text")
+ .realClick();
+
+ cy.get("[ui5-tokenizer]")
+ .shadow()
+ .find("[ui5-responsive-popover] [ui5-list] [ui5-li]")
+ .eq(0)
+ .should("have.attr", "text", "Token 1");
+
+ cy.get("[ui5-tokenizer]")
+ .shadow()
+ .find("[ui5-responsive-popover] [ui5-list] [ui5-li]")
+ .eq(1)
+ .should("have.attr", "text", "Token 2");
+
+ cy.get("[ui5-token]").eq(0).invoke("prop", "text", "Modified Token 1");
+ cy.get("[ui5-token]").eq(1).invoke("prop", "text", "Modified Token 2");
+
+ cy.get("[ui5-tokenizer]")
+ .shadow()
+ .find("[ui5-responsive-popover] [ui5-list] [ui5-li]")
+ .eq(0)
+ .should("have.attr", "text", "Modified Token 1");
+
+ cy.get("[ui5-tokenizer]")
+ .shadow()
+ .find("[ui5-responsive-popover] [ui5-list] [ui5-li]")
+ .eq(1)
+ .should("have.attr", "text", "Modified Token 2");
+
+ // Verify unchanged token remains the same
+ cy.get("[ui5-tokenizer]")
+ .shadow()
+ .find("[ui5-responsive-popover] [ui5-list] [ui5-li]")
+ .eq(2)
+ .should("have.attr", "text", "Token 3");
+ });
+});
diff --git a/packages/main/src/Tokenizer.ts b/packages/main/src/Tokenizer.ts
index da74d3d498bb..9cad4b2c9e98 100644
--- a/packages/main/src/Tokenizer.ts
+++ b/packages/main/src/Tokenizer.ts
@@ -333,6 +333,10 @@ class Tokenizer extends UI5Element {
type: HTMLElement,
"default": true,
individualSlots: true,
+ invalidateOnChildChange: {
+ properties: ["text"],
+ slots: false,
+ },
})
tokens!: Array;
diff --git a/packages/main/src/TokenizerPopoverTemplate.tsx b/packages/main/src/TokenizerPopoverTemplate.tsx
index 4fb138b0a7b9..58fa75b7b8d1 100644
--- a/packages/main/src/TokenizerPopoverTemplate.tsx
+++ b/packages/main/src/TokenizerPopoverTemplate.tsx
@@ -42,7 +42,7 @@ export default function TokenizerPopoverTemplate(this: Tokenizer) {
onItemDelete={this.itemDelete}
>
{this._tokens
- .map(token => {token.text})}
+ .map(token => )}
{this._isPhone &&