52 lines
1.4 KiB
TypeScript
52 lines
1.4 KiB
TypeScript
"use client";
|
|
|
|
import * as React from "react";
|
|
import { ChevronDown } from "lucide-react";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
interface AccordionItemProps {
|
|
title: string;
|
|
children: React.ReactNode;
|
|
defaultOpen?: boolean;
|
|
}
|
|
|
|
export function AccordionItem({
|
|
title,
|
|
children,
|
|
defaultOpen = false,
|
|
}: AccordionItemProps) {
|
|
const [isOpen, setIsOpen] = React.useState(defaultOpen);
|
|
const contentRef = React.useRef<HTMLDivElement>(null);
|
|
|
|
return (
|
|
<div className="border-b border-brown-light/30">
|
|
<button
|
|
className="flex w-full items-center justify-between py-5 text-left font-bold text-cream transition-colors hover:text-neon cursor-pointer"
|
|
onClick={() => setIsOpen(!isOpen)}
|
|
aria-expanded={isOpen}
|
|
>
|
|
{title}
|
|
<ChevronDown
|
|
className={cn(
|
|
"h-5 w-5 shrink-0 text-neon transition-transform duration-300",
|
|
isOpen && "rotate-180"
|
|
)}
|
|
/>
|
|
</button>
|
|
<div
|
|
ref={contentRef}
|
|
className="overflow-hidden transition-all duration-300"
|
|
style={{
|
|
maxHeight: isOpen
|
|
? contentRef.current?.scrollHeight
|
|
? `${contentRef.current.scrollHeight}px`
|
|
: "500px"
|
|
: "0px",
|
|
}}
|
|
>
|
|
<div className="pb-5 text-cream-dim leading-relaxed">{children}</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|