diff --git a/packages/main/cypress/specs/ToolbarSelect.cy.tsx b/packages/main/cypress/specs/ToolbarSelect.cy.tsx index 994165672765..f7c1fef6a698 100644 --- a/packages/main/cypress/specs/ToolbarSelect.cy.tsx +++ b/packages/main/cypress/specs/ToolbarSelect.cy.tsx @@ -344,4 +344,42 @@ describe("Toolbar general interaction", () => { .eq(0) .should("not.have.attr", "selected"); }); + + it("Should ensure only one option is selected at any time", () => { + cy.mount( + <> + + + 1 + 2 + 3 + + + + + ); + + // Set up button to attempt selecting multiple options + cy.get("#selectMultiple").then($btn => { + $btn.get(0).addEventListener("ui5-click", () => { + const opt1 = document.getElementById("opt1") as ToolbarSelectOption; + const opt2 = document.getElementById("opt2") as ToolbarSelectOption; + const opt3 = document.getElementById("opt3") as ToolbarSelectOption; + + // Try to select multiple options + opt1.selected = true; + opt2.selected = true; + opt3.selected = true; // This should be the final selection + }); + }); + + // Click button to attempt multiple selections + cy.get("#selectMultiple").realClick(); + + // Verify only the last option (opt3) is selected + cy.get("[ui5-toolbar-select-option]").eq(2).should("have.attr", "selected"); + cy.get("[ui5-toolbar-select-option]").eq(0).should("not.have.attr", "selected"); + cy.get("[ui5-toolbar-select-option]").eq(1).should("not.have.attr", "selected"); + cy.get("ui5-select", { includeShadowDom: true }).should("have.attr", "value", "3"); + }); }); \ No newline at end of file diff --git a/packages/main/src/ToolbarSelect.ts b/packages/main/src/ToolbarSelect.ts index cab2baea6341..ff3011be84ac 100644 --- a/packages/main/src/ToolbarSelect.ts +++ b/packages/main/src/ToolbarSelect.ts @@ -201,11 +201,7 @@ class ToolbarSelect extends ToolbarItem { _syncOptions(selectedOption: HTMLElement): void { const selectedOptionIndex = Number(selectedOption?.getAttribute("data-ui5-external-action-item-index")); this.options.forEach((option: ToolbarSelectOption, index: number) => { - if (index === selectedOptionIndex) { - option.setAttribute("selected", ""); - } else { - option.removeAttribute("selected"); - } + option.selected = index === selectedOptionIndex; }); } diff --git a/packages/main/src/ToolbarSelectOption.ts b/packages/main/src/ToolbarSelectOption.ts index 2bf45bfaee3b..1287701ac9cf 100644 --- a/packages/main/src/ToolbarSelectOption.ts +++ b/packages/main/src/ToolbarSelectOption.ts @@ -2,6 +2,7 @@ import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js"; import slot from "@ui5/webcomponents-base/dist/decorators/slot.js"; import property from "@ui5/webcomponents-base/dist/decorators/property.js"; +import type ToolbarSelect from "./ToolbarSelect.js"; /** * @class @@ -23,7 +24,32 @@ class ToolbarSelectOption extends UI5Element { * @public */ @property({ type: Boolean }) - selected = false; + set selected(value: boolean) { + if (value) { + this.setAttribute("selected", ""); + this._clearSiblingsAndSync(); + } else { + this.removeAttribute("selected"); + } + } + + get selected(): boolean { + return this.hasAttribute("selected"); + } + + _clearSiblingsAndSync(): void { + const parent = this.parentElement as ToolbarSelect; + if (parent) { + parent.options?.forEach(option => { + if (option !== this) { + option.removeAttribute("selected"); + } + }); + if (parent.select) { + parent.select.value = this.textContent || ""; + } + } + } /** * Defines the text of the component.