How to Build an Interactive Accordion Component with React and GSAP

React code on a laptop

Jane Phillips

Jane Phillips

Published April 4, 2023
12 minute read

Web development has come a long way in recent years, with new technologies and techniques constantly emerging to help developers create more engaging and interactive user experiences. One such technique is the use of accordion components, which allow users to expand and collapse sections of content on a webpage.

In this article, we‘ll explore how to build a dynamic and visually stunning accordion component using React, a popular JavaScript library for building user interfaces, and the GreenSock Animation Platform (GSAP), a powerful library for creating high-performance animations.

We‘ll cover everything from setting up your development environment to creating the accordion‘s structure, styling it with CSS, and adding interactive animations with GSAP. By the end of this tutorial, you‘ll have a fully functional and visually impressive accordion component that you can use in your own projects.

Prerequisites

Before we dive into building our accordion component, let‘s make sure you have the necessary knowledge and tools:

  • Familiarity with HTML, CSS, and JavaScript
  • Basic understanding of React and React hooks
  • Node.js and npm installed on your machine
  • A code editor of your choice (e.g., Visual Studio Code, Sublime Text, etc.)

Setting Up the Project

First, let‘s create a new React project using Create React App. Open your terminal and navigate to the directory where you want to create your project, then run the following command:

npx create-react-app react-gsap-accordion

This will create a new directory called "react-gsap-accordion" with a basic React project structure inside. Navigate into the project directory:

cd react-gsap-accordion

Next, we‘ll install the GSAP library. Run the following command in your terminal:

npm install gsap

Now, open the project in your code editor and locate the src/App.js file. This is where we‘ll build our accordion component.

Creating the Accordion Structure

Let‘s start by creating the basic structure of our accordion component. Replace the contents of App.js with the following code:

import React, { useState } from ‘react‘;
import ‘./App.css‘;

