Skip to content
Open
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
6 changes: 6 additions & 0 deletions packages/main/src/Menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import {
isDesktop,
} from "@ui5/webcomponents-base/dist/Device.js";
import i18n from "@ui5/webcomponents-base/dist/decorators/i18n.js";
import announce from "@ui5/webcomponents-base/dist/util/InvisibleMessage.js";
import InvisibleMessageMode from "@ui5/webcomponents-base/dist/types/InvisibleMessageMode.js";
import type I18nBundle from "@ui5/webcomponents-base/dist/i18nBundle.js";
import "@ui5/webcomponents-icons/dist/slim-arrow-right.js";
import jsxRenderer from "@ui5/webcomponents-base/dist/renderer/JsxRenderer.js";
Expand All @@ -40,6 +42,7 @@ import menuTemplate from "./MenuTemplate.js";
import {
MENU_CANCEL_BUTTON_TEXT,
MENU_POPOVER_ACCESSIBLE_NAME,
MENU_ITEM_LOADING,
} from "./generated/i18n/i18n-defaults.js";

// Styles
Expand Down Expand Up @@ -496,6 +499,9 @@ class Menu extends UI5Element {

_afterPopoverOpen() {
this._allMenuItems[0]?.focus();
if (this.loading) {
announce(Menu.i18nBundle.getText(MENU_ITEM_LOADING), InvisibleMessageMode.Polite);
}
this.fireDecoratorEvent("open");
}

Expand Down
15 changes: 15 additions & 0 deletions packages/main/src/MenuItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import { isDesktop, isPhone } from "@ui5/webcomponents-base/dist/Device.js";
import { renderFinished } from "@ui5/webcomponents-base/dist/Render.js";
import "@ui5/webcomponents-icons/dist/nav-back.js";
import type I18nBundle from "@ui5/webcomponents-base/dist/i18nBundle.js";
import announce from "@ui5/webcomponents-base/dist/util/InvisibleMessage.js";
import InvisibleMessageMode from "@ui5/webcomponents-base/dist/types/InvisibleMessageMode.js";
import NavigationMode from "@ui5/webcomponents-base/dist/types/NavigationMode.js";
import ItemNavigation from "@ui5/webcomponents-base/dist/delegate/ItemNavigation.js";
import ItemNavigationBehavior from "@ui5/webcomponents-base/dist/types/ItemNavigationBehavior.js";
Expand All @@ -39,6 +41,8 @@ import {
MENU_BACK_BUTTON_ARIA_LABEL,
MENU_CANCEL_BUTTON_TEXT,
MENU_POPOVER_ACCESSIBLE_NAME,
MENU_ITEM_END_CONTENT_ACCESSIBLE_NAME,
MENU_ITEM_LOADING,
} from "./generated/i18n/i18n-defaults.js";
import type { IMenuItem } from "./Menu.js";

Expand Down Expand Up @@ -399,6 +403,14 @@ class MenuItem extends ListItem implements IMenuItem {
return MenuItem.i18nBundle.getText(MENU_POPOVER_ACCESSIBLE_NAME);
}

get endContentAccessibleName() {
return MenuItem.i18nBundle.getText(MENU_ITEM_END_CONTENT_ACCESSIBLE_NAME);
}

get loadingText() {
return MenuItem.i18nBundle.getText(MENU_ITEM_LOADING);
}

onBeforeRendering() {
super.onBeforeRendering();

Expand Down Expand Up @@ -627,6 +639,9 @@ class MenuItem extends ListItem implements IMenuItem {
if (!this._openedByMouse) {
this._allMenuItems[0]?.focus();
}
if (this.loading) {
announce(MenuItem.i18nBundle.getText(MENU_ITEM_LOADING), InvisibleMessageMode.Polite);
}
this.fireDecoratorEvent("open");
}

Expand Down
20 changes: 19 additions & 1 deletion packages/main/src/MenuItemTemplate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,15 @@ function rightContent(this: MenuItem) {
</div>
);
case this.hasEndContent:
return <slot name="endContent" onKeyDown={this._endContentKeyDown}></slot>;
return (
<div
class="ui5-menu-item-end-content"
role="group"
aria-label={this.endContentAccessibleName}
>
<slot name="endContent" onKeyDown={this._endContentKeyDown}></slot>
</div>
);
case !!this.additionalText:
return (
<span
Expand Down Expand Up @@ -123,6 +131,7 @@ function listItemPostContent(this: MenuItem) {
<div
id={`${this._id}-menu-main`}
class={this.loading ? "menu-busy-indicator-main" : ""}
aria-busy={this.loading}
>
{
this.items.length ? (
Expand Down Expand Up @@ -150,6 +159,15 @@ function listItemPostContent(this: MenuItem) {
/>
}
</div >

{/* ARIA live region for loading state announcement */}
<span
class="ui5-hidden-text"
aria-live="polite"
aria-atomic="true"
>
{this.loading ? this.loadingText : ""}
</span>
{
this.isPhone && (
<div slot="footer" class="ui5-menu-dialog-footer">
Expand Down
6 changes: 6 additions & 0 deletions packages/main/src/i18n/messagebundle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,12 @@ MENU_ITEM_GROUP_SINGLE_ACCESSIBLE_NAME=Contains Selectable Items
#XACT: ARIA information for the Menu Item Group with itemSelectionMode "MultiSelect"
MENU_ITEM_GROUP_MULTI_ACCESSIBLE_NAME=Contains Multi-Selectable Items

#XACT: ARIA information for the Menu Item end content slot
MENU_ITEM_END_CONTENT_ACCESSIBLE_NAME=Additional Actions

#XACT: ARIA information for the Menu Item loading state
MENU_ITEM_LOADING=Loading

#XACT: ARIA announcement for roldesecription attribute of Dialog header
DIALOG_HEADER_ARIA_ROLE_DESCRIPTION=Interactive Header

Expand Down
5 changes: 5 additions & 0 deletions packages/main/src/themes/MenuItem.css
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@
padding-top: 0.25rem;
}

.ui5-menu-item-end-content {
display: inline-flex;
align-items: center;
}

.ui5-menu-busy-indicator {
position: absolute;
width: 100%;
Expand Down
Loading