UNPKG

@shopify/polaris

Version:

Shopify’s product component library

71 lines (62 loc) 2.38 kB
import { objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js'; import React$1, { useState, useRef, useCallback, useEffect } from 'react'; import { classNames } from '../../utilities/css.js'; import styles from './Collapsible.scss.js'; function Collapsible({ id, expandOnPrint, open, transition, children }) { const [height, setHeight] = useState(0); const [isOpen, setIsOpen] = useState(open); const [animationState, setAnimationState] = useState('idle'); const collapisbleContainer = useRef(null); const isFullyOpen = animationState === 'idle' && open && isOpen; const isFullyClosed = animationState === 'idle' && !open && !isOpen; const content = expandOnPrint || !isFullyClosed ? children : null; const wrapperClassName = classNames(styles.Collapsible, isFullyClosed && styles.isFullyClosed, expandOnPrint && styles.expandOnPrint); const collapsibleStyles = _objectSpread2(_objectSpread2({}, transition && { transitionDuration: `${transition.duration}`, transitionTimingFunction: `${transition.timingFunction}` }), { maxHeight: isFullyOpen ? 'none' : `${height}px`, overflow: isFullyOpen ? 'visible' : 'hidden' }); const handleCompleteAnimation = useCallback(() => { setAnimationState('idle'); setIsOpen(open); }, [open]); useEffect(() => { if (open !== isOpen) { setAnimationState('measuring'); } }, [open, isOpen]); useEffect(() => { if (!open || !collapisbleContainer.current) return; // If collapsible defaults to open, set an initial height setHeight(collapisbleContainer.current.scrollHeight); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { if (!collapisbleContainer.current) return; switch (animationState) { case 'idle': break; case 'measuring': setHeight(collapisbleContainer.current.scrollHeight); setAnimationState('animating'); break; case 'animating': setHeight(open ? collapisbleContainer.current.scrollHeight : 0); } }, [animationState, open, isOpen]); return /*#__PURE__*/React$1.createElement("div", { id: id, style: collapsibleStyles, ref: collapisbleContainer, className: wrapperClassName, onTransitionEnd: handleCompleteAnimation, "aria-expanded": open }, content); } export { Collapsible };