Accordion
The following accordion component is used for showing hidden information based on the collapse and expand. You can use it as a single component and style it extensively by yourself if you desire. It takes in an array of elements items
with title
and content
. An example of usage is:
Install the following libraries. Assuming you have Tailwind CSS installed
npm install framer-motion
// App.jsximport React from 'react';import Accordion from './components/accordion';
const App = () => { const accordionItems = [ { title: 'Section 1', content: 'Content for section 1 goes here.' }, { title: 'Section 2', content: 'Content for section 2 goes here.' }, { title: 'Section 3', content: 'Content for section 3 goes here.' }, ];
return ( <div className="flex justify-center items-center h-screen"> <Accordion items={accordionItems} titleClass="text-lg font-semibold hover:bg-gray-300" contentClass="text-gray-700" className="max-w-md w-48 bg-white border border-gray-300 shadow-lg" /> </div> );};export default App;
// Accordion.jsximport React, { useState } from 'react';import { motion, AnimatePresence } from 'framer-motion';
const AccordionItem = ({ title, content, isOpen, onToggle, titleClass, contentClass }) => ( <div className="border-b"> <button className={`flex justify-between w-full p-4 text-left focus:outline-none ${titleClass} ${isOpen ? 'bg-gray-200' : 'bg-white'}`} onClick={onToggle} > <span>{title}</span> <span>{isOpen ? '-' : '+'}</span> </button> <AnimatePresence> {isOpen && ( <motion.div initial={{ opacity: 0, height: 0 }} animate={{ opacity: 1, height: 'auto' }} exit={{ opacity: 0, height: 0 }} transition={{ duration: 0.3, ease: [0.4, 0, 0.6, 1] }} style={{ overflow: 'hidden' }} className={`bg-gray-100 ${contentClass}`} > <div className="p-4">{content}</div> </motion.div> )} </AnimatePresence> </div>);
const Accordion = ({ items, titleClass, contentClass, className }) => { const [openIndex, setOpenIndex] = useState(null);
const handleToggle = (index) => { setOpenIndex(openIndex === index ? null : index); };
return ( <div className={`rounded-lg shadow-md ${className}`}> {items.map((item, index) => ( <AccordionItem key={index} title={item.title} content={item.content} isOpen={openIndex === index} onToggle={() => handleToggle(index)} titleClass={titleClass} contentClass={contentClass} /> ))} </div> );};
export default Accordion;