"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));

var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));

var _react = _interopRequireWildcard(require("react"));

var _reactDom = require("react-dom");

var _propTypes = _interopRequireDefault(require("prop-types"));

var _classnames = _interopRequireDefault(require("classnames"));

var _constants = require("../../constants");

var _popper = _interopRequireDefault(require("popper.js"));

var _Layer = _interopRequireDefault(require("../Layer"));

function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }

function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

// Copyright 1999-2020. Plesk International GmbH. All rights reserved.

/* eslint-disable react/no-deprecated */

/**
 * `Popper` component.
 */
class Popper extends _react.Component {
  constructor(...args) {
    super(...args);
    (0, _defineProperty2.default)(this, "state", {
      popperStyle: null,
      arrowStyle: null,
      actualPlacement: this.props.placement
    });
    (0, _defineProperty2.default)(this, "popper", null);
    (0, _defineProperty2.default)(this, "contentRef", /*#__PURE__*/(0, _react.createRef)());
    (0, _defineProperty2.default)(this, "extractStyles", state => {
      if (!state) {
        return;
      }

      const {
        onUpdate
      } = this.props;
      const data = {
        popperStyle: {
          position: state.offsets.popper.position,
          ...(state.hide ? {
            visibility: 'hidden',
            pointerEvents: 'none'
          } : undefined),
          ...state.styles
        },
        actualPlacement: state.placement,
        arrowStyle: state.arrowStyles
      };
      this.setState(data);

      if (onUpdate) {
        onUpdate(data);
      }
    });
  }

  componentDidMount() {
    this.updatePopper(this.props);
  }

  componentDidUpdate(prevProps) {
    const {
      show,
      boundariesElement,
      placement,
      offset,
      behavior,
      arrow,
      children
    } = this.props;

    if (prevProps.show !== show || prevProps.boundariesElement !== boundariesElement || prevProps.placement !== placement || prevProps.offset !== offset || prevProps.behavior !== behavior || prevProps.arrow !== arrow || prevProps.children !== children) {
      setTimeout(() => {
        this.updatePopper(this.props);
      }, 0);
    }
  }

  componentWillUnmount() {
    if (this.popper) {
      this.popper.destroy();
    }
  }

  updatePopper({
    show,
    boundariesElement,
    placement,
    offset,
    behavior,
    arrow,
    targetRef
  }) {
    if (this.popper) {
      this.popper.destroy();
    }

    if (!this.contentRef.current || !show) {
      return;
    }

    const popperOpts = {
      placement,
      modifiers: {
        applyStyle: {
          enabled: false
        },
        applyReactStyle: {
          enabled: true,
          fn: this.extractStyles,
          order: 900
        },
        preventOverflow: {
          enabled: true,
          boundariesElement
        },
        hide: {
          enabled: true
        },
        offset: {
          enabled: true,
          offset
        },
        flip: {
          enabled: true,
          padding: 0,
          behavior
        },
        arrow: arrow && {
          enabled: true,
          element: this.arrowRef
        }
      }
    };
    let reference;

    if (targetRef && targetRef.current) {
      reference = targetRef.current;
    } else {
      reference = (0, _reactDom.findDOMNode)(this);
    }

    this.popper = new _popper.default(reference, this.contentRef.current, popperOpts);
  }

  render() {
    const {
      baseClassName,
      className,
      children,
      target,
      targetRef,
      arrow,
      placement,
      behavior,
      offset,
      onUpdate,
      zIndex,
      show,
      boundariesElement,
      style,
      ...props
    } = this.props;
    const {
      popperStyle
    } = this.state;
    const {
      arrowStyle,
      actualPlacement
    } = this.state;
    const arrowElement = arrow && /*#__PURE__*/(0, _react.cloneElement)(arrow, {
      ref: ref => this.arrowRef = ref,
      style: arrowStyle
    });
    return /*#__PURE__*/_react.default.createElement(_react.Fragment, null, target, show ? /*#__PURE__*/_react.default.createElement(_Layer.default, {
      level: zIndex
    }, /*#__PURE__*/_react.default.createElement("div", (0, _extends2.default)({
      ref: this.contentRef,
      className: (0, _classnames.default)(baseClassName, className, `${baseClassName}--placement-${actualPlacement}`),
      style: { ...style,
        ...(popperStyle ? popperStyle : {
          position: 'fixed',
          opacity: 0
        })
      }
    }, props), children, arrowElement)) : null);
  }

}

Popper.propTypes = {
  /**
   * Whether show popper content.
   */
  show: _propTypes.default.bool,

  /**
   * Content of the `Popper`.
   */
  children: _propTypes.default.node,

  /**
   * Target for popper.
   */
  target: _propTypes.default.any.isRequired,

  /**
   * A React reference to the DOM element that needs for calculating the position of the popup.
   */
  targetRef: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.shape({
    current: _propTypes.default.instanceOf(HTMLElement)
  })]),

  /**
   * Arrow element of popper
   */
  arrow: _propTypes.default.element,

  /**
   * Placement for popper.
   */
  placement: _propTypes.default.oneOf(['auto', 'auto-start', 'auto-end', 'auto-top', 'auto-right', 'auto-bottom', 'auto-left', 'top', 'top-start', 'top-end', 'right', 'right-start', 'right-end', 'bottom', 'bottom-start', 'bottom-end', 'left', 'left-start', 'left-end']),

  /**
   * The behavior used to change the popper's placement.
   */
  behavior: _propTypes.default.oneOfType([_propTypes.default.oneOf(['flip', 'clockwise', 'counterclockwise']), _propTypes.default.arrayOf(_propTypes.default.string)]),

  /**
   * Shift your popper on both axis.
   */
  offset: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]),

  /**
   * Update callback function
   */
  onUpdate: _propTypes.default.func,

  /**
   * @ignore
   */
  className: _propTypes.default.string,

  /**
   * @ignore
   */
  baseClassName: _propTypes.default.string,

  /**
   * zIndex value.
   */
  zIndex: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]),

  /**
   * Boundaries element for preventOverflow property.
   */
  boundariesElement: _propTypes.default.oneOfType([_propTypes.default.oneOf(['scrollParent', 'window', 'viewport']), _propTypes.default.instanceOf(HTMLElement)]),

  /**
   * @ignore
   */
  style: _propTypes.default.object
};
Popper.defaultProps = {
  show: true,
  children: null,
  arrow: null,
  placement: 'bottom-start',
  behavior: 'flip',
  offset: '0, 0',
  onUpdate: null,
  className: null,
  baseClassName: `${_constants.CLS_PREFIX}popper`,
  zIndex: null,
  boundariesElement: 'window',
  style: undefined,
  targetRef: undefined
};
var _default = Popper;
exports.default = _default;