diff --git a/packages/main/cypress/specs/Toolbar.cy.tsx b/packages/main/cypress/specs/Toolbar.cy.tsx
index 6d54e72cf7c6..ef51d3385bea 100644
--- a/packages/main/cypress/specs/Toolbar.cy.tsx
+++ b/packages/main/cypress/specs/Toolbar.cy.tsx
@@ -4,7 +4,7 @@ import ToolbarSelect from "../../src/ToolbarSelect.js";
import ToolbarSelectOption from "../../src/ToolbarSelectOption.js";
import ToolbarSeparator from "../../src/ToolbarSeparator.js";
import ToolbarSpacer from "../../src/ToolbarSpacer.js";
-import type ToolbarItem from "../../src/ToolbarItem.js";
+import ToolbarItem from "../../src/ToolbarItem.js";
import add from "@ui5/webcomponents-icons/dist/add.js";
import decline from "@ui5/webcomponents-icons/dist/decline.js";
import employee from "@ui5/webcomponents-icons/dist/employee.js";
@@ -617,3 +617,126 @@ describe("Toolbar Button", () => {
});
});
});
+
+describe("Toolbar Item", () => {
+ it("Should render ui5-toolbar-item with correct properties and not suppress events", () => {
+ // Mount the Toolbar with a ui5-toolbar-item wrapping a web component
+ cy.mount(
+
+
+
+
+
+ );
+
+ // Verify the ui5-toolbar-item has the correct properties
+ cy.get("ui5-toolbar-item").should((item) => {
+ expect(item).to.have.attr("prevent-overflow-closing");
+ expect(item).to.have.attr("overflow-priority", "AlwaysOverflow");
+ });
+
+ // Verify the inner component (ui5-button) is rendered
+ cy.get("ui5-toolbar-item")
+ .find("ui5-button").should((button) => {
+ expect(button).to.exist;
+ expect(button).to.contain.text("User Menu");
+ });
+
+ // Attach a click event to the inner button
+ cy.get("ui5-button#innerButton")
+ .then(button => {
+ button.get(0).addEventListener("click", cy.stub().as("buttonClicked"));
+ });
+
+ // Trigger a click event on the inner button
+ cy.get("ui5-button#innerButton").click();
+
+ // Verify the click event was triggered
+ cy.get("@buttonClicked").should("have.been.calledOnce");
+ });
+
+ it("Should respect prevent-overflow-closing property", () => {
+ // Mount the Toolbar with constrained width to force overflow
+ cy.mount(
+
+
+
+
+
+
+
+
+
+
+ );
+
+ // Wait for overflow processing
+ cy.wait(500);
+
+ // Click the overflow button to open the popover
+ cy.get("ui5-toolbar")
+ .shadow()
+ .find(".ui5-tb-overflow-btn")
+ .click();
+
+ // Verify the popover is open
+ cy.get("ui5-toolbar")
+ .shadow()
+ .find(".ui5-overflow-popover")
+ .should("have.prop", "open", true);
+
+ // Click on the item with prevent-overflow-closing
+ cy.get("ui5-toolbar-item[prevent-overflow-closing]")
+ .find("ui5-button")
+ .click();
+
+ // Verify the popover remains open
+ cy.get("ui5-toolbar")
+ .shadow()
+ .find(".ui5-overflow-popover")
+ .should("have.prop", "open", true);
+
+ // Optional: Test that normal items still close the popover
+ cy.get("ui5-toolbar-item:not([prevent-overflow-closing])")
+ .find("ui5-button")
+ .click();
+
+ // Verify the popover closes
+ cy.get("ui5-toolbar")
+ .shadow()
+ .find(".ui5-overflow-popover")
+ .should("have.prop", "open", false);
+ });
+
+ it("Should respect overflow-priority property", () => {
+ // Mount the Toolbar with multiple ui5-toolbar-items
+ cy.mount(
+
+
+
+
+
+
+
+
+ );
+
+ // Verify the overflow-priority property is respected
+ cy.get("ui5-toolbar-item[overflow-priority='AlwaysOverflow']")
+ .should("exist")
+ .should("have.attr", "overflow-priority", "AlwaysOverflow");
+
+ cy.get("ui5-toolbar-item[overflow-priority='NeverOverflow']")
+ .should("exist")
+ .should("have.attr", "overflow-priority", "NeverOverflow");
+
+ // Simulate overflow behavior and ensure high-priority item remains visible
+ cy.viewport(300, 1080); // Simulate a smaller viewport
+ cy.get("ui5-toolbar-item[overflow-priority='NeverOverflow']")
+ .should("be.visible");
+
+ // Ensure low-priority item is hidden or moved to overflow
+ cy.get("ui5-toolbar-item[overflow-priority='AlwaysOverflow']")
+ .should("not.be.visible");
+ });
+})
diff --git a/packages/main/src/ToolbarItem.ts b/packages/main/src/ToolbarItem.ts
index db9f5057e015..6bac1967fab1 100644
--- a/packages/main/src/ToolbarItem.ts
+++ b/packages/main/src/ToolbarItem.ts
@@ -1,6 +1,10 @@
import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js";
import property from "@ui5/webcomponents-base/dist/decorators/property.js";
import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js";
+import slot from "@ui5/webcomponents-base/dist/decorators/slot.js";
+import jsxRenderer from "@ui5/webcomponents-base/dist/renderer/JsxRenderer.js";
+import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js";
+import ToolbarItemTemplate from "./ToolbarItemTemplate.js";
import type ToolbarItemOverflowBehavior from "./types/ToolbarItemOverflowBehavior.js";
@@ -16,13 +20,19 @@ type ToolbarItemEventDetail = {
bubbles: true,
})
+@customElement({
+ tag: "ui5-toolbar-item",
+ languageAware: true,
+ renderer: jsxRenderer,
+ template: ToolbarItemTemplate,
+})
+
/**
* @class
*
* Represents an abstract class for items, used in the `ui5-toolbar`.
* @constructor
* @extends UI5Element
- * @abstract
* @public
* @since 1.17.0
*/
@@ -65,6 +75,17 @@ class ToolbarItem extends UI5Element {
onAfterRendering(): void {
this._isRendering = false;
}
+ /**
+ * Wrapped component slot.
+ * @public
+ * @since 2.15.0
+ */
+
+ @slot({
+ "default": true, type: HTMLElement, invalidateOnChildChange: true,
+ })
+ item!: HTMLElement | undefined;
+
/**
* Defines if the width of the item should be ignored in calculating the whole width of the toolbar
* @protected
@@ -112,10 +133,26 @@ class ToolbarItem extends UI5Element {
},
};
}
+
+ constructor() {
+ super();
+ }
+
+ /**
+ * Handles the click event on the toolbar item.
+ * If `preventOverflowClosing` is false, it will fire a "close-overflow" event.
+ */
+ onClick(e?: Event): void {
+ if (e && !this.preventOverflowClosing) {
+ this.fireDecoratorEvent("close-overflow");
+ }
+ }
}
export type {
IEventOptions,
ToolbarItemEventDetail,
};
+ToolbarItem.define();
+
export default ToolbarItem;
diff --git a/packages/main/src/ToolbarItemTemplate.tsx b/packages/main/src/ToolbarItemTemplate.tsx
new file mode 100644
index 000000000000..12126b0b4f48
--- /dev/null
+++ b/packages/main/src/ToolbarItemTemplate.tsx
@@ -0,0 +1,9 @@
+import type ToolbarItem from "./ToolbarItem.js";
+
+export default function ToolbarItemTemplate(this: ToolbarItem) {
+ return (
+
+
+
+ );
+}
diff --git a/packages/main/test/pages/Toolbar.html b/packages/main/test/pages/Toolbar.html
index de6b72c48bcf..8dcbe57ea41e 100644
--- a/packages/main/test/pages/Toolbar.html
+++ b/packages/main/test/pages/Toolbar.html
@@ -77,7 +77,9 @@
-
+
+ Call me later
+
diff --git a/packages/main/test/pages/ToolbarWrappers.html b/packages/main/test/pages/ToolbarWrappers.html
new file mode 100644
index 000000000000..f105eaf9ef98
--- /dev/null
+++ b/packages/main/test/pages/ToolbarWrappers.html
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+ Toolbar
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file