67 lines
1.8 KiB
TypeScript
67 lines
1.8 KiB
TypeScript
"use client"
|
|
|
|
import { useRef } from "react"
|
|
|
|
import { ChevronDownIcon } from "@/components/Icons"
|
|
import { getIconByIconName } from "@/components/Icons/get-icon-by-icon-name"
|
|
|
|
import { accordionItemVariants } from "./variants"
|
|
|
|
import styles from "./accordionItem.module.css"
|
|
|
|
import type { AccordionItemProps } from "./accordionItem"
|
|
|
|
export default function AccordionItem({
|
|
children,
|
|
icon,
|
|
title,
|
|
theme,
|
|
variant,
|
|
className,
|
|
}: AccordionItemProps) {
|
|
const contentRef = useRef<HTMLDivElement>(null)
|
|
const detailsRef = useRef<HTMLDetailsElement>(null)
|
|
|
|
const IconComp = getIconByIconName(icon)
|
|
|
|
function toggleAccordion() {
|
|
const details = detailsRef.current
|
|
const content = contentRef.current
|
|
if (details && content) {
|
|
if (details.open) {
|
|
content.style.maxHeight = `${content.scrollHeight}px`
|
|
content.addEventListener(
|
|
"transitionend",
|
|
() => {
|
|
// Remove maxHeight after transition to allow content to transition multiple times
|
|
content.style.maxHeight = "none"
|
|
},
|
|
{ once: true }
|
|
)
|
|
} else {
|
|
content.style.maxHeight = "0"
|
|
}
|
|
}
|
|
}
|
|
|
|
return (
|
|
<li className={accordionItemVariants({ className, variant, theme })}>
|
|
<details ref={detailsRef} onToggle={toggleAccordion}>
|
|
<summary className={styles.summary}>
|
|
{IconComp && <IconComp className={styles.icon} color="burgundy" />}
|
|
<span className={styles.title}>{title}</span>
|
|
<ChevronDownIcon
|
|
className={styles.chevron}
|
|
color="burgundy"
|
|
width={20}
|
|
height={20}
|
|
/>
|
|
</summary>
|
|
<div ref={contentRef} className={styles.content}>
|
|
{children}
|
|
</div>
|
|
</details>
|
|
</li>
|
|
)
|
|
}
|