import React, { FC, useEffect, useRef, useState } from 'react' export declare interface CollapseProps extends React.HTMLProps { isOpen: boolean } export const Collapse: FC = ({ isOpen, className, style, ...props }) => { const [height, setHeight] = useState(isOpen ? 'auto' : '0') const [overflow, setOverflow] = useState( isOpen ? 'visible' : 'hidden' ) const [visibility, setVisibility] = useState( isOpen ? 'visible' : 'hidden' ) const content = useRef(null) useEffect(() => { if (content.current) { if (isOpen && height !== 'auto') { setHeight(`${content.current?.scrollHeight}px`) setVisibility('visible') } else if (!isOpen && height !== '0') { setHeight(`${content.current?.scrollHeight}px`) window.requestAnimationFrame(() => setTimeout(() => { setHeight('0') setOverflow('hidden') }) ) } } }, [isOpen, height]) const onTransitionEnd = (e: React.TransitionEvent) => { if (e.target === content.current && e.propertyName === 'height') { if (!isOpen) { setVisibility('hidden') } } } const styles: React.CSSProperties = { ...style, willChange: 'height', height, overflow, visibility: visibility === 'hidden' ? 'hidden' : 'visible', } return (
) }