/** * Copyright (c) TonTech. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * */ import { useRef, useLayoutEffect, useState } from 'react'; import type { FC, ComponentProps } from 'react'; import styles from './collapsible.module.css'; export interface CollapsibleProps extends ComponentProps<'div'> { open: boolean; } export const Collapsible: FC = ({ open, children, ...props }) => { const contentRef = useRef(null); const [height, setHeight] = useState(open ? undefined : 0); useLayoutEffect(() => { const el = contentRef.current; if (!el) return undefined; if (open) { setHeight(el.scrollHeight); const onEnd = () => setHeight(undefined); el.addEventListener('transitionend', onEnd, { once: true }); return () => el.removeEventListener('transitionend', onEnd); } setHeight(el.scrollHeight); const id = requestAnimationFrame(() => { requestAnimationFrame(() => { setHeight(0); }); }); return () => cancelAnimationFrame(id); }, [open]); return (
{children}
); };