Skip to content
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
38 changes: 38 additions & 0 deletions packages/main/cypress/specs/ToolbarSelect.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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(
<>
<Toolbar>
<ToolbarSelect>
<ToolbarSelectOption id="opt1">1</ToolbarSelectOption>
<ToolbarSelectOption id="opt2">2</ToolbarSelectOption>
<ToolbarSelectOption id="opt3">3</ToolbarSelectOption>
</ToolbarSelect>
</Toolbar>
<Button id="selectMultiple">Select Multiple</Button>
</>
);

// 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");
});
});
6 changes: 1 addition & 5 deletions packages/main/src/ToolbarSelect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
});
}

Expand Down
28 changes: 27 additions & 1 deletion packages/main/src/ToolbarSelectOption.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand Down
Loading