'use strict';

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

exports.__esModule = true;
exports.TabPanel = exports.TAB_PANEL_ITEM_ROLES = exports.TAB_PANEL_STYLES = void 0;

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

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

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

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

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

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

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

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

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

var _lodash = require("lodash");

var _Nav = _interopRequireDefault(require("react-bootstrap/lib/Nav"));

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

var _index = require("../index");

var _functions = require("../utils/functions");

var TAB_PANEL_STYLES = {
  TABS: 'tabs',
  PILLS: 'pills',
  MENU: 'menu'
};
exports.TAB_PANEL_STYLES = TAB_PANEL_STYLES;
var TAB_PANEL_ITEM_ROLES = {
  menuitem: 'menuitem',
  tab: 'tab'
};
exports.TAB_PANEL_ITEM_ROLES = TAB_PANEL_ITEM_ROLES;

var TabPanel =
/*#__PURE__*/
function (_React$Component) {
  (0, _inheritsLoose2.default)(TabPanel, _React$Component);

  function TabPanel() {
    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;
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "state", {
      focusedItemIndex: 0,
      isDropdownOpen: false
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "isStyledAsTab", function () {
      var _this$props = _this.props,
          bsStyle = _this$props.bsStyle,
          activeKey = _this$props.activeKey;
      return bsStyle === TAB_PANEL_STYLES.TABS || activeKey || activeKey === 0;
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "setFocusedItemByIndex", function (index) {
      var rawChildren = _this.props.children;
      var children = (0, _functions.cleanEmptyChildren)(rawChildren);

      if (index !== -1 && !children[index].props.disabled) {
        _this.setState({
          focusedItemIndex: index
        });
      }
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleClick", function (event) {
      var rawChildren = _this.props.children;
      var children = (0, _functions.cleanEmptyChildren)(rawChildren);

      var tabPanelNode = _reactDom.default.findDOMNode((0, _assertThisInitialized2.default)(_this));

      var childNode = event.target.parentNode;
      var index = TabPanel.getChildIndex(tabPanelNode, childNode);

      _this.setFocusedItemByIndex(index);

      if (!TabPanel.isItemOfDropdownType(children[index])) {
        _this.setState({
          isDropdownOpen: false
        });
      }
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleKeyDown", function (event) {
      var rawChildren = _this.props.children;
      var children = (0, _functions.cleanEmptyChildren)(rawChildren);
      var _this$state = _this.state,
          focusedItemIndex = _this$state.focusedItemIndex,
          isDropdownOpen = _this$state.isDropdownOpen;
      var focusedTab = children[focusedItemIndex];

      switch (event.keyCode) {
        case _constants.KeyCodes.ARROW_LEFT:
        case _constants.KeyCodes.ARROW_UP:
          if (!isDropdownOpen) {
            var previousTab = _this.getPreviousTab();

            _this.setFocusedItemByIndex(previousTab);
          }

          break;

        case _constants.KeyCodes.ARROW_RIGHT:
          if (!isDropdownOpen) {
            var nextTab = _this.getNextTab();

            _this.setFocusedItemByIndex(nextTab);
          }

          break;

        case _constants.KeyCodes.ARROW_DOWN:
          if (!isDropdownOpen) {
            if (TabPanel.isItemOfDropdownType(focusedTab)) {
              _this.setState({
                isDropdownOpen: true
              });
            } else {
              var _nextTab = _this.getNextTab();

              _this.setFocusedItemByIndex(_nextTab);

              event.preventDefault();
            }
          }

          break;

        case _constants.KeyCodes.TAB:
          _this.setState({
            isDropdownOpen: false
          });

          var activeItem = _this.getActiveItemIndex();

          if (activeItem < focusedItemIndex && event.shiftKey || activeItem > focusedItemIndex && !event.shiftKey) {
            _this.setFocusedItemByIndex(activeItem);

            event.preventDefault();
          }

          break;

        case _constants.KeyCodes.ENTER:
        case _constants.KeyCodes.SPACE:
          if (TabPanel.isItemCanBeFocusedWithKeyboard(children[focusedItemIndex])) {
            event.preventDefault();

            _this.setState({
              isDropdownOpen: false
            });

            _this.setActiveItem(focusedTab, event.target);
          }

          break;

        case _constants.KeyCodes.ESC:
          _this.setState({
            isDropdownOpen: false
          });

      }
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "setActiveItem", function (focusedTab, target) {
      var focusedItem;

      if (TabPanel.isItemOfTabItemType(focusedTab)) {
        focusedItem = focusedTab;
      } else {
        var navDropdownNode = target.parentNode.parentNode;
        var index = TabPanel.getChildIndex(navDropdownNode, target);
        var children = (0, _functions.cleanEmptyChildren)(focusedTab.props.children);
        focusedItem = children[index];
      }

      if ((0, _lodash.isEmpty)(focusedItem)) {
        return;
      }

      var activeTabPath = TabPanel.getItemPath(focusedItem);

      _this.activatePath(activeTabPath);

      var _focusedItem$props = focusedItem.props,
          eventKey = _focusedItem$props.eventKey,
          onClick = _focusedItem$props.onClick,
          onSelect = _focusedItem$props.onSelect;

      if (onSelect) {
        onSelect(eventKey);
      }

      if (onClick) {
        onClick();
      }
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "activatePath", function (activeTabPath) {
      if (activeTabPath) {
        _this.context.router.push(activeTabPath);
      }
    });
    return _this;
  }

  TabPanel.getChildIndex = function getChildIndex(containerNode, childNode) {
    var index = -1;
    var childrenArray = Array.from(containerNode.children);

    while (index === -1 && childNode !== null) {
      index = childrenArray.indexOf(childNode);
      childNode = childNode.parentNode;
    }

    return index;
  };

  TabPanel.getItemPath = function getItemPath(item) {
    if ((0, _lodash.isEmpty)(item) || (0, _lodash.isEmpty)(item.props)) {
      return '';
    }

    var to = item.props.to;
    return to && (to.pathname || to) || '';
  };

  TabPanel.isItemCanBeFocusedWithKeyboard = function isItemCanBeFocusedWithKeyboard(item) {
    var isAllowedByDefault = TabPanel.isItemOfDropdownType(item) || TabPanel.isItemOfTabItemType(item);
    return isAllowedByDefault || item.props.role in TAB_PANEL_ITEM_ROLES;
  };

  TabPanel.isItemOfDropdownType = function isItemOfDropdownType(item) {
    return item && (0, _functions.isElementHasType)(item, _index.NavDropdown);
  };

  TabPanel.isItemOfTabItemType = function isItemOfTabItemType(item) {
    return item && (0, _functions.isElementHasType)(item, _index.TabItem);
  };

  var _proto = TabPanel.prototype;

  _proto.getChildContext = function getChildContext() {
    return {
      isStyledAsTab: this.isStyledAsTab
    };
  };

  _proto.componentDidMount = function componentDidMount() {
    this.focusActiveItem();
  };

  _proto.componentDidUpdate = function componentDidUpdate(previousProps, previousState) {
    if (this.isStyledAsTab()) {
      var previousFocusedItemIndex = previousState.focusedItemIndex;
      var focusedItemIndex = this.state.focusedItemIndex;

      if (previousFocusedItemIndex !== focusedItemIndex) {
        this.focusToItemNodeByIndex(focusedItemIndex);
      }
    }
  };

  _proto.focusToItemNodeByIndex = function focusToItemNodeByIndex(focusedItemIndex) {
    var childNodes = _reactDom.default.findDOMNode(this).children;

    var activeNode = childNodes[focusedItemIndex];

    if (activeNode) {
      activeNode.firstChild.focus();
    }
  };

  _proto.focusActiveItem = function focusActiveItem() {
    var activeItemIndex = this.getActiveItemIndex();
    this.setFocusedItemByIndex(activeItemIndex);
    this.focusToItemNodeByIndex(activeItemIndex);
  };

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

    var _this$props2 = this.props,
        activeKey = _this$props2.activeKey,
        rawChildren = _this$props2.children;
    var children = (0, _functions.cleanEmptyChildren)(rawChildren);
    var activeItemIndex;

    if (activeKey === null) {
      activeItemIndex = children.findIndex(function (child) {
        return child && (child.props.active || _this2.context.router && _this2.context.router.isActive(TabPanel.getItemPath(child), false));
      });
    } else {
      activeItemIndex = children.findIndex(function (child) {
        return child && child.props.eventKey === activeKey;
      });
    }

    return activeItemIndex;
  };

  _proto.getPreviousTab = function getPreviousTab() {
    var rawChildren = this.props.children;
    var children = (0, _functions.cleanEmptyChildren)(rawChildren);
    var focusedItemIndex = this.state.focusedItemIndex;
    var previousItemIndex = focusedItemIndex - 1;
    var isPreviousChildPresent = previousItemIndex >= 0;
    var lastChildIndex = children.length - 1;

    if (isPreviousChildPresent && TabPanel.isItemCanBeFocusedWithKeyboard(children[previousItemIndex])) {
      return previousItemIndex;
    }

    return TabPanel.isItemCanBeFocusedWithKeyboard(children[lastChildIndex]) ? lastChildIndex : lastChildIndex - 1;
  };

  _proto.getNextTab = function getNextTab() {
    var rawChildren = this.props.children;
    var children = (0, _functions.cleanEmptyChildren)(rawChildren);
    var focusedItemIndex = this.state.focusedItemIndex;
    var nextItemIndex = focusedItemIndex + 1;
    var isNextChildPresent = nextItemIndex < children.length;

    if (isNextChildPresent && TabPanel.isItemCanBeFocusedWithKeyboard(children[nextItemIndex])) {
      return nextItemIndex;
    }

    return 0;
  };

  _proto.render = function render() {
    var _this$props3 = this.props,
        testAutomationId = _this$props3.testAutomationId,
        centered = _this$props3.centered,
        noBorder = _this$props3.noBorder,
        topMenu = _this$props3.topMenu,
        clearRightPadding = _this$props3.clearRightPadding,
        clearLeftPadding = _this$props3.clearLeftPadding,
        clearLeftWrapperPadding = _this$props3.clearLeftWrapperPadding,
        clearRightWrapperPadding = _this$props3.clearRightWrapperPadding,
        fullWidthBorder = _this$props3.fullWidthBorder,
        noPadding = _this$props3.noPadding,
        className = _this$props3.className,
        children = _this$props3.children,
        preserveBottomBorder = _this$props3.preserveBottomBorder,
        props = (0, _objectWithoutPropertiesLoose2.default)(_this$props3, ["testAutomationId", "centered", "noBorder", "topMenu", "clearRightPadding", "clearLeftPadding", "clearLeftWrapperPadding", "clearRightWrapperPadding", "fullWidthBorder", "noPadding", "className", "children", "preserveBottomBorder"]);
    className = (0, _classnames.default)({
      'rc-nav-centered': centered,
      'rc-nav-noHorizontalPadding': noPadding,
      'rc-nav-noBorder': noBorder,
      'rc-nav-fullWidthBorder': !noBorder && fullWidthBorder,
      'rc-nav-topMenu': topMenu,
      'rc-nav-clearRightPadding': clearRightPadding,
      'rc-nav-clearLeftPadding': clearLeftPadding,
      'rc-nav-clearLeftWrapperPadding': clearLeftWrapperPadding,
      'rc-nav-clearRightWrapperPadding': clearRightWrapperPadding,
      'rc-nav-preserveBottomBorder': preserveBottomBorder
    }, className);
    return _react.default.createElement(_Nav.default, (0, _extends2.default)({
      bsStyle: "tabs",
      className: className,
      "data-test-automation-id": testAutomationId,
      role: "tablist",
      tabIndex: 0,
      onClick: this.handleClick,
      onKeyDown: this.handleKeyDown
    }, props), children);
  };

  return TabPanel;
}(_react.default.Component);

exports.TabPanel = TabPanel;
(0, _defineProperty2.default)(TabPanel, "propTypes", {
  testAutomationId: _propTypes.default.string,
  children: _propTypes.default.node.isRequired,
  centered: _propTypes.default.bool,
  noBorder: _propTypes.default.bool,
  topMenu: _propTypes.default.bool,
  clearRightPadding: _propTypes.default.bool,
  clearLeftPadding: _propTypes.default.bool,
  clearLeftWrapperPadding: _propTypes.default.bool,
  clearRightWrapperPadding: _propTypes.default.bool,
  fullWidthBorder: _propTypes.default.bool,
  noPadding: _propTypes.default.bool,
  preserveBottomBorder: _propTypes.default.bool,
  className: _propTypes.default.string,
  activeKey: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]),
  bsStyle: _propTypes.default.oneOf([TAB_PANEL_STYLES.TABS, TAB_PANEL_STYLES.MENU, TAB_PANEL_STYLES.PILLS])
});
(0, _defineProperty2.default)(TabPanel, "defaultProps", {
  testAutomationId: 'tabs',
  centered: false,
  noBorder: false,
  topMenu: false,
  clearRightPadding: false,
  clearLeftPadding: false,
  clearLeftWrapperPadding: false,
  clearRightWrapperPadding: false,
  fullWidthBorder: false,
  preserveBottomBorder: false,
  noPadding: false,
  className: null,
  activeKey: null,
  bsStyle: TAB_PANEL_STYLES.TABS
});
(0, _defineProperty2.default)(TabPanel, "contextTypes", {
  router: _propTypes.default.object
});
(0, _defineProperty2.default)(TabPanel, "childContextTypes", {
  isStyledAsTab: _propTypes.default.func
});