Chore: Allow MenuItems to have role=menuitem when URL is set (#86886)

Allow passing a role into a MenuItem component, and fallback to default behaviour if not passed
This commit is contained in:
Tom Ratcliffe 2024-05-07 13:12:02 +01:00 committed by GitHub
parent c6975e06d2
commit a597300027
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 25 additions and 4 deletions

View File

@ -78,4 +78,14 @@ describe('MenuItem', () => {
expect(await screen.findByTestId(selectors.components.Menu.SubMenu.container)).toBeInTheDocument();
});
it('renders with role="link" when URL is passed', async () => {
render(<MenuItem label="URL Item" url="/some-url" />);
expect(screen.getByRole('link', { name: 'URL Item' })).toBeInTheDocument();
});
it('renders with expected role when URL and role are passed', async () => {
render(<MenuItem label="URL Item" url="/some-url" role="menuitem" />);
expect(screen.getByRole('menuitem', { name: 'URL Item' })).toBeInTheDocument();
});
});

View File

@ -1,5 +1,13 @@
import { css, cx } from '@emotion/css';
import React, { ReactElement, useCallback, useState, useRef, useImperativeHandle, CSSProperties } from 'react';
import React, {
ReactElement,
useCallback,
useState,
useRef,
useImperativeHandle,
CSSProperties,
AriaRole,
} from 'react';
import { GrafanaTheme2, LinkTarget } from '@grafana/data';
@ -29,7 +37,7 @@ export interface MenuItemProps<T = unknown> {
/** Icon of the menu item */
icon?: IconName;
/** Role of the menu item */
role?: string;
role?: AriaRole;
/** Url of the menu item */
url?: string;
/** Handler for the click behaviour */
@ -70,7 +78,7 @@ export const MenuItem = React.memo(
disabled,
destructive,
childItems,
role = 'menuitem',
role,
tabIndex = -1,
customSubMenuContainerStyles,
shortcut,
@ -153,7 +161,10 @@ export const MenuItem = React.memo(
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onKeyDown={handleKeys}
role={url === undefined ? role : undefined}
// If there's no URL, then set either the role from the props, or fallback to menuitem
// If there IS a URL, then use the role from props - which will result in this either being a
// link (default role of an anchor), or whatever the user of this component specified
role={!url ? role || 'menuitem' : role}
data-role="menuitem" // used to identify menuitem in Menu.tsx
ref={localRef}
data-testid={testId}