6

I want to change the icon based on whether the accordion is expanded or not.

I see that on the material ui page that the CSS have .Mui-expanded which can see whether expanded={true} or false, but how can I use this to set a different icon when expanded is true or false.

So I want to set IconA if expand is true and IconB if expand is false.

expandIcon={<IconA/>}
Tuan Le
  • 103
  • 1
  • 3
  • 10

3 Answers3

12

You can use expandIcon prop available for AccordionSummary component. Set condition like this: expandIcon={expanded === 'panel1'?<ExpandMoreIcon />:<Minimize/>}

<Accordion expanded={expanded === 'panel1'} onChange={handleChange('panel1')}>
    <AccordionSummary
      expandIcon={expanded === 'panel1'?<ExpandMoreIcon />:<Minimize/>}
      aria-controls="panel1bh-content"
      id="panel1bh-header"
    >
      <Typography className={classes.heading}>General settings</Typography>
      <Typography className={classes.secondaryHeading}>I am an accordion</Typography>
    </AccordionSummary>
    <AccordionDetails>
      <Typography>
        Nulla facilisi. Phasellus sollicitudin nulla et quam mattis feugiat. Aliquam eget
        maximus est, id dignissim quam.
      </Typography>
    </AccordionDetails>
  </Accordion>

This sample code is taken from docs:https://material-ui.com/components/accordion/#controlled-accordion

Murli Prajapati
  • 8,833
  • 5
  • 38
  • 55
5

The solution mentioned above https://stackoverflow.com/a/63691313/11603006 is absolutely right but has the disadvantage that you must use a useState hook to show a different icon when the accordion is collapsed/expanded. This makes it however difficult (impossible?) to specify a custom expandIcon globally in the Theme. Therefore Mui should in my opinion pass the expand state to the expandIcon prop. There is a feature request for this https://github.com/mui/material-ui/issues/18326 but it has not been implemented yet. As a workaround and an alternative to the above solution, which has the benefit that it can be used in the theme globaly, it is possible to provide a custom icon in that way:

  const CustomExpandIcon = () => {
    return (
      <Box
        sx={{
          '.Mui-expanded & > .collapsIconWrapper': {
            display: 'none',
          },
          '.expandIconWrapper': {
            display: 'none',
          },
          '.Mui-expanded & > .expandIconWrapper': {
            display: 'block',
          },
        }}
      >
        <div className="expandIconWrapper">
          <MinusIcon />
        </div>
        <div className="collapsIconWrapper">
          <PlusIcon />
        </div>
      </Box>
    )
  }

See: https://codesandbox.io/s/basicaccordion-material-demo-forked-2916o

Jonathan
  • 517
  • 1
  • 6
  • 12
2

you can use conditional rendering

     <Accordion
      key={index + 1}
      className={style.accordianMargin}
      expanded={expanded === index + 1}
      onChange={handleChange(index + 1)}
    >
      <AccordionSummary
        expandIcon={
          expanded && opened === index + 1 ? <RemoveIcon /> : 
                                                <AddIcon />
        }
      >
Sehrish Waheed
  • 1,230
  • 14
  • 17