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

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
96 changes: 95 additions & 1 deletion packages/fiori/cypress/specs/ShellBar.cy.tsx
Original file line number Diff line number Diff line change
@@ -523,4 +523,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
@@ -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";
@@ -195,6 +196,7 @@ const PREDEFINED_PLACE_ACTIONS = ["feedback", "sys-help"];
Popover,
ListItemStandard,
Menu,
ButtonBadge,
],
})
/**
@@ -1132,7 +1134,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),
};
}),
{
@@ -1197,7 +1198,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);
}
});
28 changes: 21 additions & 7 deletions packages/fiori/src/ShellBarTemplate.tsx
Original file line number Diff line number Diff line change
@@ -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 (
@@ -183,12 +184,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
@@ -197,14 +201,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>
@@ -218,12 +224,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
49 changes: 6 additions & 43 deletions packages/fiori/src/themes/ShellBar.css
Original file line number Diff line number Diff line change
@@ -384,11 +384,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;
}
@@ -406,44 +401,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 {
@@ -470,12 +433,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;
17 changes: 0 additions & 17 deletions packages/fiori/test/specs/ShellBar.spec.js
Original file line number Diff line number Diff line change
@@ -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");
2 changes: 1 addition & 1 deletion packages/main/src/themes/base/rtl-parameters.css
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@
--_ui5_menu_submenu_placement_type_left_margin_offset: 0.25rem 0;
--_ui5-menu_item_icon_float: right;

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

[dir="rtl"],