material-uiaccordiononblur

How to collapse React MUI Accordion onblur


I have a MUI Accordion in my React project, and I would like for it to collapse when the user clicks somewhere else on the page.

I would like to do this via css, as I am doing the following via css:

.focus {
    /* border: 2px solid red !important; */
    background-color: white !important;
}


                <Accordion>
                  <AccordionSummary
                    focusVisibleClassName='focus'
                    expandIcon={<ExpandMoreIcon />}
                    aria-controls="panel1a-content"
                    id="panel1a-header"
                  >
                    <TextField
                      style={{ width: 350 }}
                      id="entityName"
                      value={entity.entityName}
                      onChange={(event) => {
                        setEntity({ ...entity, entityName: event.target.value });
                      }}
                    />
                  </AccordionSummary>
                  <AccordionDetails sx={{ borderTop: '1px dashed black', width: 400 }}>
                    <Typography>
                      Source
                    </Typography>
                    <TextField sx={{ width: 350 }}></TextField>

                    <Typography>
                      Classification
                    </Typography>
                    <TextField sx={{ width: 350 }}></TextField>
                  </AccordionDetails>
                </Accordion>

I appreciate your assistance.

I have searched on this requirement, and not found any results.


Solution

  • You can implement ClickAwayListener component to detect when a click event happens outside of its child element. And to get the current state of the expended prop you have to add onChange prop to your Accordion component, and finally make use of expanded prop to set its value (true/false). Please take a look at the code below for a better understanding. also, a working example was added as a link.

    Import:

    import ClickAwayListener from '@mui/material/ClickAwayListener';
    

    And inside your function:

    const [open, setOpen] = useState(false);
    const handleClickAway = () => {
    if(open){
      setOpen(false);
    }
    };
    
    return (
    
    <ClickAwayListener onClickAway={handleClickAway}>       
    
        <Accordion expanded={open} onChange={(e,expanded)=>{setOpen(expanded)}}>
          <AccordionSummary
            focusVisibleClassName='focus'
            expandIcon={<ExpandMoreIcon />}
            aria-controls="panel1a-content"
            id="panel1a-header"
          >
            <TextField
              style={{ width: 350 }}
              id="entityName"
              value={entity.entityName}
              onChange={(event) => {
                setEntity({ ...entity, entityName: event.target.value });
              }}
            />
          </AccordionSummary>
          <AccordionDetails sx={{ borderTop: '1px dashed black', width: 400 }}>
            <Typography>
              Source
            </Typography>
            <TextField sx={{ width: 350 }}></TextField>
    
            <Typography>
              Classification
            </Typography>
            <TextField sx={{ width: 350 }}></TextField>
          </AccordionDetails>
        </Accordion>
    
    </ClickAwayListener>
    
    );
    

    https://codesandbox.io/s/mui-accordion-clickoutside-kmg1eb?file=/demo.js