Menu

Building the Expandable Accordion Component

Building the Expandable Accordion Component

This Expandable Accordion Component uses a Functional Component in React, along with the useState hook, to manage which section is currently active.

The data array stores multiple accordion items, and each item is rendered dynamically using the map function, with each section receiving a title and hidden content.

When a user clicks an accordion header, the onClick event triggers the toggleItem function, which checks the current activeIndex and updates it to open the selected section if it is closed, or to close it if it is already open.

Based on this state change, conditional rendering is applied to show or hide the content, and the UI smoothly expands or collapses using a CSS grid-based transition (grid-template-rows).

This ensures that only one section remains open at a time, and that the interface updates instantly and smoothly in response to user interaction.

File Pa****th: Expandable Accordion\src\components\ExpandableAccordion.jsx

import React, { useState } from 'react'


function ExpandableAccordion() {


    const [activeIndex, setActiveIndex] = useState(null)


    const data = [
        {
            title: "Frontend Development",
            content: "Frontend development focuses on building the visual and interactive parts of a website using HTML, CSS, and JavaScript to create user-friendly interfaces."
        },
        {
            title: "Responsive Design",
            content: "Responsive design ensures a website automatically adjusts to different screen sizes like mobile, tablet, and desktop for a smooth user experience."
        },
        {
            title: "Web Performance",
            content: "Web performance is about improving speed and efficiency by optimizing images, reducing unnecessary code, and enhancing loading time."
        },
        {
            title: "UI/UX Design",
            content: "UI/UX design focuses on how a website looks and feels, ensuring it is visually appealing, easy to navigate, and user-centric."
        },
        {
            title: "Version Control",
            content: "Version control helps developers track changes in code, collaborate with teams, and manage project history using tools like Git."
        }
    ]


    const toggleItem = (index) => {
        setActiveIndex(activeIndex === index ? null : index)
    }


    return (
        <>
            <div className="main-wrapper flex flex-col items-center w-full min-h-screen px-4 md:px-8 py-8">


                <h1 className="text-2xl md:text-3xl lg:text-4xl font-bold mb-6">
                    Expandable Accordion
                </h1>


                <h2 className="text-sm md:text-base text-slate-600 text-center max-w-lg leading-7 mb-8 font-medium tracking-wide">
                    An interactive UI component with smooth expand and collapse behavior.
                </h2>


                <div className="w-full max-w-2xl space-y-3">


                    {data.map((item, index) => (
                        <div
                            key={index}
                            className="border border-blue-900 rounded-lg overflow-hidden shadow-sm"
                        >


                            {/* Header */}
                            <button
                                onClick={() => toggleItem(index)}
                                className="accordion w-full flex justify-between items-center p-4 bg-blue-100 hover:bg-blue-400 hover:text-white transition cursor-pointer"
                            >
                                <span className="font-medium text-left">
                                    {item.title}
                                </span>


                                <span className="text-xl">
                                    {activeIndex === index ? "−" : "+"}
                                </span>
                            </button>


                            {/* Content */}
                            <div
                                className={`grid transition-[grid-template-rows] duration-300 ease-in-out ${activeIndex === index ? "grid-rows-[1fr]" : "grid-rows-[0fr]"
                                    }`}
                            >
                                <div className="overflow-hidden">
                                    <div className="px-4 py-3">
                                        <p className="text-gray-700 text-sm">
                                            {item.content}
                                        </p>
                                    </div>
                                </div>
                            </div>


                        </div>
                    ))}


                </div>


            </div>
        </>
    )
}


export default ExpandableAccordion