[menu] Allow Menu Items to be focused via keyboard when wrapped in <span> and <Tooltip> tags
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 99.1k
- Forks
- 32.5k
- Avg merge
- 2d 17h
- Merged PRs (30d)
- 106
Description
Summary
While trying to create a keyboard accessible dropdown menu, MenuItems were wrapped in a <Tooltip> and <span> became inaccessible and broke the accessibility of the dropdown menu. The Menu itself was selectable via keyboard, but the items wrapped in both <Tooltip> and <span> within it were completely inaccessible.
Example of an inaccessible MenuItem:
<Tooltip title={"This is menu item 1"} placement="top" arrow>
<span>
<MenuItem>
Menu Item 1
</MenuItem>
</span>
</Tooltip>
Examples
This menu is not keyboard accessible.
Specific keystrokes were tab to select the menu, return to open, and then I tried both tab and arrow keys to try and focus a specific Menu Item.
<Button onClick={handleMenuOpen}>Dropdown Menu</Button>
<Menu
open={isOpen}
onClose={handleMenuClose}
>
<Tooltip title={"This is menu item 1"} placement="top" arrow>
<span>
<MenuItem>
Menu Item 1
</MenuItem>
</span>
</Tooltip>
<Tooltip title={"This is menu item 2"} placement="top" arrow>
<MenuItem>
Menu Item 2
</MenuItem>
</Tooltip>
</Menu>
This example is keyboard accessible. When opened with tab + return the first menu item is auto-focused.
<Button onClick={handleMenuOpen}>Dropdown Menu</Button>
<Menu
open={isOpen}
onClose={handleMenuClose}
>
<Tooltip title={"This is menu item 1"} placement="top" arrow>
<MenuItem>
Menu Item 1
</MenuItem>
</Tooltip>
<Tooltip title={"This is menu item 2"} placement="top" arrow>
<MenuItem>
Menu Item 2
</MenuItem>
</Tooltip>
</Menu>
Both examples built by using create-react-app to generate a clean application and then MUI was installed with in the application.
Expanded code snippets
Full code for breaking PoC app
import { useState } from 'react';
import { Button, Menu, MenuItem, Tooltip } from '@mui/material';
function App() {
const [isOpen, setIsOpen] = useState(false)
const handleMenuOpen = () => {
setIsOpen(true)
}
const handleMenuClose = () => {
setIsOpen(false)
}
return (
<div className="App">
<header className="App-header">
<Button onClick={handleMenuOpen}>Dropdown Menu</Button>
<Menu
open={isOpen}
onClose={handleMenuClose}
>
<Tooltip title={"This is menu item 1"} placement="top" arrow>
<span>
<MenuItem>
Menu Item 1
</MenuItem>
</span>
</Tooltip>
<Tooltip title={"This is menu item 2"} placement="top" arrow>
<MenuItem>
Menu Item 2
</MenuItem>
</Tooltip>
</Menu>
</header>
</div>
);
}
export default App;
Relevant `package.json` properties
"dependencies": {
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@mui/material": "^5.15.20",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
Motivation
I am trying to create a keyboard accessible dropdown menu with MenuItems that are wrapped in <span> tags for formatting, styling, and some minor control functions.
Search keywords: MenuItem Span Accessibility
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.