Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
4b9e525
chore(ui5-toolbar): toolbar item wrapper introduced
PetyaMarkovaBogdanova Aug 12, 2025
eb44c13
Merge branch 'main' into poc-toolbar-item
PetyaMarkovaBogdanova Sep 2, 2025
0439ce7
Merge branch 'main' into poc-toolbar-item
PetyaMarkovaBogdanova Sep 2, 2025
7c49aa4
chore(ui5-toolbar-item): wrappers introduced
PetyaMarkovaBogdanova Sep 9, 2025
682adfa
Merge branch 'poc-toolbar-item' of github.com:SAP/ui5-webcomponents i…
PetyaMarkovaBogdanova Sep 9, 2025
a177545
Merge branch 'main' into poc-toolbar-item
PetyaMarkovaBogdanova Sep 9, 2025
6169477
chore(ui5-toolbar-item): toolbar wrappers
PetyaMarkovaBogdanova Sep 10, 2025
6d61c76
chore(ui5-toolbar): toolbar item wrapper introduced
PetyaMarkovaBogdanova Sep 10, 2025
84607fb
chore(ui5-toolbar): toolbar item wrapper introduced
PetyaMarkovaBogdanova Sep 10, 2025
8b60ec7
chore(ui5-toolbar): toolbar item wrapper introduced
PetyaMarkovaBogdanova Sep 10, 2025
433a23b
Merge branch 'main' into poc-toolbar-item
PetyaMarkovaBogdanova Sep 11, 2025
72da995
Merge branch 'main' into poc-toolbar-item
PetyaMarkovaBogdanova Sep 11, 2025
a82c920
Merge branch 'main' into poc-toolbar-item
PetyaMarkovaBogdanova Sep 12, 2025
fed79a5
chore(ui5-toolbar-item): item wrapers introduced
PetyaMarkovaBogdanova Sep 16, 2025
2324db6
Merge branch 'poc-toolbar-item' of github.com:SAP/ui5-webcomponents i…
PetyaMarkovaBogdanova Sep 16, 2025
22648ff
Merge branch 'main' into poc-toolbar-item
PetyaMarkovaBogdanova Sep 16, 2025
669a44a
chore(ui5-toolbar-item): items wrappers introduced
PetyaMarkovaBogdanova Sep 16, 2025
9a12522
chore(ui5-toolbar): toolbar item wrapper introduced
PetyaMarkovaBogdanova Sep 16, 2025
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
125 changes: 124 additions & 1 deletion packages/main/cypress/specs/Toolbar.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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(
<Toolbar>
<ToolbarItem prevent-overflow-closing overflow-priority="AlwaysOverflow">
<Button id="innerButton" icon="employee">User Menu</Button>
</ToolbarItem>
</Toolbar>
);

// 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(
<div style={{ width: "200px" }}>
<Toolbar>
<ToolbarItem overflow-priority="AlwaysOverflow" prevent-overflow-closing>
<Button id="preventCloseButton" icon="employee">Prevent Close</Button>
</ToolbarItem>
<ToolbarItem overflow-priority="AlwaysOverflow">
<Button id="normalButton" icon="add">Normal Button</Button>
</ToolbarItem>
</Toolbar>
</div>
);

// 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(
<Toolbar>
<ToolbarItem overflow-priority="AlwaysOverflow">
<Button id="highPriorityButton" icon="employee">High Priority</Button>
</ToolbarItem>
<ToolbarItem overflow-priority="NeverOverflow">
<Button id="lowPriorityButton" icon="employee">Low Priority</Button>
</ToolbarItem>
</Toolbar>
);

// 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");
});
})
39 changes: 38 additions & 1 deletion packages/main/src/ToolbarItem.ts
Original file line number Diff line number Diff line change
@@ -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";

Expand All @@ -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
*/
Expand Down Expand Up @@ -65,6 +75,17 @@ class ToolbarItem extends UI5Element {
onAfterRendering(): void {
this._isRendering = false;
}
/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

duplicated comment

* 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
Expand Down Expand Up @@ -112,10 +133,26 @@ class ToolbarItem extends UI5Element {
},
};
}

constructor() {
super();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since the constructor doesn't handle any arguments, this override can be omitted

}

