From 842bdc2e425df72a95c5d65cf30fefc721707017 Mon Sep 17 00:00:00 2001 From: Dobromira Boycheva Date: Wed, 12 Aug 2026 10:23:13 +0300 Subject: [PATCH 1/9] chore(ui5-user-menu): spec updates and UX fixes --- packages/fiori/cypress/specs/UserMenu.cy.tsx | 49 +++++++++++++++++-- packages/fiori/src/UserMenuTemplate.tsx | 7 +++ packages/fiori/src/themes/UserMenu.css | 15 +++++- packages/fiori/src/themes/UserMenuItem.css | 3 -- packages/fiori/test/pages/UXCIntegration.html | 15 +++--- packages/fiori/test/pages/UserMenu.html | 15 ++++-- .../fiori/test/pages/UserSettingsDialog.html | 9 +++- packages/main/cypress/specs/Menu.cy.tsx | 42 ++++++++++++++++ packages/main/src/MenuItemTemplate.tsx | 8 +++ packages/main/src/themes/Menu.css | 5 +- .../_samples/fiori/UserMenu/Advanced/main.js | 1 + .../fiori/UserMenu/Advanced/sample.html | 13 ++--- .../fiori/UserMenu/Advanced/sample.tsx | 14 +++--- .../_samples/fiori/UserMenu/Basic/sample.html | 2 +- .../_samples/fiori/UserMenu/Basic/sample.tsx | 2 +- .../UserSettingsDialog/Basic/sample.html | 9 +++- .../fiori/UserSettingsDialog/Basic/sample.tsx | 12 ++++- .../UserSettingsDialog/SaveMode/sample.html | 9 +++- .../UserSettingsDialog/SaveMode/sample.tsx | 12 ++++- 19 files changed, 202 insertions(+), 40 deletions(-) diff --git a/packages/fiori/cypress/specs/UserMenu.cy.tsx b/packages/fiori/cypress/specs/UserMenu.cy.tsx index 669b45488df0b..056d2708605e7 100644 --- a/packages/fiori/cypress/specs/UserMenu.cy.tsx +++ b/packages/fiori/cypress/specs/UserMenu.cy.tsx @@ -971,6 +971,28 @@ describe("Responsiveness", () => { cy.get("@headerBar").find("[ui5-button]").should("have.length", 1); }); + it("popover header has no divider line (::before pseudo-element hidden)", () => { + cy.mount( + <> + + + + + + ); + + cy.get("[ui5-user-menu]").shadow() + .find("[ui5-responsive-popover]") + .shadow() + .find("[ui5-dialog]") + .shadow() + .find(".ui5-popup-header-root") + .then($el => { + const before = window.getComputedStyle($el[0], "::before"); + expect(before.height).to.equal("0px"); + }); + }); + it("Event firing - 'ui5-check' after 'click' on user menu item", () => { cy.mount( <> @@ -1313,6 +1335,26 @@ describe("InfoArea slot", () => { }); }); }); + + it("info-area has 8px padding on all sides", () => { + cy.mount( + <> + + + + + All actions are recorded under the proxy audit log. + + + + ); + + cy.get("[ui5-user-menu]").shadow().find(".ui5-user-menu-info-area") + .should("have.css", "padding-top", "8px") + .and("have.css", "padding-bottom", "8px") + .and("have.css", "padding-left", "8px") + .and("have.css", "padding-right", "8px"); + }); }); describe("UserMenuItem", () => { @@ -1578,7 +1620,7 @@ describe("UserMenuItem", () => { .should("not.have.attr", "show-selection"); }); - it("selection text has correct styling", () => { + it("selection text wraps instead of truncating", () => { cy.mount( <> @@ -1596,9 +1638,8 @@ describe("UserMenuItem", () => { .shadow() .find(".ui5-user-menu-item-selection-text") .should("have.css", "font-weight", "400") - .and("have.css", "white-space", "nowrap") - .and("have.css", "overflow", "hidden") - .and("have.css", "text-overflow", "ellipsis"); + .and("not.have.css", "white-space", "nowrap") + .and("not.have.css", "text-overflow", "ellipsis"); }); it("text wrapper has column layout with gap", () => { diff --git a/packages/fiori/src/UserMenuTemplate.tsx b/packages/fiori/src/UserMenuTemplate.tsx index 999b871b3357c..3c0f2bbac86ba 100644 --- a/packages/fiori/src/UserMenuTemplate.tsx +++ b/packages/fiori/src/UserMenuTemplate.tsx @@ -57,6 +57,13 @@ export default function UserMenuTemplate(this: UserMenu) { onClick={this._closeUserMenu} slot="endContent" />} + + {this._isPhone && this._titleMovedToHeader && + + + + + + + ); + + cy.get("[ui5-menu-item][text='Parent Item']") + .shadow() + .find(".ui5-menu-back-button") + .should("have.css", "margin-right", "0px"); + }); + + it("submenu header has a close button", () => { + cy.mount( + <> + + + + + + + + ); + + cy.get("[ui5-menu-item][text='Parent Item']") + .shadow() + .find(".ui5-menu-close-button") + .should("exist"); + }); }); \ No newline at end of file diff --git a/packages/main/src/MenuItemTemplate.tsx b/packages/main/src/MenuItemTemplate.tsx index f9b75d0b0cd46..df482bda91a4a 100644 --- a/packages/main/src/MenuItemTemplate.tsx +++ b/packages/main/src/MenuItemTemplate.tsx @@ -6,6 +6,7 @@ import Button from "./Button.js"; import List from "./List.js"; import BusyIndicator from "./BusyIndicator.js"; import navBackIcon from "@ui5/webcomponents-icons/dist/nav-back.js"; +import declineIcon from "@ui5/webcomponents-icons/dist/decline.js"; import checkIcon from "@ui5/webcomponents-icons/dist/accept.js"; import slimArrowRight from "@ui5/webcomponents-icons/dist/slim-arrow-right.js"; import Icon from "./Icon.js"; @@ -134,6 +135,13 @@ function listItemPostContent(this: MenuItem) { {this.text} + + + + + + + + ); + + cy.get("[ui5-user-menu-item][text='Setting']") + .should("be.focused"); + }); + it("tests close event", () => { cy.mount( <> diff --git a/packages/fiori/src/UserMenu.ts b/packages/fiori/src/UserMenu.ts index e8b26d0be842a..ef89551a20364 100644 --- a/packages/fiori/src/UserMenu.ts +++ b/packages/fiori/src/UserMenu.ts @@ -433,6 +433,7 @@ class UserMenu extends UI5Element { this._titleMovedToHeader = false; this._isScrolled = false; this._setupObserver(); + this._menuItems[0]?.getFocusDomRef()?.focus(); this.fireDecoratorEvent("open"); } From 1ca9e5103fad52c5e7197db3379aeb765f36a5ba Mon Sep 17 00:00:00 2001 From: Dobromira Boycheva Date: Tue, 18 Aug 2026 13:59:14 +0300 Subject: [PATCH 4/9] fix(ui5-user-menu): move close button to UserMenu level and fix title centering --- packages/fiori/cypress/specs/UserMenu.cy.tsx | 28 +++++++++++++ packages/fiori/src/UserMenuItemTemplate.tsx | 16 +++++++- packages/fiori/src/UserMenuTemplate.tsx | 7 ---- packages/fiori/src/themes/UserMenu.css | 8 ++++ packages/fiori/src/themes/UserMenuItem.css | 4 ++ packages/main/cypress/specs/Menu.cy.tsx | 42 -------------------- packages/main/src/MenuItemTemplate.tsx | 15 +++---- packages/main/src/themes/Menu.css | 4 -- 8 files changed, 60 insertions(+), 64 deletions(-) diff --git a/packages/fiori/cypress/specs/UserMenu.cy.tsx b/packages/fiori/cypress/specs/UserMenu.cy.tsx index b686142bb85b3..f66de2dbb7932 100644 --- a/packages/fiori/cypress/specs/UserMenu.cy.tsx +++ b/packages/fiori/cypress/specs/UserMenu.cy.tsx @@ -989,6 +989,34 @@ describe("Responsiveness", () => { cy.get("@headerBar").find("[ui5-button][slot='endContent']").should("have.length", 1); }); + it("submenu header on phone has close button in UserMenuItem", () => { + cy.ui5SimulateDevice("phone"); + cy.mount( + <> + + + + + + + + + ); + + cy.get("[ui5-user-menu-item][text='Settings']") + .ui5MenuItemClick(); + + cy.get("[ui5-user-menu-item][text='Settings']") + .shadow() + .find("[ui5-responsive-popover]") + .should("have.attr", "open"); + + cy.get("[ui5-user-menu-item][text='Settings']") + .shadow() + .find(".ui5-menu-close-button") + .should("exist"); + }); + it("popover header has no divider line (::before pseudo-element hidden)", () => { cy.mount( <> diff --git a/packages/fiori/src/UserMenuItemTemplate.tsx b/packages/fiori/src/UserMenuItemTemplate.tsx index ff561b1bb1627..78df1a5c3969e 100644 --- a/packages/fiori/src/UserMenuItemTemplate.tsx +++ b/packages/fiori/src/UserMenuItemTemplate.tsx @@ -1,9 +1,23 @@ import type UserMenuItem from "./UserMenuItem.js"; import MenuItemTemplate from "@ui5/webcomponents/dist/MenuItemTemplate.js"; import type { MenuItemHooks } from "@ui5/webcomponents/dist/MenuItemTemplate.js"; +import Button from "@ui5/webcomponents/dist/Button.js"; +import declineIcon from "@ui5/webcomponents-icons/dist/decline.js"; export default function UserMenuItemTemplate(this: UserMenuItem) { - const hooks: Partial = {}; + const hooks: Partial = { + menuItemDialogHeaderEnd: function menuItemDialogHeaderEnd(this: UserMenuItem) { + return ( + - - - - - - - ); - - cy.get("[ui5-menu-item][text='Parent Item']") - .shadow() - .find(".ui5-menu-back-button") - .should("have.css", "margin-right", "0px"); - }); - - it("submenu header has a close button", () => { - cy.mount( - <> - - - - - - - - ); - - cy.get("[ui5-menu-item][text='Parent Item']") - .shadow() - .find(".ui5-menu-close-button") - .should("exist"); - }); }); \ No newline at end of file diff --git a/packages/main/src/MenuItemTemplate.tsx b/packages/main/src/MenuItemTemplate.tsx index df482bda91a4a..3fc91c17419be 100644 --- a/packages/main/src/MenuItemTemplate.tsx +++ b/packages/main/src/MenuItemTemplate.tsx @@ -6,7 +6,6 @@ import Button from "./Button.js"; import List from "./List.js"; import BusyIndicator from "./BusyIndicator.js"; import navBackIcon from "@ui5/webcomponents-icons/dist/nav-back.js"; -import declineIcon from "@ui5/webcomponents-icons/dist/decline.js"; import checkIcon from "@ui5/webcomponents-icons/dist/accept.js"; import slimArrowRight from "@ui5/webcomponents-icons/dist/slim-arrow-right.js"; import Icon from "./Icon.js"; @@ -15,11 +14,13 @@ import type { ListItemHooks } from "./ListItemTemplate.js"; export type MenuItemHooks = ListItemHooks & { menuItemTextContent: JsxTemplate; + menuItemDialogHeaderEnd: JsxTemplate; } const predefinedHooks: Partial = { iconBegin, menuItemTextContent, + menuItemDialogHeaderEnd: () => {}, }; export default function MenuItemTemplate(this: MenuItem, hooks?: Partial) { @@ -39,7 +40,7 @@ export default function MenuItemTemplate(this: MenuItem, hooks?: Partial {ListItemTemplate.call(this, currentHooks)} - {listItemPostContent.call(this)} + {listItemPostContent.call(this, currentHooks)} ; } @@ -103,7 +104,7 @@ function iconBegin(this: MenuItem) { } } -function listItemPostContent(this: MenuItem) { +function listItemPostContent(this: MenuItem, hooks?: Partial) { return this.hasSubmenu && - + + + + + + + + ); + + cy.get("[ui5-user-menu-item][text='Settings']") + .shadow() + .find(".ui5-menu-close-button") + .should("not.exist"); + }); + it("popover header has no divider line (::before pseudo-element hidden)", () => { cy.mount( <> From ea76f48c0e28f61c83e0a5eda526629263c1b0d8 Mon Sep 17 00:00:00 2001 From: Dobromira Boycheva Date: Tue, 18 Aug 2026 14:23:14 +0300 Subject: [PATCH 9/9] chore(ui5-user-menu): fix linting errors in UserMenuItemTemplate --- packages/fiori/src/UserMenuItemTemplate.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/fiori/src/UserMenuItemTemplate.tsx b/packages/fiori/src/UserMenuItemTemplate.tsx index 63442812e5844..bb4813c5e53da 100644 --- a/packages/fiori/src/UserMenuItemTemplate.tsx +++ b/packages/fiori/src/UserMenuItemTemplate.tsx @@ -28,7 +28,7 @@ export default function UserMenuItemTemplate(this: UserMenuItem) { function phoneTemplate(this: UserMenuItem) { const hooks: Partial = { - iconBegin: function (this: UserMenuItem) { + iconBegin(this: UserMenuItem) { if (this.hasIcon) { return ; } @@ -36,7 +36,7 @@ function phoneTemplate(this: UserMenuItem) { return
; } }, - listItemContent: function (this: UserMenuItem) { + listItemContent(this: UserMenuItem) { return (<> {this.showSelection ? (