'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var React = require('react');
var css = require('../../utilities/css.js');
var Collapsible$1 = require('./Collapsible.scss.js');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var React__default = /*#__PURE__*/_interopDefaultLegacy(React);

function Collapsible({
  id,
  expandOnPrint,
  open,
  transition = true,
  preventMeasuringOnChildrenUpdate: _preventMeasuringOnChildrenUpdate,
  children,
  onAnimationEnd
}) {
  const [height, setHeight] = React.useState(0);
  const [isOpen, setIsOpen] = React.useState(open);
  const [animationState, setAnimationState] = React.useState('idle');
  const collapsibleContainer = React.useRef(null);
  const isFullyOpen = animationState === 'idle' && open && isOpen;
  const isFullyClosed = animationState === 'idle' && !open && !isOpen;
  const content = expandOnPrint || !isFullyClosed ? children : null;
  const wrapperClassName = css.classNames(Collapsible$1["default"].Collapsible, isFullyClosed && Collapsible$1["default"].isFullyClosed, expandOnPrint && Collapsible$1["default"].expandOnPrint);
  const transitionDisabled = isTransitionDisabled(transition);
  const transitionStyles = typeof transition === 'object' && {
    transitionDuration: transition.duration,
    transitionTimingFunction: transition.timingFunction
  };
  const collapsibleStyles = { ...transitionStyles,
    ...{
      maxHeight: isFullyOpen ? 'none' : `${height}px`,
      overflow: isFullyOpen ? 'visible' : 'hidden'
    }
  };
  const handleCompleteAnimation = React.useCallback(({
    target
  }) => {
    if (target === collapsibleContainer.current) {
      setAnimationState('idle');
      setIsOpen(open);
      onAnimationEnd && onAnimationEnd();
    }
  }, [onAnimationEnd, open]);
  const startAnimation = React.useCallback(() => {
    if (transitionDisabled) {
      setIsOpen(open);
      setAnimationState('idle');

      if (open && collapsibleContainer.current) {
        setHeight(collapsibleContainer.current.scrollHeight);
      } else {
        setHeight(0);
      }
    } else {
      setAnimationState('measuring');
    }
  }, [open, transitionDisabled]);
  React.useEffect(() => {
    if (open !== isOpen) {
      startAnimation();
    } // startAnimation should only be fired if the open state changes.
    // eslint-disable-next-line react-hooks/exhaustive-deps

  }, [open, isOpen]);
  React.useEffect(() => {
    if (!open || !collapsibleContainer.current) return; // If collapsible defaults to open, set an initial height

    setHeight(collapsibleContainer.current.scrollHeight); // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);
  React.useEffect(() => {
    if (!collapsibleContainer.current) return;

    switch (animationState) {
      case 'idle':
        break;

      case 'measuring':
        setHeight(collapsibleContainer.current.scrollHeight);
        setAnimationState('animating');
        break;

      case 'animating':
        setHeight(open ? collapsibleContainer.current.scrollHeight : 0);
    }
  }, [animationState, open, isOpen]);
  return /*#__PURE__*/React__default["default"].createElement("div", {
    id: id,
    style: collapsibleStyles,
    ref: collapsibleContainer,
    className: wrapperClassName,
    onTransitionEnd: handleCompleteAnimation,
    "aria-hidden": !open
  }, content);
}
const zeroDurationRegex = /^0(ms|s)$/;

function isTransitionDisabled(transitionProp) {
  if (typeof transitionProp === 'boolean') {
    return !transitionProp;
  }

  const {
    duration
  } = transitionProp;

  if (duration && zeroDurationRegex.test(duration.trim())) {
    return true;
  }

  return false;
}

exports.Collapsible = Collapsible;
