Skip to content

feat(ui5-shellbar): replace custom badges with ButtonBadge #11284

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
May 27, 2025
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
96 changes: 95 additions & 1 deletion packages/fiori/cypress/specs/ShellBar.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -527,4 +527,98 @@ describe("Events", () => {
cy.get("@searchButtonClick")
.should("have.been.calledOnce");
});
});
});
describe("ButtonBadge in ShellBar", () => {
it("Test if ShellBarItem count appears in ButtonBadge", () => {
cy.mount(
<ShellBar id="shellbarwithitems">
<ShellBarItem id="test-item" icon="accept" text="Item" count="42" />
</ShellBar>
);

cy.get("#shellbarwithitems")
.shadow()
.find(".ui5-shellbar-custom-item ui5-button-badge[slot='badge']")
.should("exist")
.should("have.attr", "text", "42");
});

it("Test count updates propagate to ButtonBadge", () => {
cy.mount(
<ShellBar id="test-invalidation">
<ShellBarItem id="test-invalidation-item" icon="accept" text="Item" count="1" />
</ShellBar>
);

cy.get("#test-invalidation-item").invoke("attr", "count", "3");

cy.get("#test-invalidation")
.shadow()
.find(".ui5-shellbar-custom-item ui5-button-badge[slot='badge']")
.should("have.attr", "text", "3");
});

it("Test if overflow button shows appropriate badge when items are overflowed", () => {
cy.mount(
<ShellBar id="shellbar-with-overflow"
primaryTitle="Product Title"
secondaryTitle="Secondary Title"
showNotifications={true}
showProductSwitch={true}
notificationsCount="10">
<img slot="logo" src="https://upload.wikimedia.org/wikipedia/commons/5/59/SAP_2011_logo.svg" />
<Button icon="nav-back" slot="startButton"></Button>
<ShellBarItem id="item1" icon="accept" text="Item 1" count="42" />
<ShellBarItem id="item2" icon="alert" text="Item 2" count="5" />
<ShellBarItem id="item3" icon="attachment" text="Item 3" />
<ShellBarItem id="item4" icon="bell" text="Item 4" />
<Avatar slot="profile">
<img src="https://sdk.openui5.org/test-resources/sap/f/images/Woman_avatar_01.png" />
</Avatar>
<Input placeholder="Search" slot="searchField" />
</ShellBar>
);

cy.viewport(320, 800);

cy.get("#shellbar-with-overflow")
.shadow()
.find(".ui5-shellbar-overflow-button")
.should("be.visible");

cy.get("#shellbar-with-overflow")
.shadow()
.find(".ui5-shellbar-overflow-button ui5-button-badge[slot='badge']")
.should("exist")
.should("have.attr", "design", "AttentionDot");

cy.mount(
<ShellBar id="shellbar-with-single-overflow"
primaryTitle="Product Title"
secondaryTitle="Secondary Title"
showProductSwitch={true}>
<img slot="logo" src="https://upload.wikimedia.org/wikipedia/commons/5/59/SAP_2011_logo.svg" />
<Button icon="nav-back" slot="startButton"></Button>
<ShellBarItem id="single-item" icon="accept" text="Item" count="42" />
<ShellBarItem id="item3" icon="attachment" text="Item 3" />
<ShellBarItem id="item4" icon="bell" text="Item 4" />
<Avatar slot="profile">
<img src="https://sdk.openui5.org/test-resources/sap/f/images/Woman_avatar_01.png" />
</Avatar>
</ShellBar>
);

cy.viewport(320, 800);

cy.get("#shellbar-with-single-overflow")
.shadow()
.find(".ui5-shellbar-overflow-button")
.should("be.visible");

cy.get("#shellbar-with-single-overflow")
.shadow()
.find(".ui5-shellbar-overflow-button ui5-button-badge[slot='badge']")
.should("exist")
.should("have.attr", "text", "42");
});
});
5 changes: 3 additions & 2 deletions packages/fiori/src/ShellBar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import type { ListItemClickEventDetail } from "@ui5/webcomponents/dist/List.js";
import type { ResizeObserverCallback } from "@ui5/webcomponents-base/dist/delegate/ResizeHandler.js";
import Popover from "@ui5/webcomponents/dist/Popover.js";
import Button from "@ui5/webcomponents/dist/Button.js";
import ButtonBadge from "@ui5/webcomponents/dist/ButtonBadge.js";
import Menu from "@ui5/webcomponents/dist/Menu.js";
import Icon from "@ui5/webcomponents/dist/Icon.js";
import type Input from "@ui5/webcomponents/dist/Input.js";
Expand Down Expand Up @@ -198,6 +199,7 @@ const PREDEFINED_PLACE_ACTIONS = ["feedback", "sys-help"];
Popover,
ListItemStandard,
Menu,
ButtonBadge,
],
})
/**
Expand Down Expand Up @@ -1176,7 +1178,6 @@ class ShellBar extends UI5Element {
stableDomRef: item.stableDomRef,
tooltip: item.title || item.text,
accessibilityAttributes: item.accessibilityAttributes,
accessibleName: item.count ? `${item.title || item.text}, ${item.count}` : (item.title || item.text),
};
}),
{
Expand Down Expand Up @@ -1241,7 +1242,7 @@ class ShellBar extends UI5Element {
let overflowNotifications = null;

this._itemsInfo.forEach(item => {
if (item.count && this.isIconHidden(item.icon!)) {
if (item.count && item.classes.includes("ui5-shellbar-hidden-button")) {
notificationsArr.push(item.count);
}
});
Expand Down
28 changes: 21 additions & 7 deletions packages/fiori/src/ShellBarTemplate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Button from "@ui5/webcomponents/dist/Button.js";
import type ShellBar from "./ShellBar.js";
import ShellBarPopoverTemplate from "./ShellBarPopoverTemplate.js";
import slimArrowDown from "@ui5/webcomponents-icons/dist/slim-arrow-down.js";
import ButtonBadge from "@ui5/webcomponents/dist/ButtonBadge.js";

export default function ShellBarTemplate(this: ShellBar) {
return (
Expand Down Expand Up @@ -184,12 +185,15 @@ export default function ShellBarTemplate(this: ShellBar) {
}}
icon="sap-icon://bell"
data-ui5-text="Notifications"
data-ui5-notifications-count={this.notificationsCount}
onClick={this._handleNotificationsPress}
tooltip={this._notificationsText}
accessibilityAttributes={this.accInfo.notifications.accessibilityAttributes}
data-ui5-stable="notifications"
/>
>
{this.notificationsCount && (
<ButtonBadge slot="badge" design="OverlayText" text={this.notificationsCount} />
)}
</Button>
)}
{this.customItemsInfo.map(item => (
<Button
Expand All @@ -198,14 +202,16 @@ export default function ShellBarTemplate(this: ShellBar) {
class={`${item.classes} ui5-shellbar-items-for-arrow-nav`}
icon={item.icon}
tooltip={item.tooltip}
data-count={item.count}
data-ui5-notifications-count={this.notificationsCount}
data-ui5-external-action-item-id={item.refItemid}
data-ui5-stable={item.stableDomRef}
onClick={item.press}
accessibilityAttributes={item.accessibilityAttributes}
accessibleName={item.accessibleName}
/>
>
{item.count && (
<ButtonBadge slot="badge" design="OverlayText" text={item.count} />
)}
</Button>
))}
</div>
</div>
Expand All @@ -219,12 +225,20 @@ export default function ShellBarTemplate(this: ShellBar) {
...this.classes.overflow,
}}
icon="sap-icon://overflow"
data-count={this._overflowNotifications}
onClick={this._handleOverflowPress}
tooltip={this._overflowText}
accessibilityAttributes={this.accInfo.overflow.accessibilityAttributes}
data-ui5-stable="overflow"
/>
>
{this._overflowNotifications && (
<ButtonBadge
slot="badge"
design={this._overflowNotifications === " " ? "AttentionDot" : "OverlayText"}
text={this._overflowNotifications === " " ? "" : this._overflowNotifications}
/>
)}
</Button>

{this.hasProfile && profileButton.call(this)}
{this.showProductSwitch && (
<Button
Expand Down
49 changes: 6 additions & 43 deletions packages/fiori/src/themes/ShellBar.css
Original file line number Diff line number Diff line change
Expand Up @@ -386,11 +386,6 @@ slot[name="profile"] {
margin-inline-start: 0.5rem;
}

.ui5-shellbar-overflow-container-right-child .ui5-shellbar-button[data-count]:has(+ .ui5-shellbar-overflow-button)::before {
inset-inline-end: var(--_ui5-shellbar-notification-btn-count-offset);
}


:host([breakpoint-size="S"]) .ui5-shellbar-overflow-container-right {
padding-inline-start: 0;
}
Expand All @@ -408,44 +403,12 @@ slot[name="profile"] {
padding-inline-start: var(--_ui5-shellbar-content-margin-start);
}

:host(:not([notifications-count])) .ui5-shellbar-bell-button {
position: relative;
}

:host([notifications-count]:not([notifications-count=""])) .ui5-shellbar-bell-button::before,
.ui5-shellbar-button[data-count]::before {
position: absolute;
width: auto;
height: 1rem;
min-width: 1rem;
background: var(--sapContent_BadgeBackground);
border: var(--_ui5_shellbar_button_badge_border);
color: var(--sapContent_BadgeTextColor);
top: -0.25rem;
right: -0.25rem;
padding: 0 0.3125rem;
border-radius: 0.5rem;
display: flex;
justify-content: center;
align-items: center;
font-size: var(--sapFontSmallSize);
font-family: "72override", var(--sapFontFamily);
z-index: 2;
box-sizing: border-box;
}

:host([notifications-count]:not([notifications-count=""])) .ui5-shellbar-bell-button::before {
content: attr(data-ui5-notifications-count);
inset-inline-end: var(--_ui5-shellbar-notification-btn-count-offset);
}

.ui5-shellbar-button[data-count]::before {
content: attr(data-count);
.ui5-shellbar-overflow-container-right-child .ui5-shellbar-bell-button [slot="badge"] {
inset-inline-end: var(--_ui5-shellbar-notification-btn-count-offset);
}

.ui5-shellbar-button[data-count=" "]::before {
height: 0.75rem;
min-width: 0.75rem;
.ui5-shellbar-overflow-container-right-child .ui5-shellbar-custom-item [slot="badge"] {
inset-inline-end: var(--_ui5-shellbar-notification-btn-count-offset);
}

.ui5-shellbar-menu-button {
Expand All @@ -472,12 +435,12 @@ slot[name="profile"] {

.ui5-shellbar-search-full-width-wrapper {
position: absolute;
top: 0;
bottom: 0.0625rem;
left: 0;
background: var(--sapShellColor);
height: 100%;
width: 100%;
z-index: 100;
z-index: 1001;
display: flex;
align-items: center;
box-sizing: border-box;
Expand Down
17 changes: 0 additions & 17 deletions packages/fiori/test/specs/ShellBar.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,23 +89,6 @@ describe("Component Behavior", () => {
assert.ok(await innerButtonWithStableDomRef.isExisting(), "There is indeed an element in the Shellbar's shadow root with an attribute, matching the stable dom ref");
});

it("tests count property", async () => {
const shellbar = await browser.$("#shellbarwithitems");
const icon = await shellbar.shadow$("ui5-button[data-count]");

assert.strictEqual(await icon.getAttribute("data-count"), '42', "Count property propagates to ui5-button");
});

it("tests if shellbar item invalidates the shellbar", async () => {
const shellbar = await browser.$("#test-invalidation");
const item = await browser.$("#test-invalidation-item");

await item.setProperty("count", "3");

assert.strictEqual(await shellbar.shadow$(".ui5-shellbar-custom-item").getAttribute("data-count"), "3");

});

it("tests 'click' on custom action", async () => {
const shellbar = await browser.$("#shellbarwithitems");
const resultInput = await browser.$("#press-input3");
Expand Down
2 changes: 1 addition & 1 deletion packages/main/src/themes/base/rtl-parameters.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
--_ui5_menu_submenu_margin_offset: -0.25rem 0;
--_ui5_menu_submenu_placement_type_left_margin_offset: 0.25rem 0;

--_ui5-shellbar-notification-btn-count-offset: -0.125rem;
--_ui5-shellbar-notification-btn-count-offset: 0.125rem;
}

[dir="rtl"],
Expand Down
Loading