Home > Software engineering >  How to expand Material UI accordion on mouse over
How to expand Material UI accordion on mouse over

Time:11-26

I would like to expand Material UI accordions by mouse hover. But I can't see any prop which could be useful. I checked onMouseOver, onMouseEnter but when its fired closes the accordion. I would simpler for user to avoid over-clicking. I've also add some css parts "&:hover" to const Accordion, but without succses.

const Accordion = withStyles({
    root: {
        border: '1px solid rgba(0, 0, 0, .125)',
        boxShadow: 'none',
        '&:not(:last-child)': {
            borderBottom: 0,
        },
        '&:before': {
            display: 'none',
        },
        '&$expanded': {
            margin: 'auto',
        },
    },
    expanded: {},
})(MuiAccordion);
const AccordionSummary = withStyles({
    root: {
        backgroundColor: 'rgba(0, 0, 0, 0)',
        borderBottom: '1px solid rgba(0, 0, 0, .125)',
        marginBottom: -1,
        minHeight: 30,
        '&$expanded': {
            minHeight: 30,
        },
    },
    content: {
        '&$expanded': {
            margin: '12px 0',
        },
    },
    expanded: {},
})(MuiAccordionSummary);
const AccordionDetails = withStyles((theme) => ({
    root: {
        padding: theme.spacing(2),
    },
}))(MuiAccordionDetails);
export default function CategoryList(props) {
    const [expanded, setExpanded] = React.useState('panel1');

    const handleChange = (panel) => (event, newExpanded) => {
        setExpanded(newExpanded ? panel : false);
    };

    return (
        <div>
            {props.categories.map(category =>
                <Accordion
                    square
                    expanded={expanded === category.label}
                    // onChange={handleChange(category.label)}
                    onMouseMove={handleChange(category.label)}
                    >
                    <AccordionSummary
                        expandIcon={<ExpandMoreIcon fontSize={"small"}/>}
                        aria-controls="panel1d-content" id="panel1d-header">
                        <Typography>{category.label}</Typography>
                    </AccordionSummary>
                    <AccordionDetails>
                        <CategoryItem category={category}/>
                    </AccordionDetails>
                </Accordion>
            )}
        </div>
    );
}

jklkjlk

CodePudding user response:

I think you are pretty close but you don't want to open or close the Accordion on onChange or onMouseMove handlers, but rather onMouseOver.

I did a minimum reproducible example here

Basically I changed the callback to

  const handleChange = (panel) => {
    setExpanded(panel);
  };

Added a callback onm ouseLeave for the Accordion container <div> (to reset the expanded value) and called the handleChange onm ouseOver the Accordion so:

<div onm ouseLeave={() => {handleChange("");}}>
  {categories.map((category) => (
    <Accordion
      square
      expanded={expanded === category.label}
      onMouseOver={() => handleChange(category.label)}
    >
    ...

onMouseLeave callback from the container div you can also call handleChange("pannel1") (instead of handleChange("")) if you want that to be opened when the mouse is not hovering over any category element, or even ignore that part completely if you are fine with leaving the last hovered Accordion expanded.

PS: If you create a minimum reproducible example yourself in the future it would make the life of people who can help way easier :)

  • Related