๐ŸŽจ

UI Library

A collection of beautiful, reusable React components and CSS snippets built with Tailwind CSS and Framer Motion.

Accordions

Vertically collapsing panels that hide and reveal content.

Basic Accordion

If you're unhappy with your purchase, we'll refund you in full.
Accordion.tsxLanguage: tsx
import { useState } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; export function BasicAccordion() { const [openIndex, setOpenIndex] = useState<number | null>(0); const items = [ { title: "What is your refund policy?", content: "If you're unhappy with your purchase, we'll refund you in full." }, { title: "Do you offer technical support?", content: "Yes, we offer 24/7 technical support for all our premium customers." }, { title: "Can I upgrade my plan later?", content: "Absolutely. You can upgrade or downgrade your plan at any time." }, ]; return ( <div className="w-full max-w-lg mx-auto bg-surface border border-border rounded-2xl overflow-hidden divide-y divide-border"> {items.map((item, index) => { const isOpen = openIndex === index; return ( <div key={index} className="overflow-hidden"> <button onClick={() => setOpenIndex(isOpen ? null : index)} className="w-full flex justify-between items-center p-5 text-left font-medium text-foreground hover:bg-black/5 dark:hover:bg-white/5 transition-colors" > {item.title} <motion.svg animate={{ rotate: isOpen ? 180 : 0 }} transition={{ duration: 0.3, ease: "easeInOut" }} className="w-5 h-5 text-muted shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2} > <path strokeLinecap="round" strokeLinejoin="round" d="M19 9l-7 7-7-7" /> </motion.svg> </button> <AnimatePresence initial={false}> {isOpen && ( <motion.div initial={{ height: 0 }} animate={{ height: "auto" }} exit={{ height: 0 }} transition={{ duration: 0.3, ease: "easeInOut" }} > <div className="p-5 pt-0 text-muted leading-relaxed"> {item.content} </div> </motion.div> )} </AnimatePresence> </div> ); })} </div> ); }