30 lines
838 B
React
30 lines
838 B
React
|
|
import { useState } from 'react'
|
||
|
|
|
||
|
|
export function CollapsibleSection({
|
||
|
|
title,
|
||
|
|
summary,
|
||
|
|
defaultOpen = false,
|
||
|
|
children,
|
||
|
|
className = '',
|
||
|
|
}) {
|
||
|
|
const [open, setOpen] = useState(defaultOpen)
|
||
|
|
|
||
|
|
return (
|
||
|
|
<section className={`collapsible-section card ${className}`.trim()}>
|
||
|
|
<button
|
||
|
|
type="button"
|
||
|
|
className="collapsible-section-trigger"
|
||
|
|
onClick={() => setOpen((v) => !v)}
|
||
|
|
aria-expanded={open}
|
||
|
|
>
|
||
|
|
<span className="collapsible-section-title">{title}</span>
|
||
|
|
{summary && <span className="collapsible-section-summary muted">{summary}</span>}
|
||
|
|
<span className="collapsible-section-chevron" aria-hidden="true">
|
||
|
|
{open ? '▾' : '▸'}
|
||
|
|
</span>
|
||
|
|
</button>
|
||
|
|
{open && <div className="collapsible-section-body">{children}</div>}
|
||
|
|
</section>
|
||
|
|
)
|
||
|
|
}
|