Skip to content
This repository has been archived by the owner on May 24, 2024. It is now read-only.

[terra-navigation-side-menu] A11y changes #2166

Merged
merged 13 commits into from
May 21, 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: 3 additions & 0 deletions packages/terra-framework-docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## Unreleased

* Changed
* Updated example for drill-in view under `terra-navigation-side-menu`.

## 1.89.1 - (May 20, 2024)

* Fixed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class DrillInDefault extends React.Component {
},
{ key: 'subsubmenu2', text: 'Laboratory' },
{
key: 'subsubmenu3', text: 'Rehabilitation services', childKeys: ['rehab1', 'rehab2', 'rehab3'], icon: <IconHospital />,
key: 'subsubmenu3', text: 'Rehabilitation services', childKeys: ['rehab1', 'rehab2', 'rehab3'], icon: <IconHospital a11yLabel="Location" />,
},
{ key: 'rehab1', text: 'Rehabilitation services 1' },
{ key: 'rehab2', text: 'Rehabilitation services 2' },
Expand All @@ -56,6 +56,7 @@ class DrillInDefault extends React.Component {
selectedChildKey={this.state.selectedChildKey}
ariaLabel="Sub Menu List"
variant={VARIANTS.DRILL_IN}
headerLevel={3}
/>
);

Expand Down
4 changes: 4 additions & 0 deletions packages/terra-navigation-side-menu/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

* Added
* Added headerLevel prop for the title of the menu.
* Added missing A11y attributes.

## 2.58.1 - (May 20, 2024)

* Fixed
Expand Down
27 changes: 26 additions & 1 deletion packages/terra-navigation-side-menu/src/NavigationSideMenu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ const propTypes = {
* String that labels the navigation menu for screen readers.
*/
ariaLabel: PropTypes.string,
/**
* The heading level for the title of the menu.
*/
headerLevel: PropTypes.oneOf([1, 2, 3, 4, 5, 6]),
/**
* An array of configuration for each menu item.
*/
Expand Down Expand Up @@ -96,6 +100,7 @@ const propTypes = {
const defaultProps = {
menuItems: [],
variant: VARIANTS.NAVIGATION_SIDE_MENU,
headerLevel: 3,
};

const processMenuItems = (menuItems, variant) => {
Expand Down Expand Up @@ -257,6 +262,16 @@ class NavigationSideMenu extends Component {
const listMenuItems = this.menuContainer && this.menuContainer.querySelectorAll('[data-menu-item]');
const currentIndex = Array.from(listMenuItems).indexOf(event.target);
const lastIndex = listMenuItems.length - 1;

if (event.nativeEvent.keyCode === KeyCode.KEY_ESCAPE) {
const parentKey = this.state.parents[this.props.selectedMenuKey];
if (parentKey) {
this.handleBackClick(event);
} else if (this.props.routingStackBack) {
this.props.routingStackBack();
}
}

if (event.nativeEvent.keyCode === KeyCode.KEY_SPACE || event.nativeEvent.keyCode === KeyCode.KEY_RETURN) {
event.preventDefault();
if (!item.isDisabled) {
Expand Down Expand Up @@ -379,6 +394,7 @@ class NavigationSideMenu extends Component {
selectedMenuKey,
toolbar,
variant,
headerLevel,
...customProps
} = this.props;
const currentItem = this.state.items[selectedMenuKey];
Expand All @@ -388,6 +404,8 @@ class NavigationSideMenu extends Component {
theme.className,
]);

const HeaderElement = `h${headerLevel}`;

const parentKey = this.state.parents[selectedMenuKey];
if (parentKey) {
this.onBack = this.handleBackClick;
Expand All @@ -400,6 +418,12 @@ class NavigationSideMenu extends Component {
theme.className,
]);

const titleStyles = cx([
'title',
{ 'nav-side-menu-title': (variant === VARIANTS.NAVIGATION_SIDE_MENU) },
{ 'drill-in-title': (variant === VARIANTS.DRILL_IN) },
]);

let header;
if (this.onBack || (currentItem && !currentItem.isRootMenu)) {
header = (
Expand All @@ -413,9 +437,10 @@ class NavigationSideMenu extends Component {
onKeyDown={this.handleBackKeydown}
onClick={this.onBack}
data-navigation-side-menu
aria-label={currentItem ? currentItem.text : null}
>
{(this.onBack) ? <span className={cx(['header-icon', 'back'])} /> : null}
<h1 className={cx('title')}>{currentItem ? currentItem.text : null}</h1>
<HeaderElement className={titleStyles}>{currentItem ? currentItem.text : null}</HeaderElement>
</div>
{toolbar}
</li>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,20 @@

.title {
color: var(--terra-navigation-side-menu-header-color);
font-size: var(--terra-navigation-side-menu-font-size, 1.10714rem);
font-weight: var(--terra-navigation-side-menu-font-weight, 500);
hyphens: auto;
margin: 5px;
overflow-wrap: break-word; /* Modern browsers */
padding: 0.28571rem;
width: 100%;
word-wrap: break-word; /* For IE 10 and IE 11 */
}

.nav-side-menu-title {
font-size: var(--terra-navigation-side-menu-font-size, 1.10714rem);
font-weight: var(--terra-navigation-side-menu-font-weight, 500);
}

.drill-in-title {
MadanKumarGovindaswamy marked this conversation as resolved.
Show resolved Hide resolved
font-weight: 700;
}
}
12 changes: 10 additions & 2 deletions packages/terra-navigation-side-menu/src/_MenuItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ class MenuItem extends React.Component {
} = this.props;
const theme = this.context;

const itemIcon = hasChevron && !icon ? <IconFolder /> : (icon || <IconDocuments />);
const itemIcon = hasChevron && !icon ? <IconFolder a11yLabel={intl.formatMessage({ id: 'Terra.navigation.side.menu.folder' })} /> : (icon || <IconDocuments a11yLabel={intl.formatMessage({ id: 'Terra.navigation.side.menu.document' })} />);

const itemClassNames = classNames(cx(
'menu-item',
Expand All @@ -137,6 +137,14 @@ class MenuItem extends React.Component {
{ 'is-disabled': isDisabled },
);

const ariaAttributes = {};
ariaAttributes['aria-haspopup'] = hasChevron;
ariaAttributes['aria-disabled'] = isDisabled;

if (hasChevron) {
ariaAttributes['aria-expanded'] = !hasChevron;
}

MadanKumarGovindaswamy marked this conversation as resolved.
Show resolved Hide resolved
return (
<li
className={listItemClassNames}
Expand All @@ -149,7 +157,7 @@ class MenuItem extends React.Component {
tabIndex={this.props.tabIndex}
className={itemClassNames}
onKeyDown={this.handleKeyDown}
aria-haspopup={hasChevron}
{...ariaAttributes}
>
{variant === VARIANTS.DRILL_IN && itemIcon && <span className={cx('icon')}>{itemIcon}</span>}
<div className={cx('title')}>
Expand Down
Loading
Loading