Skip to content
Open
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
66 changes: 65 additions & 1 deletion packages/main/cypress/specs/ToolbarSelect.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,70 @@ describe("Toolbar general interaction", () => {
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");
cy.get("[ui5-toolbar]")
.find("[ui5-toolbar-select]")
.shadow()
.find("[ui5-select]")
.find("[ui5-option]")
.eq(2)
.should("have.attr", "selected");
});

it("Should clear the inner select when value is set to empty string after render", () => {
cy.mount(
<Toolbar>
<ToolbarSelect value="Option 2">
<ToolbarSelectOption>Option 1</ToolbarSelectOption>
<ToolbarSelectOption>Option 2</ToolbarSelectOption>
<ToolbarSelectOption>Option 3</ToolbarSelectOption>
</ToolbarSelect>
</Toolbar>
);

cy.document().then(doc => {
const select = doc.querySelector("ui5-toolbar-select") as ToolbarSelect;
select.value = "";
});

cy.get("[ui5-toolbar]")
.find("[ui5-toolbar-select]")
.shadow()
.find("[ui5-select]")
.should("have.attr", "value", "");
});

it("Should not let stale _value override a later programmatic selected change", () => {
cy.mount(
<>
<Toolbar>
<ToolbarSelect value="Option 1">
<ToolbarSelectOption id="prog-opt1">Option 1</ToolbarSelectOption>
<ToolbarSelectOption id="prog-opt2">Option 2</ToolbarSelectOption>
<ToolbarSelectOption id="prog-opt3">Option 3</ToolbarSelectOption>
</ToolbarSelect>
</Toolbar>
<Button id="prog-btn">Select Option 3</Button>
</>
);

cy.get("#prog-btn").then($btn => {
$btn.get(0).addEventListener("click", () => {
const options = document.querySelectorAll("ui5-toolbar-select-option");
options.forEach(opt => { (opt as ToolbarSelectOption).selected = false; });
(document.getElementById("prog-opt3") as ToolbarSelectOption).selected = true;
});
});

cy.get("#prog-btn").realClick();

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]")
.find("[ui5-toolbar-select]")
.shadow()
.find("[ui5-select]")
.find("[ui5-option]")
.eq(2)
.should("have.attr", "selected");
});
});
41 changes: 37 additions & 4 deletions packages/main/src/ToolbarSelect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,14 +154,22 @@ class ToolbarSelect extends ToolbarItemBase {
*/
@property()
set value(newValue: string) {
if (this.select && this.select.value !== newValue) {
this.select.value = newValue;
if (this.select) {
if (this.select.value !== newValue) {
this.select.value = newValue;
}
this._value = "";
} else {
this._value = newValue;
}
this._value = newValue;
}

get value(): string | undefined {
return this.select ? this.select.value : this._value;
if (this._value) {
return this._value;
}
const selectedOption = this.options.find(o => o.selected);
return selectedOption?.textContent || this.select?.value || "";
}

get select(): Select | null {
Expand Down Expand Up @@ -195,6 +203,30 @@ class ToolbarSelect extends ToolbarItemBase {
}
}

onBeforeRendering(): void {
super.onBeforeRendering();
let lastSelectedIndex = -1;
this.options.forEach((option, index) => {
if (option.selected) {
lastSelectedIndex = index;
}
});
this.options.forEach((option, index) => {
const shouldBeSelected = index === lastSelectedIndex;
if (option.selected !== shouldBeSelected) {
option.selected = shouldBeSelected;
}
});
}

onAfterRendering(): void {
super.onAfterRendering();
if (this._value && this.select) {
this.select.value = this._value;
this._value = "";
}
}

onChange(e: CustomEvent<SelectChangeEventDetail>): void {
e.stopImmediatePropagation();
const selectedOptionIndex = Number(e.detail.selectedOption?.getAttribute("data-ui5-external-action-item-index"));
Expand All @@ -208,6 +240,7 @@ class ToolbarSelect extends ToolbarItemBase {
}

_syncOptions(selectedOptionIndex: number): void {
this._value = "";
this.options.forEach((option: ToolbarSelectOption, index: number) => {
option.selected = index === selectedOptionIndex;
});
Expand Down
28 changes: 1 addition & 27 deletions packages/main/src/ToolbarSelectOption.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import type { DefaultSlot } 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-strict.js";
import property from "@ui5/webcomponents-base/dist/decorators/property.js";
import type ToolbarSelect from "./ToolbarSelect.js";

/**
* @class
Expand Down Expand Up @@ -34,32 +33,7 @@ class ToolbarSelectOption extends UI5Element {
* @public
*/
@property({ type: Boolean })
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.value !== undefined && this.value !== "" ? this.value : (this.textContent || "");
}
}
}
selected = false;

/**
* Defines the text of the component.
Expand Down
1 change: 0 additions & 1 deletion packages/main/src/ToolbarSelectTemplate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ export default function ToolbarSelectTemplate(this: ToolbarSelect) {
<Select
class={this.classes.root}
style={this.styles}
value={this.value}
data-ui5-external-action-item-id={this._id}
valueState={this.valueState}
disabled={this.disabled}
Expand Down
Loading