/**
* 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;
9 changes: 9 additions & 0 deletions packages/main/src/ToolbarItemTemplate.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type ToolbarItem from "./ToolbarItem.js";

export default function ToolbarItemTemplate(this: ToolbarItem) {
return (
<div onClick={this.onClick}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once we have a sample with different types of components we should test if this click only event handling is enough to manage the closing of the popover. If not we should extend it or think of another mehanism.

<slot></slot>
</div>
);
}
4 changes: 3 additions & 1 deletion packages/main/test/pages/Toolbar.html
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@
</ui5-toolbar-select>
<ui5-toolbar-separator></ui5-toolbar-separator>
<ui5-toolbar-separator></ui5-toolbar-separator>
<ui5-toolbar-button icon="employee" text="Call me later"></ui5-toolbar-button>
<ui5-toolbar-item overflow-priority="AlwaysOverflow">
<ui5-button icon="employee">Call me later</ui5-button>
</ui5-toolbar-item>
</ui5-toolbar>
</section>
<br /><br />
Expand Down
105 changes: 105 additions & 0 deletions packages/main/test/pages/ToolbarWrappers.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<!DOCTYPE html>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add other components : Title, Text, Input, CheckBox, ToggleButton, DIV

<html>

<head>
<meta charset="utf-8">

<title>Toolbar</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta charset="utf-8">

<script src="%VITE_BUNDLE_PATH%" type="module"></script>
<link rel="stylesheet" type="text/css" href="./styles/Toolbar.css">
</head>

<body>
<div id="toolbars-container">
<ui5-title level="H3">Standard Toolbar with ToolbarSelect and ToolbarButton</ui5-title>
<br />
<section>
<ui5-toolbar id="otb_standard">
<ui5-toolbar-button icon="add" stable-dom-ref="otb_button_1" text="Left 1 (long)"></ui5-toolbar-button>
<ui5-toolbar-button icon="decline" text="Left 2"></ui5-toolbar-button>
<ui5-toolbar-button icon="employee" text="Left 3"></ui5-toolbar-button>
<ui5-toolbar-button icon="decline" text="Left 4"></ui5-toolbar-button>
<ui5-toolbar-button icon="add" text="Mid 1"></ui5-toolbar-button>
<ui5-toolbar-button icon="decline" text="Mid 2"></ui5-toolbar-button>
<ui5-toolbar-button icon="add" text="Right 1"></ui5-toolbar-button>
<ui5-toolbar-button overflow-priority="NeverOverflow" icon="employee" text="Right 4"></ui5-toolbar-button>
<ui5-toolbar-select id="toolbar-select">
<ui5-toolbar-select-option>1</ui5-toolbar-select-option>
<ui5-toolbar-select-option selected>2</ui5-toolbar-select-option>
<ui5-toolbar-select-option>3</ui5-toolbar-select-option>
</ui5-toolbar-select>
<ui5-toolbar-separator></ui5-toolbar-separator>
<ui5-toolbar-separator></ui5-toolbar-separator>
<ui5-toolbar-button overflow-priority="AlwaysOverflow" icon="employee" prevent-overflow-closing text="Call me later" ></ui5-toolbar-button>
</ui5-toolbar>
</section>
<ui5-title level="H3">Toolbar with ui5-select and ui5-button wrapped in ui5-toolbar-item</ui5-title>
<br />
<section>
<ui5-toolbar id="otb_standard">
<ui5-toolbar-item><ui5-button icon="add" stable-dom-ref="otb_button_1">Left 1 (long)</ui5-button></ui5-toolbar-item>
<ui5-toolbar-item><ui5-button icon="decline">Left 2</ui5-button></ui5-toolbar-item>
<ui5-toolbar-item><ui5-button icon="employee">Left 3</ui5-button></ui5-toolbar-item>
<ui5-toolbar-item><ui5-button icon="decline">Left 4</ui5-button></ui5-toolbar-item>
<ui5-toolbar-item><ui5-button icon="add">Mid 1</ui5-button></ui5-toolbar-item>
<ui5-toolbar-item><ui5-button icon="decline">Mid 2</ui5-button></ui5-toolbar-item>
<ui5-toolbar-item><ui5-button icon="add">Right 1</ui5-button></ui5-toolbar-item>
<ui5-toolbar-item overflow-priority="NeverOverflow"><ui5-button icon="employee">Right 4</ui5-button></ui5-toolbar-item>
<ui5-toolbar-item>
<ui5-select id="toolbar-select">
<ui5-option>1</ui5-option>
<ui5-option selected>2</ui5-option>
<ui5-option>3</ui5-option>
</ui5-select>
</ui5-toolbar-item>
<ui5-toolbar-separator></ui5-toolbar-separator>
<ui5-toolbar-separator></ui5-toolbar-separator>
<ui5-toolbar-item overflow-priority="AlwaysOverflow" prevent-overflow-closing >
<ui5-button icon="employee">Call me later</ui5-button>
</ui5-toolbar-item>
</ui5-toolbar>
</section>
<ui5-title level="H3">Toolbar with various components</ui5-title>
<br />
<section>
<ui5-toolbar id="otb_standard">
<ui5-toolbar-item>
<ui5-input id="myInput" class="input2auto" show-suggestions placeholder="Search for a country ...">
</ui5-toolbar-item>
<ui5-toolbar-item>
<ui5-text style="max-width:50px; text-overflow: ellipsis;white-space: nowrap;display: inline-block;">Simple text</ui5-text>
</ui5-toolbar-item>
<ui5-toolbar-item>
<ui5-combobox id="combo" class="combobox2auto" value="ComboBox" accessible-name-ref="countryLabel">
<ui5-cb-item text="Algeria"></ui5-cb-item>
<ui5-cb-item text="Argentina"></ui5-cb-item>
<ui5-cb-item text="Australia"></ui5-cb-item>
<ui5-cb-item text="Austria"></ui5-cb-item>
<ui5-cb-item text="Bahrain"></ui5-cb-item>
<ui5-cb-item text="Belgium"></ui5-cb-item>
<ui5-cb-item text="Very long text that makes popover wider than the ComboBox"></ui5-cb-item>
<ui5-cb-item text="Brazil"></ui5-cb-item>
<ui5-cb-item text="Bulgaria"></ui5-cb-item>
<ui5-cb-item text="Canada"></ui5-cb-item>
<ui5-cb-item text="Chile"></ui5-cb-item>
</ui5-combobox>
</ui5-toolbar-item>
<ui5-toolbar-item prevent-overflow-closing>
<ui5-title>Simple title</ui5-title>
</ui5-toolbar-item>
<ui5-toolbar-item>
<ui5-toggle-button icon="sap-icon://employee"></ui5-toggle-button>
</ui5-toolbar-item>
<ui5-toolbar-item prevent-overflow-closing>
<div>div with <a onclick="alert(100)" href="#">Link</a> and text</div>
</ui5-toolbar-item>

</ui5-toolbar>
</section>
</div>
</body>

</html>
Loading