"use strict";

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

exports.__esModule = true;
exports.TabPanelOverflowContainer = 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 _propTypes = _interopRequireDefault(require("prop-types"));

var _lodash = _interopRequireDefault(require("lodash"));

var _TabPanel = require("./TabPanel");

var _Icon = require("./Icon");

var _NavDropdown = require("./NavDropdown");

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

var _reactMeasure = _interopRequireDefault(require("react-measure"));

var _utils = require("./utils");

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

var DROPDOWN_STYLES = {
  visibility: 'hidden',
  position: 'absolute',
  left: '-100%'
};
var TAB_PANEL_STYLES = {
  whiteSpace: 'nowrap'
};
var a11yIdCounter = 1;

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

  function TabPanelOverflowContainer(props, context) {
    var _this;

    _this = _React$Component.call(this, props, context) || this;
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleResizeRootContainer", function (contentRect) {
      _this.setState({
        dimensions: contentRect.bounds,
        visibleAmount: -1 // reset to recalculate visible amount

      });
    });
    _this.tabPanelRef = _react.default.createRef();
    _this.dropdownRef = _react.default.createRef();
    _this.dropdownA11yId = 'dropdown' + a11yIdCounter++;
    _this.state = {
      visibleAmount: -1,
      dropdownWidth: -1,
      // assume it's static and does not changed
      dimensions: {
        width: -1,
        right: -1
      }
    };
    return _this;
  }

  var _proto = TabPanelOverflowContainer.prototype;

  _proto.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {
    var _this$state = this.state,
        visibleAmount = _this$state.visibleAmount,
        dimensions = _this$state.dimensions;

    var dropdownNode = _reactDom.default.findDOMNode(this.dropdownRef.current);

    if (dropdownNode) {
      var dropdownWidth = dropdownNode.getBoundingClientRect().width;

      if (this.state.dropdownWidth !== dropdownWidth) {
        this.setState({
          dropdownWidth: dropdownWidth
        });
      }
    }

    var nextVisibleAmount = this.calculateVisibleAmount();
    var actualWidth = dimensions.width;
    var prevWidth = prevState.dimensions.width;
    var isDimensionsChanged = prevWidth !== actualWidth;
    var isChildrenChanged = prevProps.children.length !== this.props.children.length;

    if (isChildrenChanged || isDimensionsChanged) {
      // force to show all items to measure
      nextVisibleAmount = (0, _functions.cleanEmptyChildren)(this.props.children).length;
    }

    if (visibleAmount !== nextVisibleAmount) {
      this.setState({
        visibleAmount: nextVisibleAmount
      });
    }
  };

  _proto.calculateVisibleAmount = function calculateVisibleAmount() {
    var rootNode = _reactDom.default.findDOMNode(this.tabPanelRef.current);

    var dropdownNode = _reactDom.default.findDOMNode(this.dropdownRef.current);

    if (!rootNode) {
      return -1;
    }

    var children = Array.from(rootNode.children).filter(function (child) {
      return child !== dropdownNode;
    });
    var dropdownNodeWidth = this.state.dropdownWidth;
    var rootNodePaddingRight = (0, _utils.getElementPadding)(rootNode).paddingRight;
    var rootNodeBorderRight = (0, _utils.getElementBorder)(rootNode).borderRight;
    var allowedRightBoundaryPoint = this.state.dimensions.right - rootNodePaddingRight - rootNodeBorderRight;
    var lastVisibleIndex = this.findLastVisibleIndex(children, allowedRightBoundaryPoint);
    var isOverflow = lastVisibleIndex !== (0, _functions.cleanEmptyChildren)(this.props.children).length - 1;

    if (isOverflow) {
      // in case of overflow, recalculate, taking into consideration that dropdown is on the screen
      var lastVisibleIndexIncludingDropdown = this.findLastVisibleIndex(children, allowedRightBoundaryPoint - dropdownNodeWidth);
      lastVisibleIndex = Math.min(lastVisibleIndex, lastVisibleIndexIncludingDropdown);
    }

    return lastVisibleIndex + 1;
  };

  _proto.findLastVisibleIndex = function findLastVisibleIndex(nodes, allowedRightBoundaryPoint) {
    var childIndex = nodes.length - 1;
    var visibleIndex = nodes.length - 1;

    while (childIndex >= 0) {
      var child = nodes[childIndex];
      childIndex--;
      var boundaryRect = child.getBoundingClientRect();
      var rightBoundaryPoint = boundaryRect.right;
      var childRightMargin = (0, _utils.getElementMargin)(child).marginRight;

      if (rightBoundaryPoint + childRightMargin > allowedRightBoundaryPoint) {
        visibleIndex--;
      } else {
        break;
      }
    }

    return visibleIndex;
  };

  _proto.render = function render() {
    var _this$props = this.props,
        rawChildren = _this$props.children,
        props = (0, _objectWithoutPropertiesLoose2.default)(_this$props, ["children"]);
    var _this$state2 = this.state,
        visibleAmount = _this$state2.visibleAmount,
        dropdownWidth = _this$state2.dropdownWidth;
    var children = (0, _functions.cleanEmptyChildren)(rawChildren);
    visibleAmount = visibleAmount === -1 ? children.length : visibleAmount;

    var head = _lodash.default.take(children, visibleAmount);

    var tail = _lodash.default.takeRight(children, children.length - visibleAmount);

    var isOverflow = tail.length > 0;
    var resultChildren = head;
    var dropdown = null;

    if (dropdownWidth === -1 || isOverflow) {
      // show it to measure dropdown size, but out of viewport to avoid UI flicker
      var dropdownStyles = null;

      if (dropdownWidth === -1) {
        dropdownStyles = DROPDOWN_STYLES;
      }

      var id = this.dropdownA11yId;
      dropdown = _react.default.createElement(_NavDropdown.NavDropdown, {
        role: "tab",
        testAutomationId: "menuItemMore",
        id: id,
        ref: this.dropdownRef,
        className: "pull-right",
        title: _react.default.createElement(_Icon.Icon, {
          name: "three-dots"
        }),
        style: dropdownStyles
      }, tail);

      if (!isOverflow) {
        dropdown = null;
      }

      if (dropdown) {
        resultChildren.push(dropdown);
      }
    }

    var tabPanel = _react.default.createElement(_TabPanel.TabPanel, (0, _extends2.default)({
      ref: this.tabPanelRef
    }, props, {
      style: TAB_PANEL_STYLES
    }), resultChildren);

    return _react.default.createElement(_reactMeasure.default, {
      bounds: true,
      onResize: this.handleResizeRootContainer
    }, function (_ref) {
      var measureRef = _ref.measureRef;
      return _react.default.createElement("div", {
        ref: measureRef
      }, tabPanel);
    });
  };

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

exports.TabPanelOverflowContainer = TabPanelOverflowContainer;
(0, _defineProperty2.default)(TabPanelOverflowContainer, "propTypes", {
  children: _propTypes.default.node
});
(0, _defineProperty2.default)(TabPanelOverflowContainer, "defaultProps", {
  children: null
});