51 lines
1.5 KiB
TypeScript
51 lines
1.5 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import { faqs } from "../content";
|
|
|
|
/**
|
|
* Accessible accordion built on native <button>. Uses aria-expanded +
|
|
* aria-controls; panels are real content (always in DOM for SEO/AEO),
|
|
* height-animated via grid-template-rows. One open at a time.
|
|
*/
|
|
export default function Faq() {
|
|
const [open, setOpen] = useState<number | null>(0);
|
|
|
|
return (
|
|
<div className="faq">
|
|
{faqs.map((f, i) => {
|
|
const isOpen = open === i;
|
|
return (
|
|
<div className="faq__item" key={i}>
|
|
<h3 className="faq__h">
|
|
<button
|
|
className="faq__btn"
|
|
aria-expanded={isOpen}
|
|
aria-controls={`faq-panel-${i}`}
|
|
id={`faq-btn-${i}`}
|
|
onClick={() => setOpen(isOpen ? null : i)}
|
|
>
|
|
<span className="faq__num">Q{i + 1}</span>
|
|
<span className="faq__q">{f.q}</span>
|
|
<span className="faq__sign" aria-hidden="true" data-open={isOpen}>
|
|
<i /><i />
|
|
</span>
|
|
</button>
|
|
</h3>
|
|
<div
|
|
id={`faq-panel-${i}`}
|
|
role="region"
|
|
aria-labelledby={`faq-btn-${i}`}
|
|
className="faq__panel"
|
|
data-open={isOpen}
|
|
>
|
|
<div className="faq__panel-inner">
|
|
<p>{f.a}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
);
|
|
}
|