diff --git a/packages/main/cypress/specs/Toolbar.cy.tsx b/packages/main/cypress/specs/Toolbar.cy.tsx index 89a65d219b67..c8ee5c1d2a81 100644 --- a/packages/main/cypress/specs/Toolbar.cy.tsx +++ b/packages/main/cypress/specs/Toolbar.cy.tsx @@ -492,6 +492,40 @@ describe("Toolbar Select", () => { }); }); }); + + it("Should correctly handle the 'value' property and 'label' slot of ToolbarSelect", () => { + // Mount the Toolbar with a ToolbarSelect component + cy.mount( + + + Select an Option: + Option 1 + Option 2 + Option 3 + + + ); + + // Verify the initial value of the ToolbarSelect + cy.get("ui5-select", { includeShadowDom: true }) + .should("have.attr", "value", "Option 2"); + + // Verify the label slot content + cy.get("ui5-toolbar-select") + .find("span[slot='label']") + .should("contain.text", "Select an Option:"); + + // Change the value of the ToolbarSelect + cy.get("ui5-select", { includeShadowDom: true }) + .realClick() + .find("ui5-option") + .contains("Option 3") + .realClick(); + + // Verify the updated value of the ToolbarSelect + cy.get("ui5-select", { includeShadowDom: true }) + .should("have.attr", "value", "Option 3"); + }); }); describe("Toolbar Button", () => { diff --git a/packages/main/src/ToolbarSelect.ts b/packages/main/src/ToolbarSelect.ts index 79faa0f938eb..2279f95c8956 100644 --- a/packages/main/src/ToolbarSelect.ts +++ b/packages/main/src/ToolbarSelect.ts @@ -5,6 +5,7 @@ import slot from "@ui5/webcomponents-base/dist/decorators/slot.js"; import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js"; import type ValueState from "@ui5/webcomponents-base/dist/types/ValueState.js"; import ToolbarSelectCss from "./generated/themes/ToolbarSelect.css.js"; +import type Select from "./Select.js"; // Templates import ToolbarSelectTemplate from "./ToolbarSelectTemplate.js"; @@ -87,9 +88,22 @@ class ToolbarSelect extends ToolbarItem { * **Note:** Use the `ui5-toolbar-select-option` component to define the desired options. * @public */ - @slot({ "default": true, type: HTMLElement, invalidateOnChildChange: true }) + @slot({ + "default": true, + type: HTMLElement, + invalidateOnChildChange: true, + }) options!: Array; + /** + * Defines the HTML element that will be displayed in the component input part, + * representing the selected option. + * @public + * @since 2.13.0 + */ + @slot() + label!: Array; + /** * Defines the value state of the component. * @default "None" @@ -124,6 +138,34 @@ class ToolbarSelect extends ToolbarItem { @property() accessibleNameRef?: string; + /** + * Defines the value of the component: + * + * @public + * @default "" + * @since 2.13.0 + */ + @property() + set value(newValue: string) { + if (this.select && this.select.value !== newValue) { + const selectedOption = this.select.options.find(option => option.textContent === newValue); + this.select.value = newValue; + selectedOption && this.fireDecoratorEvent("change", { targetRef: this.select, selectedOption }); + } + this._value = newValue; + } + + get value(): string | undefined { + return this.select ? this.select.value : this._value; + } + + get select(): Select | null { + return this.shadowRoot!.querySelector this.onOpen(...args)} onChange={(...args) => this.onChange(...args)} > + {this.hasCustomLabel && + + + } {this.options.map((option, index) => (