import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
import _extends from "@babel/runtime/helpers/extends";
import _objectSpread from "@babel/runtime/helpers/objectSpread2";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
import _inherits from "@babel/runtime/helpers/inherits";
import _createSuper from "@babel/runtime/helpers/createSuper";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
var _excluded = ["children", "title", "eventKey"],
    _excluded2 = ["hiddenClassName", "hidden", "prefixCls", "overflowedIndicator", "mode", "level", "tag", "children", "theme"];
import React, { cloneElement, Component } from 'react';
import ReactDOM from 'react-dom';
import ResizeObserver from 'resize-observer-polyfill';
import SubMenu from './SubMenu';
import { getWidth, menuAllProps, setStyle } from './util';
var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
var MENUITEM_OVERFLOWED_CLASSNAME = 'menuitem-overflowed'; // Fix ssr

if (canUseDOM) {
  require('mutationobserver-shim');
}

var DOMWrap = /*#__PURE__*/function (_Component) {
  _inherits(DOMWrap, _Component);

  var _super = _createSuper(DOMWrap);

  function DOMWrap() {
    var _this;

    _classCallCheck(this, DOMWrap);

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

    _this = _super.call.apply(_super, [this].concat(args));

    _defineProperty(_assertThisInitialized(_this), "state", {
      lastVisibleIndex: undefined
    });

    _defineProperty(_assertThisInitialized(_this), "getMenuItemNodes", function () {
      var prefixCls = _this.props.prefixCls;
      var ul = ReactDOM.findDOMNode(_assertThisInitialized(_this));

      if (!ul) {
        return [];
      } // filter out all overflowed indicator placeholder


      return [].slice.call(ul.children).filter(function (node) {
        return node.className.split(' ').indexOf("".concat(prefixCls, "-overflowed-submenu")) < 0;
      });
    });

    _defineProperty(_assertThisInitialized(_this), "getOverflowedSubMenuItem", function (keyPrefix, overflowedItems, renderPlaceholder) {
      var _this$props = _this.props,
          overflowedIndicator = _this$props.overflowedIndicator,
          level = _this$props.level,
          mode = _this$props.mode,
          prefixCls = _this$props.prefixCls,
          theme = _this$props.theme,
          propStyle = _this$props.style;

      if (level !== 1 || mode !== 'horizontal') {
        return null;
      } // put all the overflowed item inside a submenu
      // with a title of overflow indicator ('...')


      var copy = _this.props.children[0];

      var _copy$props = copy.props,
          throwAway = _copy$props.children,
          title = _copy$props.title,
          eventKey = _copy$props.eventKey,
          rest = _objectWithoutProperties(_copy$props, _excluded);

      var style = _objectSpread({}, propStyle);

      var key = "".concat(keyPrefix, "-overflowed-indicator");

      if (overflowedItems.length === 0 && renderPlaceholder !== true) {
        style = _objectSpread(_objectSpread({}, style), {}, {
          display: 'none'
        });
      } else if (renderPlaceholder) {
        style = _objectSpread(_objectSpread({}, style), {}, {
          visibility: 'hidden',
          // prevent from taking normal dom space
          position: 'absolute'
        });
        key = "".concat(key, "-placeholder");
      }

      var popupClassName = theme ? "".concat(prefixCls, "-").concat(theme) : '';
      var props = {};
      menuAllProps.forEach(function (k) {
        if (rest[k] !== undefined) {
          props[k] = rest[k];
        }
      });
      return /*#__PURE__*/React.createElement(SubMenu, _extends({
        title: overflowedIndicator,
        className: "".concat(prefixCls, "-overflowed-submenu"),
        popupClassName: popupClassName
      }, props, {
        key: key,
        eventKey: "".concat(keyPrefix, "-overflowed-indicator"),
        disabled: false,
        style: style
      }), overflowedItems);
    });

    _defineProperty(_assertThisInitialized(_this), "setChildrenWidthAndResize", function () {
      if (_this.props.mode !== 'horizontal') {
        return;
      }

      var ul = ReactDOM.findDOMNode(_assertThisInitialized(_this));

      if (!ul) {
        return;
      }

      var ulChildrenNodes = ul.children;

      if (!ulChildrenNodes || ulChildrenNodes.length === 0) {
        return;
      }

      var lastOverflowedIndicatorPlaceholder = ul.children[ulChildrenNodes.length - 1]; // need last overflowed indicator for calculating length;

      setStyle(lastOverflowedIndicatorPlaceholder, 'display', 'inline-block');

      var menuItemNodes = _this.getMenuItemNodes(); // reset display attribute for all hidden elements caused by overflow to calculate updated width
      // and then reset to original state after width calculation


      var overflowedItems = menuItemNodes.filter(function (c) {
        return c.className.split(' ').indexOf(MENUITEM_OVERFLOWED_CLASSNAME) >= 0;
      });
      overflowedItems.forEach(function (c) {
        setStyle(c, 'display', 'inline-block');
      });
      _this.menuItemSizes = menuItemNodes.map(function (c) {
        return getWidth(c);
      });
      overflowedItems.forEach(function (c) {
        setStyle(c, 'display', 'none');
      });
      _this.overflowedIndicatorWidth = getWidth(ul.children[ul.children.length - 1]);
      _this.originalTotalWidth = _this.menuItemSizes.reduce(function (acc, cur) {
        return acc + cur;
      }, 0);

      _this.handleResize(); // prevent the overflowed indicator from taking space;


      setStyle(lastOverflowedIndicatorPlaceholder, 'display', 'none');
    });

    _defineProperty(_assertThisInitialized(_this), "resizeObserver", null);

    _defineProperty(_assertThisInitialized(_this), "mutationObserver", null);

    _defineProperty(_assertThisInitialized(_this), "originalTotalWidth", 0);

    _defineProperty(_assertThisInitialized(_this), "overflowedItems", []);

    _defineProperty(_assertThisInitialized(_this), "menuItemSizes", []);

    _defineProperty(_assertThisInitialized(_this), "handleResize", function () {
      if (_this.props.mode !== 'horizontal') {
        return;
      }

      var ul = ReactDOM.findDOMNode(_assertThisInitialized(_this));

      if (!ul) {
        return;
      }

      var width = getWidth(ul);
      _this.overflowedItems = [];
      var currentSumWidth = 0; // index for last visible child in horizontal mode

      var lastVisibleIndex = undefined;

      if (_this.originalTotalWidth > width) {
        lastVisibleIndex = -1;

        _this.menuItemSizes.forEach(function (liWidth) {
          currentSumWidth += liWidth;

          if (currentSumWidth + _this.overflowedIndicatorWidth <= width) {
            lastVisibleIndex++;
          }
        });
      }

      _this.setState({
        lastVisibleIndex: lastVisibleIndex
      });
    });

    return _this;
  }

  _createClass(DOMWrap, [{
    key: "componentDidMount",
    value: function componentDidMount() {
      var _this2 = this;

      this.setChildrenWidthAndResize();

      if (this.props.level === 1 && this.props.mode === 'horizontal') {
        var menuUl = ReactDOM.findDOMNode(this);

        if (!menuUl) {
          return;
        }

        this.resizeObserver = new ResizeObserver(function (entries) {
          entries.forEach(_this2.setChildrenWidthAndResize);
        });
        [].slice.call(menuUl.children).concat(menuUl).forEach(function (el) {
          _this2.resizeObserver.observe(el);
        });

        if (typeof MutationObserver !== 'undefined') {
          this.mutationObserver = new MutationObserver(function () {
            _this2.resizeObserver.disconnect();

            [].slice.call(menuUl.children).concat(menuUl).forEach(function (el) {
              _this2.resizeObserver.observe(el);
            });

            _this2.setChildrenWidthAndResize();
          });
          this.mutationObserver.observe(menuUl, {
            attributes: false,
            childList: true,
            subTree: false
          });
        }
      }
    }
  }, {
    key: "componentWillUnmount",
    value: function componentWillUnmount() {
      if (this.resizeObserver) {
        this.resizeObserver.disconnect();
      }

      if (this.mutationObserver) {
        this.resizeObserver.disconnect();
      }
    } // get all valid menuItem nodes

  }, {
    key: "renderChildren",
    value: function renderChildren(children) {
      var _this3 = this;

      // need to take care of overflowed items in horizontal mode
      var lastVisibleIndex = this.state.lastVisibleIndex;
      return (children || []).reduce(function (acc, childNode, index) {
        var item = childNode;

        if (_this3.props.mode === 'horizontal') {
          var overflowed = _this3.getOverflowedSubMenuItem(childNode.props.eventKey, []);

          if (lastVisibleIndex !== undefined && _this3.props.className.indexOf("".concat(_this3.props.prefixCls, "-root")) !== -1) {
            if (index > lastVisibleIndex) {
              item = /*#__PURE__*/cloneElement(childNode, // 这里修改 eventKey 是为了防止隐藏状态下还会触发 openkeys 事件
              {
                style: {
                  display: 'none'
                },
                eventKey: "".concat(childNode.props.eventKey, "-hidden"),
                className: "".concat(childNode.className, " ").concat(MENUITEM_OVERFLOWED_CLASSNAME)
              });
            }

            if (index === lastVisibleIndex + 1) {
              _this3.overflowedItems = children.slice(lastVisibleIndex + 1).map(function (c) {
                return /*#__PURE__*/cloneElement(c, // children[index].key will become '.$key' in clone by default,
                // we have to overwrite with the correct key explicitly
                {
                  key: c.props.eventKey,
                  mode: 'vertical-left'
                });
              });
              overflowed = _this3.getOverflowedSubMenuItem(childNode.props.eventKey, _this3.overflowedItems);
            }
          }

          var ret = [].concat(_toConsumableArray(acc), [overflowed, item]);

          if (index === children.length - 1) {
            // need a placeholder for calculating overflowed indicator width
            ret.push(_this3.getOverflowedSubMenuItem(childNode.props.eventKey, [], true));
          }

          return ret;
        }

        return [].concat(_toConsumableArray(acc), [item]);
      }, []);
    }
  }, {
    key: "render",
    value: function render() {
      var _this$props2 = this.props,
          hiddenClassName = _this$props2.hiddenClassName,
          hidden = _this$props2.hidden,
          prefixCls = _this$props2.prefixCls,
          overflowedIndicator = _this$props2.overflowedIndicator,
          mode = _this$props2.mode,
          level = _this$props2.level,
          Tag = _this$props2.tag,
          children = _this$props2.children,
          theme = _this$props2.theme,
          rest = _objectWithoutProperties(_this$props2, _excluded2);

      if (hidden) {
        rest.className += " ".concat(hiddenClassName);
      }

      return /*#__PURE__*/React.createElement(Tag, rest, this.renderChildren(this.props.children));
    }
  }]);

  return DOMWrap;
}(Component);

_defineProperty(DOMWrap, "defaultProps", {
  tag: 'div',
  className: ''
});

export { DOMWrap as default };
//# sourceMappingURL=DOMWrap.js.map
