Make toggle/collapsable content

Recently I was building a React Web App for my side project and wanted a toggle/collapsable component. So like a caveman I planned to add an "onclick" event listener on the title div and add an arrow to the title using "::before" in the title CSS.

Then I searched to check if there was a better way to implement this and that is when I came across the following 2 options,

  1. "details" HTML tag
  2. Accordion Material UI component

details tag

When using the "details" tag, you need to have two elements inside the tag, one is the "summary" tag which would be the title and the other would ideally be a "div" containing the content that you want to display on click of the title.

  <details>
    <summary>Title of the content</summary>
    <div>
      <p>Details of the content that you want to display on the click of the title</p> 
      <ul>
        <li>List Item 1</li>
        <li>List Item 2</li>
        <li>List Item 3</li>
        <li>List Item 4</li>
      </ul>
   </div>
  </details>

The above HTML code would give a collapsable component.

Accordion Material UI component

"Accordion" component is similar to use, the "Accordion" component should have an "AccordionSummary" component for the title and an "AccordionDetails" component for the content. Following is the code that I have taken from the official Docs of Material UI.

import React from 'react';
import { Theme, createStyles, makeStyles } from '@material-ui/core/styles';
import Accordion from '@material-ui/core/Accordion';
import AccordionSummary from '@material-ui/core/AccordionSummary';
import AccordionDetails from '@material-ui/core/AccordionDetails';
import Typography from '@material-ui/core/Typography';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';

const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    root: {
      width: '100%',
    },
    heading: {
      fontSize: theme.typography.pxToRem(15),
      fontWeight: theme.typography.fontWeightRegular,
    },
  }),
);

export default function SimpleAccordion() {
  const classes = useStyles();

  return (
    <div className={classes.root}>
      <Accordion>
        <AccordionSummary
          expandIcon={<ExpandMoreIcon />}
          aria-controls="panel1a-content"
          id="panel1a-header"
        >
          <Typography className={classes.heading}>Accordion 1</Typography>
        </AccordionSummary>
        <AccordionDetails>
          <Typography>
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex,
            sit amet blandit leo lobortis eget.
          </Typography>
        </AccordionDetails>
      </Accordion>
      <Accordion>
        <AccordionSummary
          expandIcon={<ExpandMoreIcon />}
          aria-controls="panel2a-content"
          id="panel2a-header"
        >
          <Typography className={classes.heading}>Accordion 2</Typography>
        </AccordionSummary>
        <AccordionDetails>
          <Typography>
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex,
            sit amet blandit leo lobortis eget.
          </Typography>
        </AccordionDetails>
      </Accordion>
    </div>
  );
}

That's all for this post. This is my first post on Hashnode so if you do find it useful do let me know. I plan to share more of my learnings on Hashnode.