import "core-js/modules/web.dom.iterable";
import "core-js/modules/es6.array.iterator";
import "core-js/modules/es6.object.keys";
import "core-js/modules/es6.object.assign";
import "core-js/modules/es6.string.anchor";
import "core-js/modules/es7.array.includes";
import "core-js/modules/es6.string.includes";
import "core-js/modules/es6.regexp.split";

function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }

function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }

function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }

import React from 'react';
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom';
import { omit } from 'lodash';

var EventOverlay =
/*#__PURE__*/
function (_React$Component) {
  _inheritsLoose(EventOverlay, _React$Component);

  function EventOverlay() {
    var _this;

    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;
    _this.state = {
      visibleDirection: _this.props.direction
    };

    _this.componentDidMount = function () {
      _this.addHandlers();
    };

    _this.componentDidUpdate = function (prevProps) {
      if (_this.props.isOpen && prevProps.isOpen !== _this.props.isOpen || prevProps.direction !== _this.props.direction) {
        _this.addKeyHandlers();

        return _this.forceUpdate(function () {
          return _this.isVisible();
        });
      } else if (!_this.props.isOpen && prevProps.isOpen !== _this.props.isOpen) {
        return _this.removeKeyHandlers();
      }
    };

    _this.componentWillUnmount = function () {
      _this.removeHandlers();
    };

    _this.isVisible = function () {
      var _this$props = _this.props,
          direction = _this$props.direction,
          isOpen = _this$props.isOpen,
          anchorNode = _this$props.anchorNode,
          isDynamic = _this$props.isDynamic;
      if (!isOpen) return;
      if (!isDynamic) return _this.setPlacement();
      var element = ReactDOM.findDOMNode(_this.container);
      var elementAnchor = ReactDOM.findDOMNode(anchorNode);
      var side = direction.split('-')[0];
      var alignment = direction.split('-')[1];
      var anchor = elementAnchor && elementAnchor.getBoundingClientRect();
      var elementBoundingRect = element.getBoundingClientRect();
      var elementParent = element.parentElement;
      ['top', 'bottom'].includes(side) ? _this.setVerticalClass(alignment, anchor, elementBoundingRect, elementParent) : _this.setHorizontalClass(alignment, anchor, elementBoundingRect, elementParent);
    };

    _this.findParents = function (ele, tempParentArr) {
      if (tempParentArr === void 0) {
        tempParentArr = [];
      }

      return !ele.parentElement ? tempParentArr : _this.findParents(ele.parentElement, tempParentArr.concat(ele));
    };

    _this.findOverflow = function (node, searchProps) {
      return searchProps.reduce(function (agg, prop) {
        var overflowElement = window.getComputedStyle(ReactDOM.findDOMNode(node))[prop];
        return !overflowElement || agg.includes(overflowElement) ? agg : agg += overflowElement;
      }, '');
    };

    _this.findScrollParent = function (elementParents, searchProps) {
      var overflowElement = null;
      var idx = 0;

      while (!overflowElement && elementParents[idx]) {
        var currentOverflowElement = _this.findOverflow(elementParents[idx], searchProps);

        if (/(auto|scroll|hidden)/.test(currentOverflowElement)) {
          return overflowElement = elementParents[idx];
        }

        idx++;
      }

      return overflowElement ? overflowElement : window;
    };

    _this.setHorizontalClass = function (alignment, anchor, elementBoundingRect, elementParent) {
      var _this$props2 = _this.props,
          showArrow = _this$props2.showArrow,
          checkOverflow = _this$props2.checkOverflow,
          targetOffset = _this$props2.targetOffset;
      var windowRight = window.pageYOffset + window.innerWidth;
      var elementWidth = elementBoundingRect.width;
      var anchorRight = anchor.right;
      var arrowWidth = showArrow ? ReactDOM.findDOMNode(_this.arrow).getBoundingClientRect().width : 0;
      var offsetWidth = targetOffset.horizontal || 0;
      var totalWidth = anchorRight + elementWidth + arrowWidth + offsetWidth;

      var elementParents = _this.findParents(elementParent);

      var scrollParent = _this.findScrollParent(elementParents, ['overflow', 'overflow-x']);

      var parentRight = checkOverflow && !!scrollParent.getBoundingClientRect && scrollParent.getBoundingClientRect().right || windowRight;
      return totalWidth < parentRight && totalWidth < windowRight ? _this.setState({
        visibleDirection: "right-" + alignment
      }, function () {
        return _this.setPlacement();
      }) : _this.setState({
        visibleDirection: "left-" + alignment
      }, function () {
        return _this.setPlacement();
      });
    };

    _this.setVerticalClass = function (alignment, anchor, elementBoundingRect, elementParent) {
      var _this$props3 = _this.props,
          showArrow = _this$props3.showArrow,
          checkOverflow = _this$props3.checkOverflow,
          targetOffset = _this$props3.targetOffset;
      var windowBottom = window.pageXOffset + window.innerHeight;
      var elementHeight = elementBoundingRect.height;
      var anchorBottom = anchor.bottom;
      var arrowHeight = showArrow ? ReactDOM.findDOMNode(_this.arrow).getBoundingClientRect().height : 0;
      var offsetHeight = targetOffset.vertical || 0;
      var totalHeight = anchorBottom + elementHeight + arrowHeight + offsetHeight;

      var elementParents = _this.findParents(elementParent);

      var scrollParent = _this.findScrollParent(elementParents, ['overflow', 'overflow-y']);

      var parentBottom = checkOverflow && !!scrollParent.getBoundingClientRect && scrollParent.getBoundingClientRect().bottom || windowBottom;
      return totalHeight < parentBottom && totalHeight < windowBottom ? _this.setState({
        visibleDirection: "bottom-" + alignment
      }, function () {
        return _this.setPlacement();
      }) : _this.setState({
        visibleDirection: "top-" + alignment
      }, function () {
        return _this.setPlacement();
      });
    };

    _this.addHandlers = function () {
      var _this$props4 = _this.props,
          allowClickAway = _this$props4.allowClickAway,
          closeOnClick = _this$props4.closeOnClick;
      _this.handleResize = _this.isVisible;
      _this.handleScroll = _this.isVisible;

      if (allowClickAway) {
        document.addEventListener('click', _this.handleAllowClickAway, true);
      }

      closeOnClick && document.addEventListener('click', _this.handleCloseOnClick, false);
      window.addEventListener('resize', _this.handleResize, true);
      document.addEventListener('scroll', _this.handleScroll, false);

      _this.isVisible();
    };

    _this.addKeyHandlers = function () {
      var _this$props5 = _this.props,
          allowClickAway = _this$props5.allowClickAway,
          checkOverflow = _this$props5.checkOverflow;

      if (allowClickAway) {
        document.addEventListener('keydown', _this.handleKeyDown, false);
      }

      if (checkOverflow) {
        var element = ReactDOM.findDOMNode(_this.container);
        var elementParent = element.parentElement;

        var elementParents = _this.findParents(elementParent);

        var scrollParent = _this.findScrollParent(elementParents, ['overflow', 'overflow-y', 'overflow-x']);

        scrollParent && scrollParent.addEventListener('scroll', _this.handleScroll, false);
      }
    };

    _this.removeKeyHandlers = function () {
      document.removeEventListener('keydown', _this.handleKeyDown, false);
    };

    _this.removeHandlers = function () {
      document.removeEventListener('click', _this.handleAllowClickAway, true);
      document.removeEventListener('click', _this.handleCloseOnClick, false);
      window.removeEventListener('resize', _this.handleResize, true);
      document.removeEventListener('scroll', _this.handleScroll, false);
    };

    _this.handleCloseOnClick = function (e) {
      if (!_this.props.isOpen) return;
      var closeOnClick = _this.props.closeOnClick;
      return closeOnClick && _this.container && ReactDOM.findDOMNode(_this.container).contains(e.target) && _this.handleClickAway(e);
    };

    _this.handleKeyDown = function (e) {
      if (!_this.props.isOpen) return;
      if (e.keyCode === 27) return _this.handleClickAway(e);
      var anchorNode = ReactDOM.findDOMNode(_this.props.anchorNode);
      return _this.container && !anchorNode.contains(document.activeElement) && !ReactDOM.findDOMNode(_this.container).contains(document.activeElement) && _this.handleClickAway(e);
    };

    _this.handleAllowClickAway = function (e) {
      if (!_this.props.isOpen) return;
      var anchorNode = ReactDOM.findDOMNode(_this.props.anchorNode);
      return _this.container && !ReactDOM.findDOMNode(anchorNode).contains(e.target) && !ReactDOM.findDOMNode(_this.container).contains(e.target) && _this.handleClickAway(e);
    };

    _this.getAnchorPosition = function (node) {
      var rect = node.getBoundingClientRect();
      var anchorPosition = {
        top: rect.top,
        left: rect.left,
        width: node.offsetWidth,
        height: node.offsetHeight
      };
      anchorPosition.right = rect.right || anchorPosition.left + anchorPosition.width;
      anchorPosition.bottom = rect.bottom || anchorPosition.top + anchorPosition.height;
      anchorPosition.middle = anchorPosition.left + (anchorPosition.right - anchorPosition.left) / 2;
      anchorPosition.center = anchorPosition.top + (anchorPosition.bottom - anchorPosition.top) / 2;
      return anchorPosition;
    };

    _this.getTargetPosition = function (targetNode) {
      return {
        top: 0,
        center: targetNode.offsetHeight / 2,
        bottom: targetNode.offsetHeight,
        left: 0,
        middle: targetNode.offsetWidth / 2,
        right: targetNode.offsetWidth
      };
    };

    _this.getOrigin = function () {
      var side = _this.state.visibleDirection.split('-')[0];

      var alignment = _this.props.direction.split('-')[1];

      var origin = {
        anchor: {},
        target: {}
      };

      if (side === 'top' || side === 'bottom') {
        origin.anchor.vertical = side;
        origin.anchor.horizontal = alignment === 'center' ? 'middle' : alignment;
        origin.target.vertical = side === 'top' ? 'bottom' : 'top';
        origin.target.horizontal = alignment === 'center' ? 'middle' : alignment;
      }

      if (side === 'left' || side === 'right') {
        origin.anchor.vertical = alignment;
        origin.anchor.horizontal = side;
        origin.target.vertical = alignment;
        origin.target.horizontal = side === 'left' ? 'right' : 'left';
      }

      return origin;
    };

    _this.setArrowPlacement = function (anchor, container) {
      var arrow = _this.arrow;
      var targetOffset = _this.props.targetOffset;
      var visibleDirection = _this.state.visibleDirection;
      var side = visibleDirection.split('-')[0];
      var verticalOffset = targetOffset.vertical || 0;
      var horizontalOffset = targetOffset.horizontal || 0;
      var isAnchorWider = anchor.width > container.right;
      var isAnchorTaller = anchor.height > container.bottom;
      var arrowLeft = isAnchorWider && !visibleDirection.includes('center') ? visibleDirection.includes('left') ? container.middle + anchor.left : anchor.right - container.middle : anchor.middle;
      var arrowTop = isAnchorTaller && !visibleDirection.includes('center') ? visibleDirection.includes('top') ? container.center + anchor.top : anchor.bottom - container.center : anchor.center;

      switch (side) {
        case 'top':
          arrow.style.left = arrowLeft + "px";
          arrow.style.top = anchor.top - verticalOffset + "px";
          break;

        case 'bottom':
          arrow.style.left = arrowLeft + "px";
          arrow.style.top = anchor.bottom + verticalOffset + "px";
          break;

        case 'left':
          arrow.style.left = anchor.left - horizontalOffset + "px";
          arrow.style.top = arrowTop + "px";
          break;

        case 'right':
          arrow.style.left = anchor.right + horizontalOffset + "px";
          arrow.style.top = arrowTop + "px";
          break;
      }
    };

    _this.setBoundingBox = function (side, targetNode, anchorPosition) {
      var _this$props6 = _this.props,
          checkOverflow = _this$props6.checkOverflow,
          maxHeight = _this$props6.maxHeight,
          maxWidth = _this$props6.maxWidth,
          showArrow = _this$props6.showArrow,
          targetOffset = _this$props6.targetOffset;
      var arrowDims = showArrow && ReactDOM.findDOMNode(_this.arrow).getBoundingClientRect();
      var element = ReactDOM.findDOMNode(_this.container);
      var elementParent = element.parentElement;
      var documentScrollTop = document.documentElement.scrollTop;
      var documentBottom = document.documentElement.scrollHeight;
      var windowBottom = window.pageXOffset + window.innerHeight;
      var documentRight = document.documentElement.offsetWidth;
      var arrowHeight = arrowDims && arrowDims.height || 0;
      var arrowWidth = arrowDims && arrowDims.width || 0;
      var offsetHeight = targetOffset.vertical || 0;
      var offsetWidth = targetOffset.horizontal || 0;

      var elementParents = _this.findParents(elementParent);

      var scrollParent = _this.findScrollParent(elementParents, ['overflow', 'overflow-x']);

      var elementDims = element.getBoundingClientRect();
      var elementVerticalHeight = elementDims.height + offsetHeight;
      var elementVerticalWidth = elementDims.width + offsetWidth;

      var getAvailableTopSpace = function getAvailableTopSpace(top) {
        return top + anchorPosition.top - (_this.elementHeight + arrowHeight);
      };

      var parentDims = checkOverflow && !!scrollParent.getBoundingClientRect && scrollParent.getBoundingClientRect();

      if (targetNode && targetNode.style && !targetNode.style.bottom && elementVerticalHeight) {
        _this.elementHeight = elementVerticalHeight;
      }

      if (targetNode && targetNode.style && !targetNode.style.right && elementVerticalWidth) {
        _this.elementWidth = elementVerticalWidth;
        _this.elementLeft = elementDims.left;
        _this.elementRight = elementDims.right;
      }

      switch (side) {
        case 'top':
          if (!parentDims.top) {
            if (getAvailableTopSpace(documentScrollTop) < 0) {
              targetNode.style.top = arrowHeight - documentScrollTop + "px";
            }

            if (arrowHeight + _this.elementHeight > anchorPosition.top) {
              targetNode.style.bottom = windowBottom - anchorPosition.top + arrowHeight + offsetHeight + "px";
            }

            if (_this.elementWidth > documentRight) {
              targetNode.style.right = '0px';
            }

            if (_this.elementLeft < 0) {
              targetNode.style.left = '0px';
            }
          } else {
            if (anchorPosition.top - parentDims.top - _this.elementHeight - arrowHeight < 0) {
              targetNode.style.top = parentDims.top + arrowHeight + "px";
              targetNode.style.bottom = windowBottom - anchorPosition.top + arrowHeight + offsetHeight + "px";
              targetNode.style.maxHeight = (maxHeight || parentDims.height) + "px";
            }

            if (_this.elementWidth > parentDims.width || _this.elementRight > parentDims.right) {
              targetNode.style.right = documentRight - parentDims.right + "px";
            }

            if (_this.elementLeft < parentDims.left) {
              targetNode.style.left = parentDims.left + "px";
            }

            if (arrowDims && (arrowDims.top < parentDims.top || arrowDims.bottom + 1 > parentDims.bottom)) {
              _this.arrow.style.visibility = 'hidden';
            } else if (arrowDims) {
              _this.arrow.style.visibility = 'visible';
            }
          }

          break;

        case 'bottom':
          if (!parentDims.bottom) {
            if (_this.elementHeight + arrowHeight + anchorPosition.bottom + documentScrollTop > documentBottom) {
              targetNode.style.bottom = documentScrollTop + windowBottom - documentBottom + "px";
            }

            if (_this.elementWidth > documentRight) {
              targetNode.style.right = '0px';
            }

            if (elementDims.left < 0) {
              targetNode.style.left = '0px';
            }
          } else {
            if (_this.elementHeight + arrowHeight + anchorPosition.bottom > parentDims.bottom) {
              targetNode.style.bottom = windowBottom - parentDims.bottom + "px";
              targetNode.style.maxHeight = (maxHeight || parentDims.height) + "px";
            }

            if (_this.elementWidth > parentDims.width || _this.elementRight > parentDims.right) {
              targetNode.style.right = documentRight - parentDims.right + "px";
            }

            if (_this.elementLeft < parentDims.left) {
              targetNode.style.left = parentDims.left + "px";
            }

            if (arrowDims && (arrowDims.top < parentDims.top || arrowDims.bottom + 1 > parentDims.bottom)) {
              _this.arrow.style.visibility = 'hidden';
            } else if (arrowDims) {
              _this.arrow.style.visibility = 'visible';
            }
          }

          break;

        case 'left':
          if (!parentDims.left) {
            if (arrowWidth + offsetWidth + elementDims.width + anchorPosition.left > anchorPosition.left) {
              targetNode.style.left = arrowWidth + "px";
              targetNode.style.right = documentRight - anchorPosition.left + arrowWidth + offsetWidth + "px";
            }

            if (getAvailableTopSpace(documentScrollTop) < 0) {
              targetNode.style.top = -documentScrollTop + "px";
            }

            if (_this.elementHeight + arrowHeight + anchorPosition.bottom + documentScrollTop > documentBottom) {
              targetNode.style.bottom = documentScrollTop + windowBottom - documentBottom + "px";
            }
          } else {
            if (anchorPosition.left - parentDims.left < _this.elementWidth + arrowWidth) {
              targetNode.style.left = parentDims.left + arrowWidth + "px";
              targetNode.style.right = documentRight - anchorPosition.left + arrowWidth + offsetWidth + "px";
              targetNode.style.maxWidth = (maxWidth || parentDims.width) + "px";
            }

            if (anchorPosition.top - parentDims.top - _this.elementHeight < 0) {
              targetNode.style.top = parentDims.top + "px";
            }

            if (_this.elementHeight + anchorPosition.bottom > parentDims.bottom) {
              targetNode.style.bottom = windowBottom - parentDims.bottom + "px";
            }

            if (arrowDims && (arrowDims.top < parentDims.top || arrowDims.bottom > parentDims.bottom)) {
              _this.arrow.style.visibility = 'hidden';
            } else if (arrowDims) {
              _this.arrow.style.visibility = 'visible';
            }
          }

          break;

        case 'right':
          if (!parentDims.right) {
            if (arrowWidth + offsetWidth + elementDims.width + anchorPosition.right > documentRight) {
              targetNode.style.right = '0px';
            }

            if (getAvailableTopSpace(documentScrollTop) < 0) {
              targetNode.style.top = -documentScrollTop + "px";
            }

            if (_this.elementHeight + arrowHeight + anchorPosition.bottom + documentScrollTop > documentBottom) {
              targetNode.style.bottom = documentScrollTop + windowBottom - documentBottom + "px";
            }
          } else {
            if (anchorPosition.right + _this.elementWidth + arrowWidth > parentDims.right) {
              targetNode.style.left = anchorPosition.right + offsetWidth + "px";
              targetNode.style.right = documentRight - parentDims.right + "px";
              targetNode.style.maxWidth = (maxWidth || parentDims.width) + "px";
            }

            if (anchorPosition.top - parentDims.top - _this.elementHeight < 0) {
              targetNode.style.top = parentDims.top + "px";
            }

            if (_this.elementHeight + anchorPosition.bottom > parentDims.bottom) {
              targetNode.style.bottom = windowBottom - parentDims.bottom + "px";
            }

            if (arrowDims && (arrowDims.top < parentDims.top || arrowDims.bottom > parentDims.bottom)) {
              _this.arrow.style.visibility = 'hidden';
            } else if (arrowDims) {
              _this.arrow.style.visibility = 'visible';
            }
          }

          break;
      }
    };

    _this.setPlacement = function () {
      var _this$props7 = _this.props,
          anchorNode = _this$props7.anchorNode,
          isOpen = _this$props7.isOpen,
          isContained = _this$props7.isContained,
          showArrow = _this$props7.showArrow,
          targetOffset = _this$props7.targetOffset;
      var visibleDirection = _this.state.visibleDirection;
      if (!isOpen) return;
      var anchorNodeFound = ReactDOM.findDOMNode(anchorNode);
      var side = visibleDirection.split('-')[0];
      var targetNode = _this.container;
      var verticalOffset = targetOffset.vertical || 0;
      var horizontalOffset = targetOffset.horizontal || 0;
      if (!targetNode || !anchorNodeFound) return;
      anchorNodeFound.link = _this.state.id;

      var anchorPosition = _this.getAnchorPosition(anchorNodeFound);

      var targetPosition = _this.getTargetPosition(targetNode);

      var origin = _this.getOrigin();

      var anchorOrigin = origin.anchor;
      var targetOrigin = origin.target;
      var targetNodePosition = {
        top: anchorPosition[anchorOrigin.vertical] - targetPosition[targetOrigin.vertical] + (side === 'top' ? -verticalOffset : verticalOffset),
        left: anchorPosition[anchorOrigin.horizontal] - targetPosition[targetOrigin.horizontal] + (side === 'left' ? -horizontalOffset : horizontalOffset)
      };
      targetNode.style.top = targetNodePosition.top + "px";
      targetNode.style.left = targetNodePosition.left + "px";
      showArrow && _this.setArrowPlacement(anchorPosition, targetPosition);
      isContained && _this.setBoundingBox(side, targetNode, anchorPosition);
    };

    _this.handleClickAway = function (e) {
      _this.props.close && _this.props.close(e);
    };

    return _this;
  }

  var _proto = EventOverlay.prototype;

  _proto.render = function render() {
    var _this2 = this;

    var _this$props8 = this.props,
        children = _this$props8.children,
        className = _this$props8.className,
        isOpen = _this$props8.isOpen,
        maxHeight = _this$props8.maxHeight,
        maxWidth = _this$props8.maxWidth,
        showArrow = _this$props8.showArrow,
        style = _this$props8.style,
        props = _objectWithoutPropertiesLoose(_this$props8, ["children", "className", "isOpen", "maxHeight", "maxWidth", "showArrow", "style"]);

    var side = this.state.visibleDirection.split('-')[0];
    var otherProps = omit(Object.assign({}, props), ['allowClickAway', 'anchorNode', 'checkOverflow', 'close', 'closeOnClick', 'direction', 'isDynamic', 'isContained', 'targetOffset']);
    var contentNodes = React.createElement("div", {
      className: 'cui-event-overlay' + ("" + (showArrow && " cui-event-overlay--arrow" || '')) + ("" + (side && " cui-event-overlay--" + side || '')) + ("" + (className && " " + className || ''))
    }, showArrow && React.createElement("div", {
      ref: function ref(_ref) {
        return _this2.arrow = _ref;
      },
      className: "cui-event-overlay__arrow"
    }), React.createElement("div", _extends({
      className: "cui-event-overlay__children",
      ref: function ref(_ref2) {
        return _this2.container = _ref2;
      },
      style: Object.assign({}, maxWidth && {
        maxWidth: maxWidth + "px"
      }, maxHeight && {
        maxHeight: maxHeight + "px"
      }, style)
    }, otherProps), children));
    return isOpen && contentNodes;
  };

  return EventOverlay;
}(React.Component);

