'use strict';

import _extends from "@babel/runtime/helpers/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose";
import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
import _inheritsLoose from "@babel/runtime/helpers/inheritsLoose";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import React, { cloneElement } from 'react';
import { findDOMNode } from 'react-dom';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import Modal from 'react-bootstrap/lib/Modal';
import { getScrollbarWidth, closePopup, restorePopupVisibility, popupContainerId } from '../utils';
import { KeyCodes } from '../../../utils/constants';
import tabbable from 'tabbable';
export var Popup =
/*#__PURE__*/
function (_React$Component) {
  _inheritsLoose(Popup, _React$Component);

  Popup.close = function close() {
    if (Popup.stack.length) {
      var popup = Popup.stack[Popup.stack.length - 1];

      if (popup.props.onHide) {
        popup.props.onHide();
        return;
      }
    }

    closePopup();
  };

  Popup.addStyleSheet = function addStyleSheet() {
    var width = getScrollbarWidth();
    Popup.styleSheet = document.createElement('style');
    Popup.styleSheet.innerHTML = "\n            body.rc-modal-open {\n                padding-right: " + width + "px !important;\n            }\n            [aria-hidden=\"true\"] [role=\"dialog\"] {\n                padding-right: " + width + "px !important;\n            }\n        ";
    document.head.appendChild(Popup.styleSheet);
  };

  Popup.updateBodyClass = function updateBodyClass() {
    var length = Popup.stack.length;
    var regexp = /\s*rc-modal-open/g;

    if (length) {
      if (!regexp.test(document.body.className)) {
        document.body.className += document.body.className.length ? ' rc-modal-open' : 'rc-modal-open';
      }
    } else {
      document.body.className = document.body.className.replace(regexp, '');
    }
  };

  function Popup(props, context) {
    var _this;

    if (!Popup.styleSheet) {
      Popup.addStyleSheet();
    }

    _this = _React$Component.call(this, props, context) || this;

    _defineProperty(_assertThisInitialized(_this), "handleHeaderRef", function (ref) {
      if (!ref) {
        return;
      }

      var $modalHeader = findDOMNode(ref);

      if (!$modalHeader) {
        return;
      }

      var $closeButton = $modalHeader.querySelector("button[class = 'close']");

      if ($closeButton) {
        $closeButton.setAttribute('data-test-automation-id', 'closeButton');
      }
    });

    _defineProperty(_assertThisInitialized(_this), "trapFocus", function (event) {
      if (event.keyCode === KeyCodes.TAB) {
        var activeElement = document.activeElement;
        var modalContentNode = _this.modalContentRef.current;
        var tabbableNodes = tabbable(modalContentNode);
        event.stopPropagation();

        if (tabbableNodes.length === 0) {
          return event.preventDefault();
        }

        if (event.shiftKey) {
          var isDispatchedOnModalWrapper = activeElement.contains(modalContentNode);

          if (isDispatchedOnModalWrapper || tabbableNodes[0] === activeElement) {
            event.preventDefault();
            tabbableNodes[tabbableNodes.length - 1].focus();
          }
        } else {
          if (tabbableNodes[tabbableNodes.length - 1] === activeElement) {
            event.preventDefault();
            tabbableNodes[0].focus();
          }
        }
      }
    });

    _defineProperty(_assertThisInitialized(_this), "hideModal", function () {
      if (_this.props.onClose) {
        _this.props.onClose();
      } else {
        Popup.close();
      }
    });

    Popup.stack.push(_assertThisInitialized(_this));
    Popup.updateBodyClass();
    _this.modalContentRef = React.createRef();
    _this.hideModal = _this.hideModal.bind(_assertThisInitialized(_this));
    return _this;
  }

  var _proto = Popup.prototype;

  _proto.componentWillUnmount = function componentWillUnmount() {
    var index = Popup.stack.indexOf(this);

    if (index !== -1) {
      Popup.stack.splice(index, 1);
      Popup.updateBodyClass();
      setImmediate(restorePopupVisibility);
    }
  };

  _proto.render = function render() {
    // Extract own props to make it safe to pass Modal props down
    var _this$props = this.props,
        testAutomationId = _this$props.testAutomationId,
        stackable = _this$props.stackable,
        noPadding = _this$props.noPadding,
        noBottomPadding = _this$props.noBottomPadding,
        noHeaderPadding = _this$props.noHeaderPadding,
        borderedTitle = _this$props.borderedTitle,
        closeButton = _this$props.closeButton,
        keyboard = _this$props.keyboard,
        closeLabel = _this$props.closeLabel,
        className = _this$props.className,
        header = _this$props.header,
        footer = _this$props.footer,
        title = _this$props.title,
        onClose = _this$props.onClose,
        children = _this$props.children,
        ariaLabelledBy = _this$props['aria-labelledby'],
        ariaDescribedBy = _this$props['aria-describedby'],
        shouldDeriveDescFromBody = _this$props.shouldDeriveDescFromBody,
        props = _objectWithoutPropertiesLoose(_this$props, ["testAutomationId", "stackable", "noPadding", "noBottomPadding", "noHeaderPadding", "borderedTitle", "closeButton", "keyboard", "closeLabel", "className", "header", "footer", "title", "onClose", "children", "aria-labelledby", "aria-describedby", "shouldDeriveDescFromBody"]);

    var titleId = "dlg-title-" + testAutomationId;
    var contentId = "dlg-content-" + testAutomationId;

    if (!ariaLabelledBy) {
      ariaLabelledBy = titleId;
    }

    if (!ariaDescribedBy && shouldDeriveDescFromBody) {
      ariaDescribedBy = contentId;
    }

    if (this.props.footer) {
      footer = React.createElement(Modal.Footer, {
        "data-test-automation-id": "popupFooter"
      }, footer);
    }

    if (title) {
      title = React.createElement(Modal.Title, {
        role: "presentation",
        "data-test-automation-id": "title",
        className: classnames({
          'bordered-modal-title': borderedTitle
        })
      }, React.createElement("span", {
        id: titleId
      }, title));
    }

    if (!title && header) {
      header = cloneElement(header, {
        id: titleId
      });
    }

    var supportEscClose = keyboard || closeButton;
    return React.createElement(Modal, _extends({
      keyboard: supportEscClose,
      onKeyDown: this.trapFocus,
      show: true,
      "data-test-automation-id": testAutomationId,
      container: document.getElementById(popupContainerId)
    }, props, {
      "aria-labelledby": ariaLabelledBy,
      "aria-describedby": ariaDescribedBy,
      role: "document",
      enforceFocus: false,
      onHide: this.hideModal,
      className: classnames('static-modal', {
        'rc-popup-noPadding': noPadding,
        'rc-popup-noBottomPadding': noBottomPadding,
        'rc-popup-noHeaderPadding': noHeaderPadding,
        // we have a technical difficulties for close button manipulations during closeButton prop changes
        // Modal calls componentDidUpdate in incorrect order, so we have to render it always and manage
        // visibility via CSS
        'rc-popup-noCloseButton': !closeButton
      }, className)
    }), React.createElement("div", {
      ref: this.modalContentRef
    }, React.createElement(Modal.Header, {
      ref: this.handleHeaderRef,
      "data-test-automation-id": "popupHeader",
      closeButton: true,
      closeLabel: closeLabel
    }, title, header), React.createElement(Modal.Body, {
      id: contentId,
      "data-test-automation-id": "popupContent"
    }, children), footer));
  };

  return Popup;
}(React.Component);