function App() {
  const [activeIndex, setActiveIndex] = useState(null);

  const accordionData = [
    {
      title: ‘Section 1‘,
      content: ‘Lorem ipsum dolor sit amet, consectetur adipiscing elit.‘
    },
    {
      title: ‘Section 2‘,
      content: ‘Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.‘
    },
    {
      title: ‘Section 3‘, 
      content: ‘Nulla quis lorem ut libero malesuada feugiat.‘
    }
  ];

  const toggleAccordion = (index) => {
    if (activeIndex === index) {
      setActiveIndex(null);
    } else {
      setActiveIndex(index);
    }
  };

  return (
    <div className="App">

      <div className="accordion">
        {accordionData.map((item, index) => (
          <div key={index} className={`accordion-item ${activeIndex === index ? ‘active‘ : ‘‘}`}>
            <div className="accordion-title" onClick={() => toggleAccordion(index)}>
              <h2>{item.title}</h2>
            </div>
            <div className="accordion-content">
              <p>{item.content}</p>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

export default App;

In this code, we:

  1. Import the useState hook from React to manage the active accordion item.
  2. Define an array called accordionData that contains the title and content for each accordion section.
  3. Create a toggleAccordion function that updates the activeIndex state when an accordion title is clicked.
  4. Render the accordion items using the map method on the accordionData array.
  5. Add a conditional class name to each accordion item based on whether it‘s active or not.

Styling the Accordion

Now let‘s add some basic styles to our accordion component. Create a new file called App.css in the src directory and add the following styles:

.App {
  font-family: Arial, sans-serif;
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
}

.accordion {
  border: 1px solid #ccc;
  border-radius: 4px;
}

.accordion-item {
  border-bottom: 1px solid #ccc;
}

.accordion-item:last-child {
  border-bottom: none;
}

.accordion-title {
  background-color: #f1f1f1;
  padding: 10px;
  cursor: pointer;
}

.accordion-content {
  padding: 0 10px;
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease-out;
}

.accordion-item.active .accordion-content {
  max-height: 500px;
  padding: 10px;
}

These styles provide a basic layout and appearance for our accordion component. The key points to note are:

  • The .accordion-content class has a max-height of 0 and overflow set to hidden to initially hide the content.
  • The .accordion-item.active .accordion-content selector sets a max-height and padding when an accordion item is active, which will trigger the transition effect.

Adding GSAP Animations

Now it‘s time to add some interactive animations to our accordion using GSAP. First, import the gsap module at the top of your App.js file:

import { gsap } from ‘gsap‘;

Next, update the toggleAccordion function to animate the accordion content when it‘s opened or closed:

const toggleAccordion = (index) => {
  if (activeIndex === index) {
    gsap.to(`.accordion-item:nth-child(${index + 1}) .accordion-content`, {
      maxHeight: 0,
      duration: 0.3,
      ease: ‘power1.out‘
    });
    setActiveIndex(null);
  } else {
    if (activeIndex !== null) {
      gsap.to(`.accordion-item:nth-child(${activeIndex + 1}) .accordion-content`, {
        maxHeight: 0,
        duration: 0.3,
        ease: ‘power1.out‘
      });
    }
    gsap.fromTo(
      `.accordion-item:nth-child(${index + 1}) .accordion-content`,
      { maxHeight: 0 },
      {
        maxHeight: ‘auto‘,
        duration: 0.3,
        ease: ‘power1.out‘
      }
    );
    setActiveIndex(index);
  }
};

In this updated function:

  1. If the clicked accordion item is already active, we use gsap.to to animate its content‘s maxHeight to 0, effectively closing it.
  2. If the clicked accordion item is not active and another item is currently active, we first close the currently active item using gsap.to.
  3. We then use gsap.fromTo to animate the clicked item‘s content from a maxHeight of 0 to ‘auto‘, which will smoothly expand the content.

Final Result and Enhancements

With these changes, your accordion component should now have smooth, interactive animations when opening and closing items. Here‘s what the final App.js file should look like:

import React, { useState } from ‘react‘;
import { gsap } from ‘gsap‘;
import ‘./App.css‘;

function App() {
  const [activeIndex, setActiveIndex] = useState(null);

  const accordionData = [
    {
      title: ‘Section 1‘,
      content: ‘Lorem ipsum dolor sit amet, consectetur adipiscing elit.‘
    },
    {
      title: ‘Section 2‘,
      content: ‘Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.‘
    },
    {
      title: ‘Section 3‘,
      content: ‘Nulla quis lorem ut libero malesuada feugiat.‘
    }
  ];

  const toggleAccordion = (index) => {
    if (activeIndex === index) {
      gsap.to(`.accordion-item:nth-child(${index + 1}) .accordion-content`, {
        maxHeight: 0,
        duration: 0.3,
        ease: ‘power1.out‘
      });
      setActiveIndex(null);
    } else {
      if (activeIndex !== null) {
        gsap.to(`.accordion-item:nth-child(${activeIndex + 1}) .accordion-content`, {
          maxHeight: 0,
          duration: 0.3,
          ease: ‘power1.out‘
        });
      }
      gsap.fromTo(
        `.accordion-item:nth-child(${index + 1}) .accordion-content`,
        { maxHeight: 0 },
        {
          maxHeight: ‘auto‘,
          duration: 0.3,
          ease: ‘power1.out‘
        }
      );
      setActiveIndex(index);
    }
  };

  return (
    <div className="App">

      <div className="accordion">
        {accordionData.map((item, index) => (
          <div key={index} className={`accordion-item ${activeIndex === index ? ‘active‘ : ‘‘}`}>
            <div className="accordion-title" onClick={() => toggleAccordion(index)}>
              <h2>{item.title}</h2>
            </div>
            <div className="accordion-content">
              <p>{item.content}</p>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

export default App;

You can further enhance the accordion component by:

  1. Adding chevron icons that rotate when an item is opened or closed.
  2. Implementing keyboard accessibility, so users can navigate and interact with the accordion using their keyboard.
  3. Creating separate components for the accordion and accordion item to improve code organization and reusability.

Conclusion

In this tutorial, we‘ve covered how to create an interactive accordion component using React and GSAP. We started by setting up a new React project and installing the necessary dependencies. Then, we built the accordion‘s structure, styled it with CSS, and added smooth animations using GSAP.

By following these steps and exploring the suggested enhancements, you can create a polished and engaging accordion component that elevates your web development projects. Remember to experiment, customize, and adapt this component to fit your specific needs and design preferences.

Happy coding!

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *