Building a Custom React Accordion Inspired by Material-UI

Accordions are popular UI components that allow users to hide and reveal content on demand. In this tutorial, we'll create a custom accordion using React and TypeScript, inspired by the elegant design of Material-UI's Accordion. We'll walk through the steps of setting up the project, implementing the component, and styling it to match the Material-UI style.

Prerequisites:

Basic knowledge of React and TypeScript Node.js and npm installed on your machine

Step 1: Project Setup

We'll begin by setting up a new React project with TypeScript using create-react-app:

npx create-react-app my-accordion-app --template typescript
cd my-accordion-app
npm start

Step 2: Implementing the Accordion Component

Next, let's create a new component named "Accordion.tsx" in the "src" folder. The Accordion component will accept an array of sections as props, each containing a title and content.

// src/Accordion.tsx
 
import React, { useState } from 'react';
import styles from './Accordion.module.css'; // Import CSS module
 
interface AccordionProps {
  sections: {
    title: string;
    content: string;
  }[];
}
 
interface AccordionState {
  activeIndex: number | null;
}
 
const Accordion: React.FC<AccordionProps> = ({ sections }) => {
  const [activeIndex, setActiveIndex] = useState<number | null>(null);
 
  const toggleSection = (index: number) => {
    setActiveIndex((prevIndex) => (prevIndex === index ? null : index));
  };
 
  return (
    <div className={styles.accordion}>
      {sections.map((section, index) => (
        <div key={index} className={styles['accordion-section']}>
          <button
            className={`${styles['accordion-toggle']} ${
              index === activeIndex ? styles.active : ''
            }`}
            onClick={() => toggleSection(index)}
          >
            <span>{section.title}</span>
            <span className={`${styles.icon}`}>{index === activeIndex ? '-' : '+'}</span>
          </button>
          <div
            className={`${styles['accordion-content']} ${
              index === activeIndex ? styles.activeContent : ''
            }`}
          >
            {section.content}
          </div>
        </div>
      ))}
    </div>
  );
};
 
export default Accordion;

Step 3: Styling the Accordion Component

To make our Accordion visually appealing, we'll create a CSS file named "Accordion.module.css" in the "src" folder. Here, we'll define styles for the accordion, sections, toggle buttons, and the expanding content.

/* src/Accordion.module.css */
 
.accordion {
  width: 100%;
}
 
.accordion-section {
  border: 1px solid #e0e0e0;
  margin-bottom: 5px;
  border-radius: 4px;
  overflow: hidden;
}
 
.accordion-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  background-color: #f0f0f0;
  border: none;
  padding: 10px;
  text-align: left;
  font-weight: bold;
  cursor: pointer;
}
 
.active {
  background-color: #f5f5f5;
}
 
.accordion-content {
  overflow: hidden;
  padding: 10px;
  background-color: #ffffff;
  transition: max-height 0.3s ease-out;
  max-height: 0;
}
 
.activeContent {
  max-height: 1000px; /* Adjust the max height based on your content */
}
 
.icon {
  font-size: 18px;
}
 

Step 4: Using the Accordion Component

With our Accordion component and styles in place, we can now use it in our main application. Update the "App.tsx" file as follows:

// src/App.tsx
 
import React from 'react';
import Accordion from './Accordion';
 
const sections = [
  {
    title: 'Section 1',
    content: 'Content for section 1',
  },
  {
    title: 'Section 2',
    content: 'Content for section 2',
  },
  {
    title: 'Section 3',
    content: 'Content for section 3',
  },
];
 
const App: React.FC = () => {
  return (
    <div>
      <h1>Accordion Example</h1>
      <Accordion sections={sections} />
    </div>
  );
};
 
export default App;

Conclusion: In this tutorial, we built a custom accordion component in React and TypeScript, inspired by the elegant design of Material-UI's Accordion. We implemented the component with state management to toggle sections and applied CSS styles to make it visually appealing. While this implementation is not an exact replica of Material-UI's Accordion, it serves as a foundation for creating custom UI elements with similar aesthetics.

Remember, design is subjective, and you can further customize the styles and animations to match your project's specific requirements. Play around with different color schemes, add icons, or adjust transition effects to create a unique and polished accordion for your application.