Reputation: 1450
I have a simple material-ui List
containing ListItem
elements.
I want a Popover
to appear beside whatever ListItem
I place the mouse over. For this I am using the mouseEnter
event. In its handler I set the anchor element of the Popover
to be the ListItem
that the mouse pointer is currently over.
This works fine for the first element which I hover over. However because the Popover
is essentially behaving in a "modal" type fashion, when I move to another ListItem
in the List its mouseEnter
event doesn't get fired.
I've been at this for a few hours now and can't find a way around it ?
Here's a CodeSandbox. Try hovering on one of the ListItem
s and you'll see output in the console. Try moving to another and nothing happens.
import React, { useState } from "react";
import "./styles.css";
import { List, ListItem, ListItemText, Popover } from "@material-ui/core";
export default function App() {
const [popoverAnchorElement, setPopoverAnchorElement] = useState(null);
const handleMouseEnter = event => {
console.log("onMouseEnter - " + event.currentTarget.textContent);
setPopoverAnchorElement(event.currentTarget);
};
const handleClose = (event, index) => {
setPopoverAnchorElement(null);
};
let isPopoverOpen = Boolean(popoverAnchorElement);
return (
<div className="App">
<List style={{ maxWidth: "100px" }}>
<ListItem button>
<ListItemText onMouseEnter={handleMouseEnter}>ListItem1</ListItemText>
</ListItem>
<ListItem button>
<ListItemText onMouseEnter={handleMouseEnter}>ListItem2</ListItemText>
</ListItem>
<ListItem button>
<ListItemText onMouseEnter={handleMouseEnter}>ListItem3</ListItemText>
</ListItem>
</List>
<Popover
open={isPopoverOpen}
onClose={handleClose}
anchorEl={popoverAnchorElement}
anchorOrigin={{
vertical: "top",
horizontal: "center"
}}
transformOrigin={{
vertical: "top",
horizontal: "left"
}}
>
<ListItem button>
<ListItemText>ListItemInPopover</ListItemText>
</ListItem>
</Popover>
</div>
);
}
Upvotes: 1
Views: 1153
Reputation: 2254
The Popover
component overlays the whole screen (position:fixed; left:0; top:0; right:0; bottom:0; z-index:1300
), effectively blocking any mouse events from lower items.
You could try to circumvent this, for instance adding pointer-events:none;
to its overlay element would allow cursor events to pass through it.
But, using a component that blocks the whole viewport just for a small menu item seems odd to me and is likely an uphill battle.
There is a similar component in the same library called Popper
, which probably is more suited to your needs. Here you can see I've converted your Popover
to a Popper
and you get results a little more like what you're expecting. (Note I added some CSS to this element in the code sandbox to make it clearer.)
<Popper
open={isPopoverOpen}
onClose={handleClose}
anchorEl={popoverAnchorElement}
className="popper-item"
>
<ListItem button>
<ListItemText>ListItemInPopover</ListItemText>
</ListItem>
</Popper>
https://codesandbox.io/s/keen-smoke-x8tu7
I will note that the documentation points out that Popper
will not automatically close if you click away from these items, but that this can be added.
You might also look into the MenuList
component which uses Popper
under the hood but also handles some state for you.
Upvotes: 1