skip to Main Content

I aim to create a custom MUI accordion which should look like this:
Accordion aim look

Now, I have attempted in creating this custom MUI accordion using these code structure (this accordion also uses some custom search box functionality and custom accordion data)

Accordion source code:

import * as React from "react";
import { useState } from "react";
import AccordionMUI from "@mui/material/Accordion";
import AccordionSummary from "@mui/material/AccordionSummary";
import AccordionDetails from "@mui/material/AccordionDetails";
import Typography from "@mui/material/Typography";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import "./globals.css";
import { accordionData } from "./accordionData.js";
import AddCircleIcon from "@mui/icons-material/AddCircle";
import RemoveCircleIcon from "@mui/icons-material/RemoveCircle";


export default function SimpleAccordion() {
  const [search, setSearch] = useState("");
  return (
    <div>
      <input
        onChange={(e) => setSearch(e.target.value)}
        type="text"
        placeholder="Search"
      />

      {accordionData
        .filter((item) => {
          return search.toLowerCase() === ""
            ? item
            : item.sectionTitle.toLowerCase().includes(search);
        })
        .map((item) => (
          <AccordionMUI key={item.id} className="accordionMui">
            <AccordionSummary
              expandIcon={<AddCircleIcon sx={{ color: "#384558" }} />}
              aria-controls="panel1a-content"
              id="panel1a-header"
            >
              <Typography>
                <b>{item.sectionTitle}</b>
              </Typography>
            </AccordionSummary>
            <AccordionDetails>
              <Typography>{item.sectionContent}</Typography>
            </AccordionDetails>
          </AccordionMUI>
        ))}
    </div>
  );
}

CSS styling source code:

.accordionMui {
  background-color: rgba(242, 242, 242, 0.1);
  box-shadow: none;
  color: #384558;
}

#panel1a-header {
  padding-top: 5%;
  padding-bottom: 5%;
}

Full working demo here on CodeSandbox.

It currently looks like this:
current look accordion

My issue is that the last divider line of my accordion is not showing up unlike from its previous sections where there is a divider line on them below. I also want to override the styling of the divider line of the accordion and make it thicker.

I also wanted to change the collapse icons into their respective states (not expanded accordion will display AddCircleIcon, expanded accordion will display RemoveCircleIcon) but a problem arises which shows Cannot find name ‘expanded’ when I use this ternary condition expanded={expanded === 'panel1'} just like from this stack accepted question (How to change icon when accordion summary is expanded?). Thus, I am not sure how to change the collapse icons based from their states of being expanded or not expanded yet.

I am still quite confused and unsure on which classes I should use on the Accordion API of MUI and it would be of great help to gain some guides in regards to properly customizing and overriding the Accordion component from MUI as I am still learning MUI along the way.

Your responses would indeed help me a lot on this one. Thank you very much.

2

Answers


  1. You could do like this:

    1. Change to a different icon when expanded:

    just like from this stack accepted question (How to change icon when accordion summary is expanded?). Thus, I am not sure how to change the collapse icons based from their states of being expanded or not expanded yet.

    -> As per the mui accordion documentation and the way of doing in the stack question is almost same:

    You need to set state to handle AccordionMUI and control by using icons.

    ...
      const [expanded, setExpanded] = React.useState(false);
      const handleChange = (panel) => (event, newExpanded) => {
        setExpanded(newExpanded ? panel : false);
      };
    ...
      <AccordionMUI
         key={item.id}
        //set unique item id for each accordion
         expanded={expanded === item.id}
         onChange={handleChange(item.id)}
         className="accordionMui"
      >
      <AccordionSummary
         expandIcon={
         expanded === item.id ? <RemoveCircleIcon /> : 
         <AddCircleIcon />
         } 
      >
      ...
    ...
    
    1. Make divider line thicker & Missing divider line

    –> You need to remove this: (to show background color instead of box-shadow)

    box-shadow: none;
    

    Updated demo:

    Edit BasicAccordion demo — Material UI (forked)

    I hope this helps!

    Login or Signup to reply.
  2. Great question.

    The Accordion component is a MUI-opinionated Collapse component. Perhaps instead of trying to wrangle Accordion, how about making a custom component using Collapse?

    CodeSandbox Example

    function CustomAccordion(props) {
      const { data } = props
      const [isOpen, setIsOpen] = useState(true)
    
      return (
        <>
          <Box
            display="flex"
            justifyContent="space-between"
            height="60px"
            alignItems="center"
          >
            <Box sx={{ fontWeight: 'bold' }}>{data.title}</Box>
            <IconButton onClick={() => setIsOpen(!isOpen)}>
              {isOpen ? <AddCircle /> : <RemoveCircle />}
            </IconButton>
          </Box>
          <Collapse in={!isOpen} sx={{textAlign: 'left'}}>
            {data.content}
          </Collapse>
          <Divider />
        </>
      )
    }
    
    export default CustomAccordion
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search