Create Custom React Accordion
Md Forhad Sarkar
Frontend Developer | JavaScript | ReactJS | NextJs l TailwindCSS
This React component, Accordian, is an advanced version of an accordion UI element with added features like single and multiple item selection modes. It allows the user to toggle between these modes using a switch. Let’s break down the code to understand how it works.
Overview
Code Breakdown
"use client";
import React, { useState } from "react";
import data from "./data";
Explanation:
Component State
const [selected, setSelected] = useState(null);
const [isOn, setIsOn] = useState(false);
const [multiple, setMultiple] = useState([]);
Explanation:
Single Selection Handling
const handleSingleSelection = (getCurrentId) => {
setSelected(getCurrentId === selected ? null : getCurrentId);
};
Explanation:
Multiple Selection Handling
const toggleSwitch = (getCurrentId) => {
let copyMultile = [...multiple];
const findIndexOfCurrentId = copyMultile.indexOf(getCurrentId);
if (findIndexOfCurrentId === -1) copyMultile.push(getCurrentId);
else copyMultile.splice(findIndexOfCurrentId, 1);
setMultiple(copyMultile);
};
Explanation:
领英推荐
Rendering the UI
return (
<div className="flex flex-col justify-center w-full p-4">
<h3 className="font-bold text-lg">Accordion</h3>
<div className="flex justify-between items-center">
Enable multiselections
<button
className={`flex items-center cursor-pointer w-20 h-10 rounded-full p-1 ${
isOn ? "bg-green-500" : "bg-gray-300"
}`}
onClick={() => setIsOn(!isOn)}
>
<div
className={`flex justify-center items-center bg-white w-8 h-8 rounded-full shadow-md transform transition-transform ${
isOn ? "translate-x-10" : "translate-x-0"
}`}
>
<span className="text-sm font-semibold">{isOn ? "ON" : "OFF"}</span>
</div>
</button>
</div>
<div className="pt-4">
{data && data.length > 0 ? (
data.map((dataItem) => (
<div key={dataItem.id} className="w-full">
<div
onClick={
isOn
? () => toggleSwitch(dataItem.id)
: () => handleSingleSelection(dataItem.id)
}
className="flex justify-between gap-4 bg-slate-400 p-4 cursor-pointer border-b-2"
>
<h3>{dataItem.question}</h3>
{isOn ? (
multiple.indexOf(dataItem.id) !== -1 ? (
<span>-</span>
) : (
<span>+</span>
)
) : selected === dataItem.id ? (
<span>-</span>
) : (
<span>+</span>
)}
</div>
{isOn
? multiple.indexOf(dataItem.id) !== -1 && (
<div className=" p-4 bg-orange-100">{dataItem.answer}</div>
)
: selected === dataItem.id && (
<div className=" p-4 bg-orange-100">{dataItem.answer}</div>
)}
</div>
))
) : (
<div> No Data Found!</div>
)}
</div>
</div>
);
Explanation:
Wrapper div:
Title and Toggle Switch:
Rendering Accordion Items:
Summary
Single vs Multiple Selection:
State Management:
Responsive UI:
The component is styled using utility classes (likely from Tailwind CSS), ensuring it is responsive and visually appealing.
This component provides a flexible and interactive way to present content that can be expanded and collapsed, with the added functionality of switching between single and multiple selection modes.