Accordion Soft
It is a refined, minimal UI component built for Next.js and Framer Motion. It prioritizes "Organic Interactions" by using a spring-based physics engine for the expansion and rotation effects. The layout is optimized for readability, utilizing stone-toned color palettes and generous padding to maintain a premium, architectural feel.
Live Preview
Focusing on the skeletal strength of the web through clean, semantic markup.
Dependencies
npm install
framer-motionlucide-reactCode
"use client";
import { useState } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { ChevronDown } from "lucide-react";
const data = [
{
title: "Architectural Integrity",
content:
"Focusing on the skeletal strength of the web through clean, semantic markup.",
},
{
title: "Organic Interactions",
content:
"Moving away from rigid transitions toward fluid, physics-based motion.",
},
];
export default function SoftAccordion({ items = data }: any) {
const [expanded, setExpanded] = useState<number | null>(0);
return (
<div className="max-w-md mx-auto w-lg space-y-2">
{items.map((item: any, i: number) => (
<div key={i} className="overflow-hidden border-b border-stone-200">
<button
onClick={() => setExpanded(expanded === i ? null : i)}
className="flex w-full items-center justify-between py-6 text-left"
>
<span className="text-lg font-medium text-stone-800">
{item.title}
</span>
<motion.div
animate={{ rotate: expanded === i ? 180 : 0 }}
transition={{ type: "spring", stiffness: 300, damping: 20 }}
>
<ChevronDown className="w-5 h-5 text-stone-500" />
</motion.div>
</button>
<AnimatePresence initial={false}>
{expanded === i && (
<motion.div
initial={{ height: 0, opacity: 0 }}
animate={{ height: "auto", opacity: 1 }}
exit={{ height: 0, opacity: 0 }}
transition={{ duration: 0.3, ease: [0.04, 0.62, 0.23, 0.98] }}
>
<div className="pb-6 text-stone-600 leading-relaxed">
{item.content}
</div>
</motion.div>
)}
</AnimatePresence>
</div>
))}
</div>
);
}
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| items | AccordionItem[] | data | An array of objects representing each accordion row, including the header title and body content. |