Skip to content

Instantly share code, notes, and snippets.

@yungwarlock
Created December 19, 2024 08:51
Show Gist options
  • Save yungwarlock/2d83d3611e0c09ca49d451913ca142b0 to your computer and use it in GitHub Desktop.
Save yungwarlock/2d83d3611e0c09ca49d451913ca142b0 to your computer and use it in GitHub Desktop.
Accordion
import React, { useState } from "react";
interface AccordionItemProps {
title: string;
isOpen: boolean;
onClick: () => void;
content: React.ReactNode;
}
const AccordionItem = ({ title, content, isOpen, onClick }: AccordionItemProps): JSX.Element => (
<div className="border-b border-gray-200">
<button
onClick={onClick}
className="w-full p-6 text-left bg-transparent text-black"
>
<div className="flex text-2xl font-main">
<span className="w-8">{isOpen ? "-" : "+"}</span>
<span>{title}</span>
</div>
</button>
<div className={`overflow-hidden transition-all duration-500 ease-in-out ${isOpen ? "max-h-screen" : "max-h-0"}`}>
<div className="p-4 bg-white font-main">
{content}
</div>
</div>
</div>
);
interface AccordionProps {
data: {
title: string;
content: React.ReactNode;
}[];
className?: string;
}
const Accordion = ({ data = [], className }: AccordionProps): JSX.Element => {
const [openIndices, setOpenIndices] = useState<number[]>([]);
const toggleAccordion = (index: number) => {
if (openIndices.includes(index)) {
setOpenIndices(openIndices.filter((i) => i !== index));
} else {
setOpenIndices([...openIndices, index]);
}
};
return (
<div className={`w-full ${className || ""}`}>
{data.map((item, index) => (
<AccordionItem
key={index}
title={item.title}
content={item.content}
isOpen={openIndices.includes(index)}
onClick={() => toggleAccordion(index)}
/>
))}
</div>
);
};
export default Accordion;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment