Skip to content

Commit 7f1d13b

Browse files
committed
added minimal accordion
1 parent dd1daa7 commit 7f1d13b

File tree

3 files changed

+136
-0
lines changed

3 files changed

+136
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export const metadata = {
2+
title: 'Accordion',
3+
description: 'A minimal accordion component for your next project.',
4+
}
5+
6+
# Footer
7+
8+
<ComponentPreview path="components/accordion/MinimalAccordion" usingFramer />

src/components/Navigation.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,10 @@ export const navigation: Array<NavGroup> = [
235235
{
236236
title: 'Components',
237237
links: [
238+
{
239+
title: 'Accordion',
240+
href: '/blocks/accordion',
241+
},
238242
{
239243
title: 'Button',
240244
href: '/components/button',
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import React, { useState } from 'react'
2+
import { motion, Variants } from 'framer-motion'
3+
import { ChevronDown } from 'lucide-react'
4+
5+
interface AccordionItemProps {
6+
title: string
7+
content: string
8+
isExpanded: boolean
9+
onToggle: () => void
10+
backgroundColor: string
11+
}
12+
13+
interface AccordionProps {
14+
items: Array<{
15+
title: string
16+
content: string
17+
backgroundColor: string
18+
}>
19+
}
20+
21+
const AccordionItem: React.FC<AccordionItemProps> = ({
22+
title,
23+
content,
24+
isExpanded,
25+
onToggle,
26+
backgroundColor,
27+
}) => {
28+
const cardVariants: Variants = {
29+
collapsed: { height: '60px', backgroundColor: '#fafafa' },
30+
expanded: { height: 'auto', backgroundColor },
31+
}
32+
33+
const contentVariants: Variants = {
34+
collapsed: { opacity: 0, y: -20 },
35+
expanded: { opacity: 1, y: 0, transition: { delay: 0.1 } },
36+
}
37+
38+
const chevronVariants: Variants = {
39+
collapsed: { rotate: 0 },
40+
expanded: { rotate: 180 },
41+
}
42+
43+
return (
44+
<motion.div
45+
className="w-90 my-4 h-full cursor-pointer select-none overflow-hidden rounded-lg border"
46+
variants={cardVariants}
47+
initial="collapsed"
48+
animate={isExpanded ? 'expanded' : 'collapsed'}
49+
onClick={onToggle}
50+
>
51+
<div className="flex items-center justify-between p-4 text-gray-900">
52+
<h2 className="m-0 text-sm font-semibold ">{title}</h2>
53+
<motion.div variants={chevronVariants}>
54+
<ChevronDown size={18} />
55+
</motion.div>
56+
</div>
57+
<motion.div
58+
className="text-md select-none px-4 py-4"
59+
variants={contentVariants}
60+
initial="collapsed"
61+
animate={isExpanded ? 'expanded' : 'collapsed'}
62+
>
63+
<p className="m-0 text-sm text-gray-600">{content}</p>
64+
</motion.div>
65+
</motion.div>
66+
)
67+
}
68+
69+
const Accordion: React.FC<AccordionProps> = ({ items }) => {
70+
const [expandedIndex, setExpandedIndex] = useState<number | null>(null)
71+
72+
const handleToggle = (index: number) => {
73+
setExpandedIndex(expandedIndex === index ? null : index)
74+
}
75+
76+
return (
77+
<div className="space-y-4">
78+
{items.map((item, index) => (
79+
<AccordionItem
80+
key={index}
81+
title={item.title}
82+
content={item.content}
83+
backgroundColor={item.backgroundColor}
84+
isExpanded={expandedIndex === index}
85+
onToggle={() => handleToggle(index)}
86+
/>
87+
))}
88+
</div>
89+
)
90+
}
91+
92+
// Sample accordion items with custom background colors
93+
const accordionItems = [
94+
{
95+
title: 'Explore Knowledge',
96+
content:
97+
'Discover new worlds of information with our interactive learning platform.',
98+
backgroundColor: '#e6f7ff',
99+
},
100+
{
101+
title: 'Innovative Learning',
102+
content:
103+
'Experience cutting-edge educational techniques that adapt to your unique learning style.',
104+
backgroundColor: '#f6ffed',
105+
},
106+
{
107+
title: 'Global Community',
108+
content:
109+
'Connect with learners worldwide and share insights in our vibrant, diverse community.',
110+
backgroundColor: '#fff7e6',
111+
},
112+
{
113+
title: 'Personalized Growth',
114+
content:
115+
'Track your progress and receive tailored recommendations to accelerate your learning journey.',
116+
backgroundColor: '#fff1f0',
117+
},
118+
]
119+
120+
const AccordionExample: React.FC = () => {
121+
return <Accordion items={accordionItems} />
122+
}
123+
124+
export default AccordionExample

0 commit comments

Comments
 (0)