EventOverlay.displayName = 'EventOverlay';
export { EventOverlay as default };
EventOverlay.defaultProps = {
  allowClickAway: true,
  anchorNode: null,
  children: null,
  checkOverflow: false,
  className: '',
  close: null,
  direction: 'bottom-left',
  isContained: false,
  isDynamic: false,
  isOpen: false,
  maxHeight: null,
  maxWidth: null,
  showArrow: false,
  style: null,
  targetOffset: {
    horizontal: 0,
    vertical: 0
  }
};
EventOverlay.propTypes = {
  /** @prop Allows use to click outside of EventOverlay | true */
  allowClickAway: PropTypes.bool,

  /** @prop Node in which the selection begins | null */
  anchorNode: PropTypes.object,

  /** @prop Set to Check if children nodes are overflowing the EventOverlay | false */
  checkOverflow: PropTypes.bool,

  /** @prop Children nodes to render inside the EventOverlay | null */
  children: PropTypes.node,

  /** @prop Optional css class string | '' */
  className: PropTypes.string,

  /** @prop Function to close EventOverlay | null */
  close: PropTypes.func,

  /** @prop Determines if the EventOverlay should close when clicked on | true */
  closeOnClick: PropTypes.bool,

  /** @prop Sets the direction in which the EventOverlay extends | 'bottom-left' */
  direction: PropTypes.oneOf(['top-center', 'left-center', 'right-center', 'bottom-center', 'top-left', 'top-right', 'bottom-left', 'bottom-right', 'left-top', 'left-bottom', 'right-top', 'right-bottom']),

  /** @prop Determines if the contents of EventOverlay is contained within Component | false */
  isContained: PropTypes.bool,

  /** @prop Sets the EventOverlay to be a dynamic UI component | false */
  isDynamic: PropTypes.bool,

  /** @prop Sets the visibility of the EventOverlay | false */
  isOpen: PropTypes.bool,

  /** @prop Sets the max height of the EventOverlay | null */
  maxHeight: PropTypes.number,

  /** @prop Sets the max width of the EventOverlay | null */
  maxWidth: PropTypes.number,

  /** @prop Determines if the EventOverlay should show the open/close arrow | false */
  showArrow: PropTypes.bool,

  /** @prop Optional css styling | null */
  style: PropTypes.object,

  /** @prop Sets the target offset | { horizontal: 0, vertical: 0 } */
  targetOffset: PropTypes.shape({
    horizontal: PropTypes.number,
    vertical: PropTypes.number
  })
};