_defineProperty(Popup, "stack", []);

_defineProperty(Popup, "propTypes", {
  children: PropTypes.node,
  className: PropTypes.string,
  stackable: PropTypes.bool,
  borderedTitle: PropTypes.bool,
  noPadding: PropTypes.bool,
  noBottomPadding: PropTypes.bool,
  noHeaderPadding: PropTypes.bool,
  closeButton: PropTypes.bool,
  closeLabel: PropTypes.string,
  title: PropTypes.string,
  testAutomationId: PropTypes.string,
  header: PropTypes.node,
  footer: PropTypes.node,
  onClose: PropTypes.func,
  'aria-labelledby': PropTypes.string,
  'aria-describedby': PropTypes.string,
  shouldDeriveDescFromBody: PropTypes.bool,
  keyboard: PropTypes.bool
});

_defineProperty(Popup, "defaultProps", {
  children: null,
  className: null,
  testAutomationId: 'popup',
  borderedTitle: false,
  noPadding: false,
  noBottomPadding: false,
  noHeaderPadding: false,
  title: '',
  closeButton: true,
  closeLabel: 'TRANSLATE:CLOSE',
  header: null,
  footer: null,
  stackable: false,
  backdrop: 'static',
  onClose: null,
  'aria-labelledby': null,
  'aria-describedby': null,
  shouldDeriveDescFromBody: false,
  keyboard: false
});