import { CSSProperties, ReactNode, useEffect, useId, useRef, useState, } from 'react' import classNames from 'classnames' import { Transition } from '../transition/Transition' // import { Transition } from 'react-transition-group' import { reflow, animate, AnimateStop } from '../../utils' import { useCallbackState, useEvent, useSelectorId } from '../../use' import { getBoundingClientRect } from '../../utils/dom' import { CommonComponentProps } from '../../utils/types' import './Collapse.scss' interface TransitionHookWrap { (): void } const CLS_SHOW = 's-show' const CLS_COLLAPSING = 's-collapsing' export interface CollapseProps extends CommonComponentProps { className?: string style?: CSSProperties children?: ReactNode visible?: boolean duration?: number onEnter?: () => void onEntering?: () => void onEntered?: () => void onExit?: () => void onExiting?: () => void onExited?: () => void } export function Collapse(props: CollapseProps) { const { className, style, children, visible = false, duration = 300, onEnter, onEntering, onEntered, onExit, onExiting, onExited, ...restProps } = props const id = useSelectorId() const [classList, setClassList] = useCallbackState([]) const [height, setHeight] = useCallbackState('') const handleEnter = useEvent(() => { setClassList([CLS_SHOW], () => { getBoundingClientRect('#' + id, (rect) => { setClassList([CLS_SHOW, CLS_COLLAPSING]) setHeight(0, () => { setTimeout(() => { setHeight(rect.height) }, 10) }) }) }) onEnter?.() }) const handleEntering = useEvent(() => { onEntering?.() }) const handleEntered = useEvent(() => { setClassList([CLS_SHOW]) setHeight('') onEntered?.() }) const handleExit = useEvent(() => { setClassList([CLS_SHOW, CLS_COLLAPSING]) getBoundingClientRect('#' + id, (rect) => { setHeight(rect.height, () => { setTimeout(() => { setHeight(0) }, 10) }) }) onExit?.() }) const handleExiting = useEvent(() => { onExiting?.() }) const handleExited = useEvent(() => { setHeight('') setClassList([]) onExited?.() }) const collapseClass = classNames('s-collapse', classList, className) const collapseStyle = { height, transitionDuration: duration + 'ms', ...style, } return (
{children}
) } export default Collapse