import React, { forwardRef, HTMLAttributes, useRef, useState } from 'react' import PropTypes from 'prop-types' import classNames from 'classnames' import { CSSTransition } from 'react-transition-group' import { useForkedRef } from '../../hooks' export interface CCollapseProps extends HTMLAttributes { /** * A string of all className you want applied to the base component. */ className?: string /** * Set horizontal collapsing to transition the width instead of height. */ horizontal?: boolean /** * Callback fired when the component requests to be hidden. */ onHide?: () => void /** * Callback fired when the component requests to be shown. */ onShow?: () => void /** * Toggle the visibility of component. */ visible?: boolean } export const CCollapse = forwardRef( ({ children, className, horizontal, onHide, onShow, visible, ...rest }, ref) => { const collapseRef = useRef(null) const forkedRef = useForkedRef(ref, collapseRef) const [height, setHeight] = useState() const [width, setWidth] = useState() const onEntering = () => { onShow && onShow() if (horizontal) { collapseRef.current && setWidth(collapseRef.current.scrollWidth) return } collapseRef.current && setHeight(collapseRef.current.scrollHeight) } const onEntered = () => { if (horizontal) { setWidth(0) return } setHeight(0) } const onExit = () => { if (horizontal) { collapseRef.current && setWidth(collapseRef.current.scrollWidth) return } collapseRef.current && setHeight(collapseRef.current.scrollHeight) } const onExiting = () => { onHide && onHide() if (horizontal) { setWidth(0) return } setHeight(0) } const onExited = () => { if (horizontal) { setWidth(0) return } setHeight(0) } return ( {(state) => { const currentHeight = height === 0 ? null : { height } const currentWidth = width === 0 ? null : { width } return (
{children}
) }}
) } ) CCollapse.propTypes = { children: PropTypes.node, className: PropTypes.string, horizontal: PropTypes.bool, onHide: PropTypes.func, onShow: PropTypes.func, visible: PropTypes.bool, } CCollapse.displayName = 'CCollapse'