FaqSection.tsx71 lines · main
1'use client'
2
3import { useState } from 'react'
4import { cn } from 'ui'
5
6import type { GoFaqSection } from '../schemas'
7
8export default function FaqSection({ section }: { section: GoFaqSection }) {
9 const [openIndex, setOpenIndex] = useState<number | null>(null)
10
11 return (
12 <div className="max-w-7xl mx-auto px-8">
13 {(section.title || section.description) && (
14 <div className="mb-12">
15 {section.title && (
16 <h2 className="text-2xl sm:text-3xl font-medium text-foreground">{section.title}</h2>
17 )}
18 {section.description && (
19 <p className="text-foreground-lighter mt-3 text-lg">{section.description}</p>
20 )}
21 </div>
22 )}
23 <div className="border border-muted rounded-xl overflow-hidden divide-y divide-muted">
24 {section.items.map((item, i) => {
25 const isOpen = openIndex === i
26 return (
27 <div key={i}>
28 <button
29 type="button"
30 className="flex w-full items-center justify-between gap-4 p-6 sm:p-8 text-left"
31 onClick={() => setOpenIndex(isOpen ? null : i)}
32 aria-expanded={isOpen}
33 >
34 <span className="text-foreground font-medium text-base">{item.question}</span>
35 <svg
36 xmlns="http://www.w3.org/2000/svg"
37 width="16"
38 height="16"
39 viewBox="0 0 24 24"
40 fill="none"
41 stroke="currentColor"
42 strokeWidth="2"
43 strokeLinecap="round"
44 strokeLinejoin="round"
45 className={cn(
46 'shrink-0 text-foreground-lighter transition-transform duration-200',
47 isOpen && 'rotate-180'
48 )}
49 >
50 <polyline points="6 9 12 15 18 9" />
51 </svg>
52 </button>
53 <div
54 className={cn(
55 'grid transition-all duration-200',
56 isOpen ? 'grid-rows-[1fr]' : 'grid-rows-[0fr]'
57 )}
58 >
59 <div className="overflow-hidden">
60 <p className="px-6 sm:px-8 pb-6 sm:pb-8 text-foreground-lighter text-sm leading-relaxed">
61 {item.answer}
62 </p>
63 </div>
64 </div>
65 </div>
66 )
67 })}
68 </div>
69 </div>
70 )
71}