Material-UI: Expand Accordion by clicking the icon only

Viewed 11198

I have created an Accordion for my Project. But I want the panel to be expanded only when the expand icon is clicked. Currently it is expanding on clicking anywhere on the panel. Can we customize its expanding behavior ?

CODE:

import React from "react";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
import Accordion from "@material-ui/core/Accordion";
import AccordionDetails from "@material-ui/core/AccordionDetails";
import Typography from "@material-ui/core/Typography";
import AccordionSummary from "@material-ui/core/AccordionSummary";

export default function App() {
return (
    <div style={{}}>
    <h4>How to create Accordion in ReactJS?</h4>
    <Accordion style={{ width: 400}}>
        <AccordionSummary 
         expandIcon={<ExpandMoreIcon />}
         aria-controls="panel1a-content"
        >   
          <div>Click to Expand</div>
        </AccordionSummary>
        <AccordionDetails>
        <Typography>Greetings of the day :)</Typography>
        </AccordionDetails>
    </Accordion>
    </div>
);
}
2 Answers

Yes we can do it like this

1- Create our own state with handler:

  const [expand, setExpand] = React.useState(false);
  const toggleAcordion = () => {
    setExpand((prev) => !prev);
  };

2- Add our state to the Accordion:

<Accordion expanded={expand} style={{ width: 400 }}>

3- Add onClick for the icon:

    <AccordionSummary
      expandIcon={<ExpandMoreIcon />}
      aria-controls="panel1a-content"
      IconButtonProps={{
        onClick: toggleAcordion
      }}
    >

Full Code:

Codesandbox Demo

EDIT: Explanation: Material-UI Accordion has its own state (open or close) and its own click handler, what we did above is that we create our own state and override Material-UI Accordion state by the prop expanded and add event listener onClick to the icon button by the prop IconButtonProps, our event listener will open or close the Accordion by change our state.

NOTE: The code above doesn't change the style in case of the cursor pointer.

There is no public API to do what you want out-of-the-box, but you can use this CSS trick:

V5

<AccordionSummary
  sx={{
    pointerEvents: "none"
  }}
  expandIcon={
    <ExpandMoreIcon
      sx={{
        pointerEvents: "auto"
      }}
    />
  }
>

V4

const useStyles = makeStyles({
  summary: {
    pointerEvents: 'none',
  },
  icon: {
    pointerEvents: 'auto',
  },
});
<AccordionSummary
  className={classes.summary}
  expandIcon={<ExpandMoreIcon className={classes.icon} />}
>
  <Typography>Accordion 1</Typography>
</AccordionSummary>

Live Demo

Codesandbox Demo

Related