68 lines
2.2 KiB
TypeScript
68 lines
2.2 KiB
TypeScript
"use client";
|
|
|
|
import React, { useState } from 'react';
|
|
|
|
interface FAQItem {
|
|
question: string;
|
|
answer: string;
|
|
}
|
|
|
|
interface FAQAccordionProps {
|
|
items: FAQItem[];
|
|
}
|
|
|
|
export const FAQAccordion: React.FC<FAQAccordionProps> = ({ items }) => {
|
|
const [openIndex, setOpenIndex] = useState<number | null>(0);
|
|
|
|
return (
|
|
<div className="space-y-4 max-w-3xl mx-auto">
|
|
{items.map((item, index) => (
|
|
<div
|
|
key={index}
|
|
className={`
|
|
border rounded-xl overflow-hidden transition-all duration-300
|
|
${openIndex === index
|
|
? 'border-zsl-primary/50 bg-zsl-card/50'
|
|
: 'border-zsl-primary/10 bg-zsl-card/30 hover:border-zsl-primary/30'
|
|
}
|
|
`}
|
|
>
|
|
{/* Question */}
|
|
<button
|
|
onClick={() => setOpenIndex(openIndex === index ? null : index)}
|
|
className="w-full px-6 py-5 flex items-center justify-between text-left"
|
|
>
|
|
<span className="font-medium text-white pr-4">{item.question}</span>
|
|
<div className={`
|
|
w-8 h-8 rounded-full border border-zsl-primary/30 flex items-center justify-center
|
|
transition-all duration-300 shrink-0
|
|
${openIndex === index ? 'bg-zsl-primary rotate-180' : ''}
|
|
`}>
|
|
<svg
|
|
className={`w-4 h-4 transition-colors duration-300 ${openIndex === index ? 'text-zsl-bg' : 'text-zsl-primary'}`}
|
|
fill="none"
|
|
stroke="currentColor"
|
|
viewBox="0 0 24 24"
|
|
>
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
|
|
</svg>
|
|
</div>
|
|
</button>
|
|
|
|
{/* Answer */}
|
|
<div className={`
|
|
grid transition-all duration-300 ease-in-out
|
|
${openIndex === index ? 'grid-rows-[1fr]' : 'grid-rows-[0fr]'}
|
|
`}>
|
|
<div className="overflow-hidden">
|
|
<div className="px-6 pb-5 text-zsl-muted leading-relaxed border-t border-zsl-primary/10 pt-4">
|
|
{item.answer}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
);
|
|
};
|