import { JSXElement, createMemo, createSignal, onCleanup } from 'solid-js'; type SSExpandableProps = { title: JSXElement; class?: string; children?: JSXElement; style?: string; initiallyExpanded?: boolean; }; const TRANSITION_MS = 200; function SSExpandable(props: SSExpandableProps) { const [height, setHeight] = createSignal(props.initiallyExpanded ? 'auto' : 0); const isExpanded = createMemo(() => height() !== 0); let contentRef: HTMLDivElement | undefined; let timeoutId: number | undefined; const toggle = () => { if (timeoutId) clearTimeout(timeoutId); const targetHeight = contentRef?.scrollHeight ?? 0; if (isExpanded()) { setHeight(targetHeight); timeoutId = window.setTimeout(() => setHeight(0), 1); return; } setHeight(targetHeight); timeoutId = window.setTimeout(() => setHeight('auto'), TRANSITION_MS); }; onCleanup(() => { if (timeoutId) clearTimeout(timeoutId); }); return (
{ if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); toggle(); } }} > {props.title}
(contentRef = el)} class="ss_expandable__content" style={{ height: (typeof height() === 'number' ? `${height()}px` : height()) as any, 'transition-duration': `${TRANSITION_MS}ms`, }} >
{props.children}
); } export { SSExpandable };