"use strict";

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

var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");

exports.__esModule = true;
exports.default = exports.dropdownMenuPropTypes = void 0;

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

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

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

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

var _isUndefined = _interopRequireDefault(require("lodash/isUndefined"));

var _isString = _interopRequireDefault(require("lodash/isString"));

var _isNumber = _interopRequireDefault(require("lodash/isNumber"));

var _findIndex = _interopRequireDefault(require("lodash/findIndex"));

var _domLib = require("dom-lib");

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

var _VirtualizedList = require("./VirtualizedList");

var _shallowEqual = _interopRequireDefault(require("../utils/shallowEqual"));

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

var _DropdownMenuGroup = _interopRequireDefault(require("./DropdownMenuGroup"));

var _getDataGroupBy = require("../utils/getDataGroupBy");

var _this = void 0;

var DropdownMenu = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
  var _props$data = props.data,
      data = _props$data === void 0 ? [] : _props$data,
      group = props.group,
      _props$maxHeight = props.maxHeight,
      maxHeight = _props$maxHeight === void 0 ? 320 : _props$maxHeight,
      _props$activeItemValu = props.activeItemValues,
      activeItemValues = _props$activeItemValu === void 0 ? [] : _props$activeItemValu,
      _props$disabledItemVa = props.disabledItemValues,
      disabledItemValues = _props$disabledItemVa === void 0 ? [] : _props$disabledItemVa,
      _props$classPrefix = props.classPrefix,
      classPrefix = _props$classPrefix === void 0 ? 'dropdown-menu' : _props$classPrefix,
      _props$valueKey = props.valueKey,
      valueKey = _props$valueKey === void 0 ? 'value' : _props$valueKey,
      _props$labelKey = props.labelKey,
      labelKey = _props$labelKey === void 0 ? 'label' : _props$labelKey,
      virtualized = props.virtualized,
      listProps = props.listProps,
      className = props.className,
      style = props.style,
      focusItemValue = props.focusItemValue,
      dropdownMenuItemClassPrefix = props.dropdownMenuItemClassPrefix,
      DropdownMenuItem = props.dropdownMenuItemAs,
      _props$rowHeight = props.rowHeight,
      rowHeight = _props$rowHeight === void 0 ? 36 : _props$rowHeight,
      _props$rowGroupHeight = props.rowGroupHeight,
      rowGroupHeight = _props$rowGroupHeight === void 0 ? 48 : _props$rowGroupHeight,
      renderMenuGroup = props.renderMenuGroup,
      renderMenuItem = props.renderMenuItem,
      onGroupTitleClick = props.onGroupTitleClick,
      onSelect = props.onSelect,
      rest = (0, _objectWithoutPropertiesLoose2.default)(props, ["data", "group", "maxHeight", "activeItemValues", "disabledItemValues", "classPrefix", "valueKey", "labelKey", "virtualized", "listProps", "className", "style", "focusItemValue", "dropdownMenuItemClassPrefix", "dropdownMenuItemAs", "rowHeight", "rowGroupHeight", "renderMenuGroup", "renderMenuItem", "onGroupTitleClick", "onSelect"]);

  var _useClassNames = (0, _utils.useClassNames)(classPrefix),
      withClassPrefix = _useClassNames.withClassPrefix,
      prefix = _useClassNames.prefix,
      merge = _useClassNames.merge;

  var classes = merge(className, withClassPrefix('items', {
    grouped: group
  }));
  var styles = (0, _extends2.default)({}, style, {
    maxHeight: maxHeight
  });
  var menuBodyContainerRef = (0, _react.useRef)();

  var _useState = (0, _react.useState)([]),
      foldedGroupKeys = _useState[0],
      setFoldedGroupKeys = _useState[1];

  var handleGroupTitleClick = (0, _react.useCallback)(function (key, event) {
    var nextGroupKeys = foldedGroupKeys.filter(function (item) {
      return item !== key;
    });

    if (nextGroupKeys.length === foldedGroupKeys.length) {
      nextGroupKeys.push(key);
    }

    setFoldedGroupKeys(nextGroupKeys);
    onGroupTitleClick === null || onGroupTitleClick === void 0 ? void 0 : onGroupTitleClick(event);
  }, [onGroupTitleClick, foldedGroupKeys]);
  var handleSelect = (0, _react.useCallback)(function (item, value, event, checked) {
    onSelect === null || onSelect === void 0 ? void 0 : onSelect(value, item, event, checked);
  }, [onSelect]);

  var getRowHeight = function getRowHeight(list, _ref) {
    var index = _ref.index;
    var item = list[index];

    if (group && item[_getDataGroupBy.KEY_GROUP] && index !== 0) {
      return rowGroupHeight;
    }

    return rowHeight;
  };

  (0, _react.useEffect)(function () {
    var container = menuBodyContainerRef.current;
    var activeItem = container.querySelector("." + prefix('item-focus'));

    if (!activeItem) {
      activeItem = container.querySelector("." + prefix('item-active'));
    }

    if (!activeItem) {
      return;
    }

    var position = (0, _domLib.getPosition)(activeItem, container);
    var sTop = (0, _domLib.scrollTop)(container);
    var sHeight = (0, _domLib.getHeight)(container);

    if (sTop > position.top) {
      (0, _domLib.scrollTop)(container, Math.max(0, position.top - 20));
    } else if (position.top > sTop + sHeight) {
      (0, _domLib.scrollTop)(container, Math.max(0, position.top - sHeight + 32));
    }
  }, [focusItemValue, menuBodyContainerRef, prefix]);

  var renderItem = function renderItem(list, _ref2) {
    var index = _ref2.index,
        style = _ref2.style;
    var item = list[index];
    var value = item[valueKey];
    var label = item[labelKey];

    if ((0, _isUndefined.default)(label) && !item[_getDataGroupBy.KEY_GROUP]) {
      throw Error("labelKey \"" + labelKey + "\" is not defined in \"data\" : " + index);
    } // Use `value` in keys when If `value` is string or number


    var itemKey = (0, _isString.default)(value) || (0, _isNumber.default)(value) ? value : index;
    /**
     * Render <DropdownMenuGroup>
     * when if `group` is enabled
     */

    if (group && item[_getDataGroupBy.KEY_GROUP]) {
      var groupValue = item[_getDataGroupBy.KEY_GROUP_TITLE];
      return /*#__PURE__*/_react.default.createElement(_DropdownMenuGroup.default, {
        style: style,
        classPrefix: 'picker-menu-group',
        className: (0, _classnames.default)({
          folded: foldedGroupKeys.some(function (key) {
            return key === groupValue;
          })
        }),
        key: "group-" + groupValue,
        onClick: handleGroupTitleClick.bind(null, groupValue)
      }, renderMenuGroup ? renderMenuGroup(groupValue, item) : groupValue);
    } else if ((0, _isUndefined.default)(value) && !(0, _isUndefined.default)(item[_getDataGroupBy.KEY_GROUP])) {
      throw Error("valueKey \"" + valueKey + "\" is not defined in \"data\" : " + index + " ");
    }

    var disabled = disabledItemValues === null || disabledItemValues === void 0 ? void 0 : disabledItemValues.some(function (disabledValue) {
      return (0, _shallowEqual.default)(disabledValue, value);
    });
    var active = activeItemValues === null || activeItemValues === void 0 ? void 0 : activeItemValues.some(function (v) {
      return (0, _shallowEqual.default)(v, value);
    });
    var focus = !(0, _isUndefined.default)(focusItemValue) && (0, _shallowEqual.default)(focusItemValue, value);
    return /*#__PURE__*/_react.default.createElement(DropdownMenuItem, {
      style: style,
      key: itemKey,
      disabled: disabled,
      active: active,
      focus: focus,
      value: value,
      classPrefix: dropdownMenuItemClassPrefix,
      onSelect: handleSelect.bind(null, item)
    }, renderMenuItem ? renderMenuItem(label, item) : label);
  };

  var filteredItems = group ? data.filter(function (item) {
    return !(foldedGroupKeys === null || foldedGroupKeys === void 0 ? void 0 : foldedGroupKeys.some(function (key) {
      var _item$parent;

      return key === ((_item$parent = item.parent) === null || _item$parent === void 0 ? void 0 : _item$parent[_getDataGroupBy.KEY_GROUP_TITLE]);
    }));
  }) : data;
  var rowCount = filteredItems.length; // Check whether the height of the data exceeds the height of the container.

  var useVirtualized = virtualized && rowCount * rowHeight > maxHeight;
  return /*#__PURE__*/_react.default.createElement("div", (0, _extends2.default)({
    role: !useVirtualized ? 'listbox' : null
  }, rest, {
    className: classes,
    ref: (0, _utils.mergeRefs)(menuBodyContainerRef, ref),
    style: styles
  }), useVirtualized ? /*#__PURE__*/_react.default.createElement(_VirtualizedList.AutoSizer, {
    defaultHeight: maxHeight,
    style: {
      width: 'auto',
      height: 'auto'
    }
  }, function (_ref3) {
    var height = _ref3.height,
        width = _ref3.width;
    return /*#__PURE__*/_react.default.createElement(_VirtualizedList.List, (0, _extends2.default)({
      role: "listbox",
      containerRole: '',
      "aria-readonly": null
    }, listProps, {
      width: width,
      height: height || maxHeight,
      scrollToIndex: (0, _findIndex.default)(data, function (item) {
        return item[valueKey] === (activeItemValues === null || activeItemValues === void 0 ? void 0 : activeItemValues[0]);
      }),
      rowCount: rowCount,
      rowHeight: getRowHeight.bind(_this, filteredItems),
      rowRenderer: renderItem.bind(null, filteredItems)
    }));
  }) : filteredItems.map(function (_item, index) {
    return renderItem(filteredItems, {
      index: index
    });
  }));
});

var dropdownMenuPropTypes = {
  classPrefix: _propTypes.default.string,
  className: _propTypes.default.string,
  dropdownMenuItemAs: _propTypes.default.elementType,
  dropdownMenuItemClassPrefix: _propTypes.default.string,
  data: _propTypes.default.array,
  group: _propTypes.default.bool,
  disabledItemValues: _propTypes.default.array,
  activeItemValues: _propTypes.default.array,
  focusItemValue: _propTypes.default.any,
  maxHeight: _propTypes.default.number,
  valueKey: _propTypes.default.string,
  labelKey: _propTypes.default.string,
  style: _propTypes.default.object,
  renderMenuItem: _propTypes.default.func,
  renderMenuGroup: _propTypes.default.func,
  onSelect: _propTypes.default.func,
  onGroupTitleClick: _propTypes.default.func,
  virtualized: _propTypes.default.bool,
  listProps: _propTypes.default.any,
  rowHeight: _propTypes.default.number,
  rowGroupHeight: _propTypes.default.number
};
exports.dropdownMenuPropTypes = dropdownMenuPropTypes;
DropdownMenu.displayName = 'DropdownMenu';
DropdownMenu.propTypes = dropdownMenuPropTypes;
var _default = DropdownMenu;
exports.default = _default;