reactjsmaterial-uiiconsaccordionexpand

mui controlled accordion icon changes on all accordions when clicking on one specific


As the title says, I am mapping on an array of data, rendering multiple controlled accordions.
Each accordion open/closes individually when i click on one of them but not the icons.
When I click on an accordion, its icon changes correctly but so are the icons on the others accordions that should not change.
I know it is because i'm mapping but i don't know how to add an id to each accordionSummary's icon.
Here is my code :

import * as React from 'react';
import Accordion from '@mui/material/Accordion';
import AccordionDetails from '@mui/material/AccordionDetails';
import AccordionSummary from '@mui/material/AccordionSummary';
import Typography from '@mui/material/Typography';
import ControlPointIcon from '@mui/icons-material/ControlPoint';
import RemoveCircleOutlineIcon from '@mui/icons-material/RemoveCircleOutline';



const data = [{left: "general settings", right:"this is an accoridon", text :"blabla", id:"pannel-1"}, {left:"users", "right": "you'r not an user", text:"allela eegf aa ", id:"pannel-2"}]


export default function ControlledAccordions() {
  const [expanded, setExpanded] = React.useState<string | false>(false);
  const expandicon = expanded ? <RemoveCircleOutlineIcon /> : <ControlPointIcon />

  const handleChange =
    (panel: string) => (event: React.SyntheticEvent, isExpanded: boolean) => {
      setExpanded(isExpanded ? panel : false);
    };

  return (
    <div>
     {data.map((item) => 
      <Accordion expanded={expanded === item?.id} onChange={handleChange(item.id)}>
      <AccordionSummary
        expandIcon={expandicon}
        id={item.id}
      >
        <Typography sx={{ width: '33%', flexShrink: 0 }}>
         {item.left}
        </Typography>
        <Typography sx={{ color: 'text.secondary' }}>{item.right}</Typography>
      </AccordionSummary>
      <AccordionDetails>
        <Typography>
         {item.text}
        </Typography>
      </AccordionDetails>
    </Accordion>)}
     
   
    </div>
  );
}

How can I individualize each icon ?


Solution

  • Use the same logic as expanded attribute of Accordion, you can modify the AccordionSummary as follows:

    <AccordionSummary
      expandIcon={
        expanded === item?.id ? (
          <RemoveCircleOutlineIcon />
        ) : (
          <ControlPointIcon />
        )
      }
      id={item.id}
    >
      /*...*/
    </AccordionSummary>
    

    and the expandicon variable can be removed.