Skip to content
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

feat(ui5-menu-item): add accessibility attributes #9333

Merged
merged 6 commits into from
Jul 8, 2024
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
3 changes: 2 additions & 1 deletion packages/base/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@ type AccessibilityAttributes = {
controls?: LowercaseString<string>
expanded?: "true" | "false" | boolean,
hasPopup?: ARIAHasPopup,
name?: string
name?: string,
role?: ARIARoles,
ariaKeyShortcuts?: string,
}

export type {
Expand Down
1 change: 1 addition & 0 deletions packages/main/src/ListItem.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
aria-selected="{{_accInfo.ariaSelected}}"
aria-checked="{{_accInfo.ariaChecked}}"
aria-owns="{{_accInfo.ariaOwns}}"
aria-keyshortcuts="{{_accInfo.ariaKeyShortcuts}}"
>
{{> listItemPreContent}}

Expand Down
1 change: 1 addition & 0 deletions packages/main/src/ListItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ type AccInfo = {
listItemAriaLabel?: string;
ariaOwns?: string;
tooltip?: string;
ariaKeyShortcuts?: string;
}

type ListItemAccessibilityAttributes = Pick<AccessibilityAttributes, "hasPopup" | "ariaSetsize" | "ariaPosinset">;
Expand Down
6 changes: 5 additions & 1 deletion packages/main/src/MenuItem.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@
{{else if hasEndContent}}
<slot name="endContent"></slot>
{{else if additionalText}}
<span part="additional-text" class="ui5-li-additional-text">{{additionalText}}</span>
<span
part="additional-text"
class="ui5-li-additional-text"
aria-hidden="{{_accInfo.ariaHidden}}"
>{{additionalText}}</span>
{{/if}}

{{/inline}}
Expand Down
24 changes: 23 additions & 1 deletion packages/main/src/MenuItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import slot from "@ui5/webcomponents-base/dist/decorators/slot.js";
import { getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js";
import { isPhone } from "@ui5/webcomponents-base/dist/Device.js";
import AriaHasPopup from "@ui5/webcomponents-base/dist/types/AriaHasPopup.js";
import type { AccessibilityAttributes } from "@ui5/webcomponents-base/dist/types.js";
import type { ListItemAccessibilityAttributes } from "./ListItem.js";
import ListItem from "./ListItem.js";
import ResponsivePopover from "./ResponsivePopover.js";
import type PopoverPlacement from "./types/PopoverPlacement.js";
Expand All @@ -24,6 +26,8 @@ import menuItemCss from "./generated/themes/MenuItem.css.js";
type MenuBeforeOpenEventDetail = { item?: MenuItem };
type MenuBeforeCloseEventDetail = { escPressed: boolean };

type MenuItemAccessibilityAttributes = Pick<AccessibilityAttributes, "ariaKeyShortcuts" | "role"> & ListItemAccessibilityAttributes;

/**
* @class
*
Expand Down Expand Up @@ -142,6 +146,21 @@ class MenuItem extends ListItem implements IMenuItem {
@property()
tooltip?: string;

/**
* Defines the additional accessibility attributes that will be applied to the component.
* The following fields are supported:
*
* - **ariaKeyShortcuts**: Indicated the availability of a keyboard shortcuts defined for the menu item.
*
* - **role**: Defines the role of the menu item. If not set, menu item will have default role="menuitem".
*
* @public
* @since 2.1.0
* @default {}
*/
@property({ type: Object })
accessibilityAttributes: MenuItemAccessibilityAttributes = {};

/**
* Indicates whether any of the element siblings have icon.
*/
Expand Down Expand Up @@ -242,8 +261,10 @@ class MenuItem extends ListItem implements IMenuItem {

get _accInfo() {
const accInfoSettings = {
role: "menuitem",
role: this.accessibilityAttributes.role || "menuitem",
ariaHaspopup: this.hasSubmenu ? AriaHasPopup.Menu.toLowerCase() as Lowercase<AriaHasPopup> : undefined,
ariaKeyShortcuts: this.accessibilityAttributes.ariaKeyShortcuts,
ariaHidden: !!this.additionalText && !!this.accessibilityAttributes.ariaKeyShortcuts ? true : undefined,
};

return { ...super._accInfo, ...accInfoSettings };
Expand Down Expand Up @@ -314,4 +335,5 @@ export default MenuItem;
export type {
MenuBeforeCloseEventDetail,
MenuBeforeOpenEventDetail,
MenuItemAccessibilityAttributes,
};
24 changes: 20 additions & 4 deletions packages/main/test/pages/Menu.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@
<body class="bg">
<ui5-button id="btnOpen">Open Menu</ui5-button> <br/>
<ui5-menu id="menu" header-text="My ui5-menu">
<ui5-menu-item text="New File(selection prevented)" accessible-name="Opens a file explorer" additional-text="Ctrl+Alt+Shift+N" tooltip="Select a file - prevent default" icon="add-document"></ui5-menu-item>
<ui5-menu-item id="menuItemNewFile" text="New File (selection prevented)" accessible-name="Opens a file explorer" additional-text="Ctrl+Alt+Shift+N" tooltip="Select a file - prevent default" icon="add-document"></ui5-menu-item>
<ui5-menu-item text="New Folder with very long title for a menu item" additional-text="Ctrl+F" icon="add-folder" disabled>
<ui5-menu-item text="test.txt"></ui5-menu-item>
</ui5-menu-item>
<ui5-menu-separator></ui5-menu-separator>
<ui5-menu-item text="Open" icon="open-folder" accessible-name="Choose platform" loading-delay="100" loading>
<ui5-menu-item text="Open Locally" icon="open-folder" additional-text="Ctrl+K">
<ui5-menu-item text="Open from C"></ui5-menu-item>
<ui5-menu-item text="Open from D"></ui5-menu-item>
<ui5-menu-item id="menuItemFromC" text="Open from C"></ui5-menu-item>
<ui5-menu-item id="menuItemFromD" text="Open from D"></ui5-menu-item>
<ui5-menu-separator></ui5-menu-separator>
<ui5-menu-item text="Open from E" disabled></ui5-menu-item>
</ui5-menu-item>
Expand All @@ -40,7 +40,7 @@
<ui5-menu-item text="Close" additional-text="Ctrl+W" loading-delay="100" loading></ui5-menu-item>
<ui5-menu-separator></ui5-menu-separator>
<ui5-menu-item text="Preferences" icon="action-settings" disabled></ui5-menu-item>
<ui5-menu-item text="Exit" icon="journey-arrive"></ui5-menu-item>
<ui5-menu-item id="menuItemExit" text="Exit" icon="journey-arrive"></ui5-menu-item>
</ui5-menu>

<ui5-title level="H5" class="header-title">Clicked menu item text</ui5-title>
Expand Down Expand Up @@ -243,6 +243,22 @@
console.warn("Item clicked: " + event.detail.item.text);
});

menuItemNewFile.accessibilityAttributes = {
ariaKeyShortcuts: "Ctrl+Alt+Shift+N",
}

menuItemExit.accessibilityAttributes = {
ariaKeyShortcuts: "Ctrl+X",
}

menuItemFromC.accessibilityAttributes = {
role: "menuitemcheckbox",
};

menuItemFromD.accessibilityAttributes = {
role: "menuitemcheckbox",
};

</script>
</body>
</html>
25 changes: 24 additions & 1 deletion packages/main/test/specs/Menu.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ describe("Menu interaction", () => {
cy.get("[ui5-menu]")
.ui5MenuOpened();


cy.get("[ui5-menu-item][text='Item 1.0']")
.as("item")
.ui5MenuItemClick();
Expand Down Expand Up @@ -309,6 +309,7 @@ describe("Menu interaction", () => {
<ui5-menu-item text="Item 1.1"></ui5-menu-item>
</ui5-menu-item>
<ui5-menu-item text="Item 2.0" accessible-name="test accessible name"></ui5-menu-item>
<ui5-menu-item text="Item 3.0" additional-text="Ctrl+A"></ui5-menu-item>
</ui5-menu>`)

cy.get("[ui5-menu]")
Expand All @@ -334,6 +335,28 @@ describe("Menu interaction", () => {
cy.get("@items")
.eq(1)
.should("have.attr", "accessible-name", "test accessible name")

cy.get("@items")
.eq(2)
.then($el => {
$el.get(0).accessibilityAttributes = {
ariaKeyShortcuts: "Ctrl+A",
role: "menuitemcheckbox",
}
})

cy.get("@items")
.eq(2)
.shadow()
.find("li")
.should("have.attr", "aria-keyshortcuts", "Ctrl+A", "aria-keyshortcuts attribute is reflected")
.and("have.attr", "role", "menuitemcheckbox", "role attribute is reflected")

cy.get("@items")
.eq(2)
.shadow()
.find("li .ui5-li-additional-text")
.should("have.attr", "aria-hidden", "true", "aria-hidden attribute is set to true")
});
})
})