'use strict';

import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
import _extends from "@babel/runtime/helpers/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose";
import _inheritsLoose from "@babel/runtime/helpers/inheritsLoose";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import { findDOMNode } from 'react-dom';
import Store from '../../data/Store';
import { FormGroup } from './FormGroup';
import { FormControl } from './FormControl';
import { Checkbox } from './Checkbox';
import { Filter } from '../Filter';
import { Icon } from '../Icon';
import { Tooltip } from '../Tooltip';
import React from 'react';
import PropTypes from 'prop-types';
import Dropdown from 'react-bootstrap/lib/Dropdown';
import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger';
import _ from 'lodash';
import classnames from 'classnames';
import { highlight } from '../list/utils';
import { translate } from '../../../utils';
import { FocusHelper } from '../../utils/FocusHelper';
import { KeyNames } from '../../../utils/constants';
var FC = FormControl;

var doNothing = function doNothing() {};

var MultiSelectField =
/*#__PURE__*/
function (_FormGroup) {
  _inheritsLoose(MultiSelectField, _FormGroup);

  function MultiSelectField() {
    return _FormGroup.apply(this, arguments) || this;
  }

  var _proto = MultiSelectField.prototype;

  _proto.renderInput = function renderInput() {
    var _this$getPropsFromCon = this.getPropsFromContext(),
        children = _this$getPropsFromCon.children,
        innerLabel = _this$getPropsFromCon.innerLabel,
        props = _objectWithoutPropertiesLoose(_this$getPropsFromCon, ["children", "innerLabel"]);

    return React.createElement(MultiSelect, _extends({}, props, {
      label: innerLabel,
      ref: "control",
      hasFormGroupContainer: true
    }), children);
  };

  return MultiSelectField;
}(FormGroup);

_defineProperty(MultiSelectField, "propTypes", Object.assign({}, FormGroup.propTypes));

_defineProperty(MultiSelectField, "defaultProps", Object.assign({}, FormGroup.defaultProps, {
  testAutomationId: 'multiSelect'
}));

var multiSelectInstanceCounter = 0;

var MultiSelectOption =
/*#__PURE__*/
function (_React$Component) {
  _inheritsLoose(MultiSelectOption, _React$Component);

  MultiSelectOption.compareOptionValue = function compareOptionValue(source) {
    if (_.isObject(source)) {
      return _.matches(source);
    }

    return function (value) {
      return value === source;
    };
  };

  function MultiSelectOption(props, context) {
    var _this;

    _this = _React$Component.call(this, props, context) || this;
    _this.handleKeyDown = _this.handleKeyDown.bind(_assertThisInitialized(_this));
    return _this;
  }

  var _proto2 = MultiSelectOption.prototype;

  _proto2.getChildContext = function getChildContext() {
    var _this2 = this;

    return {
      getOptionIdPrefix: function getOptionIdPrefix() {
        return _this2.getId();
      }
    };
  };

  _proto2.handleKeyDown = function handleKeyDown(event) {
    switch (event.keyCode) {
      case 13: // enter

      case 32:
        // space
        this.refs.control.click();
        event.preventDefault();
        break;

      default:
        this.props.onKeyDown(event);
    }
  };

  _proto2.getId = function getId() {
    if (!_.isFunction(this.context.getOptionIdPrefix)) {
      return null;
    }

    return this.context.getOptionIdPrefix() + "_" + (this.props.groupMaster ? 'masterOption' : 'option') + "_" + this.props.ariaPosition;
  };

  _proto2.finalRender = function finalRender(props, content) {
    if (_.isFunction(this.props.tagRenderer)) {
      return this.props.tagRenderer(props, content);
    }

    return content;
  };

  _proto2.render = function render() {
    var _this3 = this;

    var _this$props = this.props,
        hint = _this$props.hint,
        description = _this$props.description;
    var values = this.context.multiSelect.values;
    var filterCallback = this.context.multiSelect.filterCallback;
    var isSelected = false;
    var isMaster = this.props.groupMaster;
    var isOptionDisabled = !!(isMaster && this.context.multiSelect.isSingleSelectMode && this.props.value === undefined) || this.props.disabled;
    var optionValues = [];

    if (!isMaster) {
      optionValues = [this.props.value];

      var index = _.findIndex(values, MultiSelectOption.compareOptionValue(this.props.value));

      isSelected = index > -1; // Skip not matched options

      if (!filterCallback(this.props.label, this.props.value)) {
        return null;
      }
    } else {
      optionValues = this.context.multiSelectGroup.values;
      var selectedValuesCount = 0;
      var groupFilteredLabels = this.context.multiSelectGroup.filteredLabels;
      optionValues.forEach(function (value) {
        var index = _.findIndex(values, MultiSelectOption.compareOptionValue(value));

        if (index > -1) {
          selectedValuesCount++;
        }
      });

      if (selectedValuesCount > 0) {
        isSelected = selectedValuesCount === optionValues.length ? true : null;
      } // Skip not matched groups


      if (!filterCallback(this.props.label, this.props.value) && !groupFilteredLabels.length) {
        return null;
      }
    }

    var highlightedLabelText = this.props.customLabel || highlight(this.context.multiSelect.filterRegExp, this.props.label);
    var icon = this.props.icon;
    var content;
    var labelTitle = !description ? this.props.label : this.props.label + " - " + description;
    var label = React.createElement("span", {
      title: hint ? null : labelTitle
    }, highlightedLabelText, description ? React.createElement("span", {
      className: "select-description"
    }, " - ", description) : null);

    if (this.context.multiSelect.isSingleSelectMode) {
      isSelected = this.props.value !== undefined && MultiSelectOption.compareOptionValue(this.props.value)(values[0]);

      var onClick = function onClick(event) {
        if (_this3.props.value !== undefined) {
          _this3.context.multiSelect.setValues([_this3.props.value]);
        }

        _this3.context.multiSelect.close();
      };

      var labelProps = {
        className: classnames('option-label', this.props.labelClassName, {
          'selected-option': isSelected
        }),
        ref: 'control'
      };

      if (!isOptionDisabled) {
        labelProps.onClick = onClick;
      }

      content = React.createElement("span", labelProps, isSelected ? React.createElement(Icon, {
        "aria-hidden": "true",
        name: "checkbox-selected-readonly"
      }) : null, label, React.createElement("div", {
        className: "icon-wrapper",
        "aria-hidden": "true"
      }, icon ? React.createElement(Icon, {
        name: icon
      }) : null));
    } else {
      content = React.createElement(Checkbox, {
        ref: "control",
        label: label,
        labelClassName: this.props.labelClassName,
        checked: isSelected,
        "aria-hidden": true,
        "aria-checked": isSelected === null ? 'mixed' : isSelected,
        disabled: isOptionDisabled,
        onChange: function onChange(value) {
          var isSelected = _this3.refs.control.getValue();

          var newValues = values.filter(function (value) {
            return _.findIndex(optionValues, MultiSelectOption.compareOptionValue(value)) === -1;
          });

          if (isSelected) {
            newValues = values.concat(optionValues);
          }

          _this3.context.multiSelect.setValues(newValues);
        }
      });
    }

    var optionId = this.getId();
    var liProps = {
      id: optionId,
      'data-test-automation-id': this.props.testAutomationId || 'option' + this.context.multiSelect.uid(),
      className: classnames("multi-select-option multi-select-option-level-" + this.props.ariaLevel, this.props.className, {
        'master-option': isMaster,
        'option-disabled': isOptionDisabled
      }),
      role: 'treeitem',
      'aria-level': this.props.ariaLevel,
      'aria-setsize': this.props.ariaSetSize,
      'aria-posinset': this.props.ariaPosition
    };

    if (!isOptionDisabled) {
      liProps.tabIndex = '-1';
      liProps.onKeyDown = this.handleKeyDown;
      liProps.onSelect = this.props.onSelect;
      liProps['aria-selected'] = isSelected === true;

      liProps.onFocus = function () {
        if (_.isFunction(_this3.context.setAriaActivedescendant)) {
          _this3.context.setAriaActivedescendant(optionId);
        }
      };
    }

    var finalContent = hint ? React.createElement(OverlayTrigger, {
      overlay: React.createElement(Tooltip, null, hint)
    }, content) : this.finalRender(liProps, content);
    return React.createElement("li", liProps, finalContent);
  };

  return MultiSelectOption;
}(React.Component);

_defineProperty(MultiSelectOption, "contextTypes", {
  multiSelect: PropTypes.object,
  multiSelectGroup: PropTypes.object,
  getOptionIdPrefix: PropTypes.func,
  setAriaActivedescendant: PropTypes.func
});

_defineProperty(MultiSelectOption, "childContextTypes", {
  getOptionIdPrefix: PropTypes.func
});

_defineProperty(MultiSelectOption, "propTypes", {
  className: PropTypes.string,
  disabled: PropTypes.bool,
  groupMaster: PropTypes.bool,
  icon: PropTypes.string,
  label: PropTypes.string.isRequired,
  labelClassName: PropTypes.string,
  onKeyDown: PropTypes.func,
  onSelect: PropTypes.func,
  testAutomationId: PropTypes.string,
  value: PropTypes.any.isRequired,
  ariaPosition: PropTypes.number,
  ariaLevel: PropTypes.number,
  ariaSetSize: PropTypes.number,
  hint: PropTypes.string,
  customLabel: PropTypes.any,
  tagRenderer: PropTypes.func,
  description: PropTypes.string
});

_defineProperty(MultiSelectOption, "defaultProps", {
  className: null,
  disabled: false,
  groupMaster: false,
  icon: '',
  labelClassName: '',
  onKeyDown: doNothing,
  onSelect: doNothing,
  testAutomationId: null,
  ariaPosition: null,
  ariaLevel: null,
  ariaSetSize: null,
  hint: null,
  customLabel: null,
  tagRenderer: null,
  description: null
});

var MultiSelectMasterOptionWrapper =
/*#__PURE__*/
function (_React$Component2) {
  _inheritsLoose(MultiSelectMasterOptionWrapper, _React$Component2);

  function MultiSelectMasterOptionWrapper() {
    var _this4;

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

    _this4 = _React$Component2.call.apply(_React$Component2, [this].concat(args)) || this;

    _defineProperty(_assertThisInitialized(_this4), "tagRenderer", function (props, content) {
      return React.createElement("div", {
        id: _this4.props.groupLabelId
      }, content);
    });

    return _this4;
  }

  var _proto3 = MultiSelectMasterOptionWrapper.prototype;

  _proto3.getTestAutomationId = function getTestAutomationId() {
    var testAutomationId = this.props.testAutomationId;
    var multiSelect = this.context.multiSelect;

    if (testAutomationId) {
      return testAutomationId;
    }

    return "optionMaster" + multiSelect.uid();
  };

  _proto3.render = function render() {
    return React.createElement(MultiSelectOption, _extends({}, this.props, {
      testAutomationId: this.getTestAutomationId(),
      tagRenderer: this.tagRenderer,
      groupMaster: true
    }));
  };

  return MultiSelectMasterOptionWrapper;
}(React.Component);

_defineProperty(MultiSelectMasterOptionWrapper, "propTypes", Object.assign({}, MultiSelectOption.propTypes, {
  testAutomationId: PropTypes.string,
  groupLabelId: PropTypes.string.isRequired
}));

_defineProperty(MultiSelectMasterOptionWrapper, "defaultProps", Object.assign({}, MultiSelectOption.defaultProps, {
  testAutomationId: null
}));

_defineProperty(MultiSelectMasterOptionWrapper, "contextTypes", {
  multiSelect: PropTypes.object
});

var MultiSelectMasterOption =
/*#__PURE__*/
function (_React$Component3) {
  _inheritsLoose(MultiSelectMasterOption, _React$Component3);

  function MultiSelectMasterOption() {
    return _React$Component3.apply(this, arguments) || this;
  }

  var _proto4 = MultiSelectMasterOption.prototype;

  _proto4.render = function render() {
    return null;
  };

  return MultiSelectMasterOption;
}(React.Component);

_defineProperty(MultiSelectMasterOption, "propTypes", Object.assign({}, MultiSelectOption.propTypes));

function getChildrenValues(children) {
  return _.flatten(React.Children.toArray(children).filter(function (child) {
    return child.type === MultiSelectOption && !child.props.groupMaster || child.type === MultiSelectOptionGroup;
  }).map(function (child) {
    if (child.type === MultiSelectOption) {
      return child.props.value;
    } else {
      return getChildrenValues(child.props.children);
    }
  }));
}

function hasValueChild(children) {
  var items = React.Children.toArray(children);
  var hasValue = items.some(function (o) {
    return o && o.props && o.props.value !== undefined;
  });

  if (hasValue) {
    return true;
  }

  for (var _iterator = items, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
    var _ref;

    if (_isArray) {
      if (_i >= _iterator.length) break;
      _ref = _iterator[_i++];
    } else {
      _i = _iterator.next();
      if (_i.done) break;
      _ref = _i.value;
    }

    var child = _ref;

    if (child && child.props && child.props.children && hasValueChild(child.props.children)) {
      return true;
    }
  }

  return false;
}

function getChildrenLabels(children, filterCallback) {
  return _.flatten(React.Children.toArray(children).filter(function (child) {
    if (child.type === MultiSelectOption || child.type === MultiSelectMasterOption) {
      if (filterCallback && !filterCallback(child.props.label, child.props.value)) {
        return false;
      }

      return true;
    } else if (child.type === MultiSelectOptionGroup) {
      return true;
    }
  }).map(function (child) {
    if (child.type === MultiSelectOption || child.type === MultiSelectMasterOption) {
      return child.props.label;
    } else {
      return getChildrenLabels(child.props.children, filterCallback);
    }
  }));
}

function getGroupValueOptionSize(children) {
  return _.filter(React.Children.toArray(children), function (o) {
    return !isMasterOption(o);
  }).map(function (o) {
    return o.key;
  }).length;
}

function isMasterOption(node) {
  return node && node.type === MultiSelectMasterOption;
}

var TreeItemAriaProps = ['aria-selected', 'aria-level', 'aria-setsize', 'aria-posinset', 'role'];

var MultiSelectOptionGroup =
/*#__PURE__*/
function (_React$Component4) {
  _inheritsLoose(MultiSelectOptionGroup, _React$Component4);

  function MultiSelectOptionGroup() {
    var _this5;

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

    _this5 = _React$Component4.call.apply(_React$Component4, [this].concat(args)) || this;

    _defineProperty(_assertThisInitialized(_this5), "getOptionId", function () {
      if (_.isFunction(_this5.context.getOptionIdPrefix)) {
        return _this5.context.getOptionIdPrefix() + "_" + _this5.props.ariaPosition;
      }

      return null;
    });

    _defineProperty(_assertThisInitialized(_this5), "getMasterOptionWrapperProps", function (props) {
      return _.omit(props, TreeItemAriaProps);
    });

    return _this5;
  }

  var _proto5 = MultiSelectOptionGroup.prototype;

  _proto5.getChildContext = function getChildContext() {
    return {
      multiSelectGroup: {
        values: getChildrenValues(this.props.children),
        filteredLabels: getChildrenLabels(this.props.children, this.context.multiSelect.filterCallback)
      },
      getOptionIdPrefix: this.getOptionId
    };
  };

  _proto5.getSiblingOptionSize = function getSiblingOptionSize() {
    return getGroupValueOptionSize(this.props.children);
  };

  _proto5.getGroupProps = function getGroupProps(props) {
    if (_.isEmpty(props)) {
      return null;
    }

    return _.pick(props, TreeItemAriaProps);
  };

  _proto5.render = function render() {
    var _this6 = this;

    var children = React.Children.toArray(this.props.children);
    var hasMaster = false;
    var items = children.map(function (child, index) {
      var childProps = child.props || {};
      var isMasterNode = isMasterOption(child);

      if (isMasterNode) {
        hasMaster = true;
      }

      var ariaPosition = hasMaster ? index : index + 1;
      return React.cloneElement(child, {
        ariaPosition: isMasterNode ? _this6.props.ariaPosition : ariaPosition,
        ariaLevel: _this6.props.ariaLevel + (isMasterNode ? 0 : 1),
        ariaSetSize: isMasterNode ? _this6.props.ariaSetSize : _this6.getSiblingOptionSize(),
        onKeyDown: _this6.props.onKeyDown,
        onSelect: _this6.props.onSelect
      }, childProps.children);
    });

    var masterItem = _.find(items, isMasterOption);

    var groupLabelId = this.getOptionId() + "_group_node";
    var masterOptionNode = masterItem ? React.createElement(MultiSelectMasterOptionWrapper, _extends({
      groupLabelId: groupLabelId
    }, this.getMasterOptionWrapperProps(masterItem.props))) : null;
    var valueItems = items.filter(function (node) {
      return !isMasterOption(node);
    });
    var hasAvailableValue = hasValueChild(valueItems);
    var groupProps = Object.assign({
      id: this.getOptionId(),
      'data-test-automation-id': this.props.testAutomationId || 'groupOption' + this.context.multiSelect.uid(),
      role: 'treeitem',
      'aria-expanded': true,
      'aria-selected': false
    }, this.getGroupProps(masterItem && masterItem.props));
    groupProps.className = classnames(groupProps.className, {
      'multi-select-has-children': !_.isEmpty(valueItems)
    });
    return React.createElement("div", groupProps, masterOptionNode, React.createElement("ul", {
      className: classnames('multi-select-group', this.props.className),
      role: hasAvailableValue ? 'group' : null,
      "aria-labelledby": hasAvailableValue && masterItem ? groupLabelId : null
    }, valueItems));
  };

  return MultiSelectOptionGroup;
}(React.Component);

_defineProperty(MultiSelectOptionGroup, "contextTypes", {
  multiSelect: PropTypes.object,
  multiSelectGroup: PropTypes.object,
  getOptionIdPrefix: PropTypes.func
});

_defineProperty(MultiSelectOptionGroup, "childContextTypes", {
  multiSelectGroup: PropTypes.object,
  getOptionIdPrefix: PropTypes.func
});

_defineProperty(MultiSelectOptionGroup, "propTypes", {
  children: PropTypes.node,
  className: PropTypes.string,
  onKeyDown: PropTypes.func,
  onSelect: PropTypes.func,
  testAutomationId: PropTypes.string,
  ariaPosition: PropTypes.number,
  ariaLevel: PropTypes.number,
  ariaSetSize: PropTypes.number
});

_defineProperty(MultiSelectOptionGroup, "defaultProps", {
  children: null,
  className: null,
  onKeyDown: doNothing,
  onSelect: doNothing,
  testAutomationId: null,
  ariaPosition: 1,
  ariaLevel: 1,
  ariaSetSize: 1
});

var MultiSelectDefaultAutomationId = 'multiSelect';
export var MultiSelect =
/*#__PURE__*/
function (_FormControl) {
  _inheritsLoose(MultiSelect, _FormControl);

  // extends defaultProps from superclass
  function MultiSelect(_props, context) {
    var _this7;

    _this7 = _FormControl.call(this, _props, context) || this;

    _defineProperty(_assertThisInitialized(_this7), "focusHelper", new FocusHelper());

    _defineProperty(_assertThisInitialized(_this7), "saveMultiSelectRef", function (ref) {
      _this7.multiSelectEle = findDOMNode(ref);
    });

    _defineProperty(_assertThisInitialized(_this7), "focus", function () {
      _this7.focusHelper.focus();
    });

    _defineProperty(_assertThisInitialized(_this7), "getTitle", function (selectedItemLabels) {
      if (_.isEmpty(selectedItemLabels)) {
        return null;
      }

      var _this7$props = _this7.props,
          label = _this7$props.label,
          selectedValuesPrefix = _this7$props.selectedValuesPrefix;
      var valueStr = selectedItemLabels.join(', ');

      if (!_this7.shouldApplyLabelPrefix()) {
        return valueStr;
      }

      return translate(selectedValuesPrefix, {
        filterName: label,
        values: valueStr
      });
    });

    _defineProperty(_assertThisInitialized(_this7), "getAriaLabel", function () {
      var _this7$props2 = _this7.props,
          label = _this7$props2.label,
          toggleAriaLabel = _this7$props2.toggleAriaLabel;

      if (!_this7.shouldApplyLabelPrefix()) {
        return label;
      }

      return translate(toggleAriaLabel, {
        filterName: label
      });
    });

    _defineProperty(_assertThisInitialized(_this7), "getDisplayLabel", function (selectedItems) {
      var _this7$props3 = _this7.props,
          label = _this7$props3.label,
          labelItemsLimit = _this7$props3.labelItemsLimit;

      if (_.isEmpty(selectedItems)) {
        return label;
      }

      var valueString = selectedItems.join(', ');

      if (selectedItems.length > labelItemsLimit) {
        valueString = selectedItems.slice(0, labelItemsLimit).concat(['...']).join(', ');
      }

      return _this7.shouldApplyLabelPrefix() ? label + ": " + valueString : valueString;
    });

    _defineProperty(_assertThisInitialized(_this7), "getSelectedItemLabels", function () {
      var children = _this7.props.children;

      var props = _this7.getPropsFromContext();

      var values = toArray(props.value);
      return getChildrenLabels(children, function (label, value) {
        return _.findIndex(values, MultiSelectOption.compareOptionValue(value)) > -1;
      });
    });

    _this7.onToggle = _this7.onToggle.bind(_assertThisInitialized(_this7));
    _this7.onKeyDown = _this7.onKeyDown.bind(_assertThisInitialized(_this7));
    _this7.showMore = _this7.showMore.bind(_assertThisInitialized(_this7));
    _this7.filterByLimit = _this7.filterByLimit.bind(_assertThisInitialized(_this7));
    _this7.filterByLabelAndLimit = _this7.filterByLabelAndLimit.bind(_assertThisInitialized(_this7));
    _this7.listItemsFilteredByLimit = [];
    _this7.listItemsFiltered = [];
    _this7.state = {
      filterText: '',
      filterRegExp: null,
      filterCallback: _this7.filterByLimit,
      isOpen: false,
      isMoreShowed: false,
      hasFilterFocus: false,
      ariaActivedescendant: null
    };
    _this7.instanceId = ++multiSelectInstanceCounter;
    return _this7;
  }

  var _proto6 = MultiSelect.prototype;

  _proto6.componentDidMount = function componentDidMount() {
    var _this8 = this;

    this.multiSelectEle.addEventListener('keydown', function (event) {
      if (_this8.state.isOpen && event.key === KeyNames.Escape) {
        event.stopPropagation();
      }
    });
  };

  _proto6.filterByLimit = function filterByLimit(label, value) {
    if (!(this.props.listItemsLimit > 0)) {
      return true;
    }

    if (this.state.isMoreShowed) {
      return true;
    }

    var validValue = typeof value !== 'undefined'; // Calculate all visible options

    if (validValue && this.listItemsFiltered.indexOf(value) === -1) {
      this.listItemsFiltered.push(value);
    }

    if (this.listItemsFilteredByLimit.length < this.props.listItemsLimit) {
      if (validValue && this.listItemsFilteredByLimit.indexOf(value) === -1) {
        this.listItemsFilteredByLimit.push(value);
      }

      return true;
    }

    return this.listItemsFilteredByLimit.indexOf(value) !== -1;
  };

  _proto6.filterByLabelAndLimit = function filterByLabelAndLimit(label, value) {
    var filterRegExp = this.state.filterRegExp;

    if (filterRegExp === null) {
      return this.filterByLimit(label, value);
    } else {
      filterRegExp.lastIndex = 0;
      return filterRegExp.test(label) && this.filterByLimit(label, value);
    }
  };

  _proto6.outputConverter = function outputConverter(e) {
    return e;
  };

  _proto6.getValue = function getValue() {
    //FIXME Not implemented
    return null;
  };

  _proto6.getChildContext = function getChildContext() {
    var _this9 = this;

    var props = this.getPropsFromContext();
    return {
      multiSelect: {
        uid: function uid() {
          return ++_this9.uid;
        },
        values: toArray(props.value),
        setValues: function setValues(values) {
          if (_this9.props.isSingleSelect) {
            values = values[0];
          }

          props.onChange(values);
        },
        filterCallback: this.state.filterCallback,
        filterRegExp: this.state.filterRegExp,
        isSingleSelectMode: this.props.isSingleSelect,
        close: function close() {
          _this9.setState({
            isOpen: false
          });
        }
      },
      level: 0,
      getOptionIdPrefix: function getOptionIdPrefix() {
        return "select_" + _this9.instanceId;
      },
      setAriaActivedescendant: function setAriaActivedescendant(ariaActivedescendant) {
        return _this9.setState({
          ariaActivedescendant: ariaActivedescendant
        });
      }
    };
  };

  _proto6.onToggle = function onToggle(isOpen) {
    this.uid = 0;

    if (!isOpen && this.state.hasFilterFocus) {
      isOpen = true;
    }

    this.setState({
      isOpen: isOpen
    });
  };

  _proto6.onKeyDown = function onKeyDown(event) {
    switch (event.key) {
      case 'Escape':
      case 'Tab':
        this.setState({
          isOpen: false
        });
        break;
    }
  };

  _proto6.setTextFilter = function setTextFilter(text) {
    var filterRegExp = Store.searchStringToRegExp(text);
    this.listItemsFiltered = [];
    this.listItemsFilteredByLimit = [];
    this.setState({
      filterText: text,
      filterRegExp: filterRegExp,
      filterCallback: this.filterByLabelAndLimit,
      isMoreShowed: false
    });
  };

  _proto6.showMore = function showMore(event) {
    event.preventDefault();
    this.setState({
      isMoreShowed: true
    });
  };

  _proto6.renderShowMore = function renderShowMore() {
    if (this.state.isMoreShowed) {
      return null;
    }

    var count = this.listItemsFiltered.length - this.listItemsFilteredByLimit.length;

    if (count <= 0) {
      return null;
    }

    return React.createElement("li", {
      role: "menuitem"
    }, React.createElement("a", {
      className: "show-more",
      onClick: this.showMore
    }, translate(this.props.showMoreCountTextTemplate, {
      count: count
    })));
  }
  /** @param {Array<String>} selectedItemLabels */
  ;

  _proto6.shouldApplyLabelPrefix = function shouldApplyLabelPrefix() {
    var _this$props2 = this.props,
        isSingleSelect = _this$props2.isSingleSelect,
        applyLabelPrefixForSingleMode = _this$props2.applyLabelPrefixForSingleMode,
        applyLabelPrefixForMultiMode = _this$props2.applyLabelPrefixForMultiMode;
    return isSingleSelect ? applyLabelPrefixForSingleMode : applyLabelPrefixForMultiMode;
  }
  /** @returns {Array<String>}*/
  ;

  _proto6.render = function render() {
    var _this10 = this;

    this.uid = 0;

    var _this$props3 = this.props,
        id = _this$props3.id,
        isFilterable = _this$props3.isFilterable,
        searchText = _this$props3.searchText,
        noResultsText = _this$props3.noResultsText,
        label = _this$props3.label,
        value = _this$props3.value,
        children = _this$props3.children,
        labelItemsLimit = _this$props3.labelItemsLimit,
        testAutomationId = _this$props3.testAutomationId,
        className = _this$props3.className,
        block = _this$props3.block,
        stretch = _this$props3.stretch,
        listHeader = _this$props3.listHeader,
        listItemsLimit = _this$props3.listItemsLimit,
        showMoreCountTextTemplate = _this$props3.showMoreCountTextTemplate,
        onChange = _this$props3.onChange,
        ariaLabelledById = _this$props3.ariaLabelledById,
        toggleAriaLabel = _this$props3.toggleAriaLabel,
        stretchDropdownMenu = _this$props3.stretchDropdownMenu,
        otherProps = _objectWithoutPropertiesLoose(_this$props3, ["id", "isFilterable", "searchText", "noResultsText", "label", "value", "children", "labelItemsLimit", "testAutomationId", "className", "block", "stretch", "listHeader", "listItemsLimit", "showMoreCountTextTemplate", "onChange", "ariaLabelledById", "toggleAriaLabel", "stretchDropdownMenu"]);

    var filter = null;
    var isNoResults = false;
    var hasChildren = children && (!(children instanceof Array) || children.length);

    if (isFilterable && hasChildren) {
      filter = React.createElement(Filter, {
        value: this.state.filterText,
        testAutomationId: "filter",
        className: "multi-select-filter",
        ref: "filter",
        placeholder: searchText,
        tabIndex: "-1",
        noOffset: true,
        onFocus: function onFocus(event) {
          if (!_this10.state.hasFilterFocus) {
            _this10.refs.filter.focus();

            _this10.setState({
              hasFilterFocus: true
            });
          }
        },
        onBlur: function onBlur(event) {
          return _this10.setState({
            hasFilterFocus: false
          });
        },
        onKeyDown: function onKeyDown(event) {
          if (['ArrowUp', 'ArrowDown', 'Escape', 'Tab'].indexOf(event.key) === -1) {
            event.stopPropagation();
          }
        },
        onChange: function onChange(filterText) {
          return _this10.setTextFilter(filterText);
        }
      });
      isNoResults = getChildrenLabels(children, this.state.filterCallback).length === 0;
    }

    var header = null;

    if (listHeader && filter) {
      header = React.createElement("li", {
        className: "multi-select-list-header",
        role: "none"
      }, listHeader, filter);
    } else if (listHeader) {
      header = React.createElement("li", {
        className: "multi-select-list-header",
        role: "none"
      }, listHeader);
    } else if (filter) {
      header = React.createElement("li", {
        className: "multi-select-list-header",
        role: "none"
      }, filter);
    }

    var selectedItemLabels = this.getSelectedItemLabels();
    var title = this.getTitle(selectedItemLabels);
    var displayLabel = this.getDisplayLabel(selectedItemLabels);
    id = id || (testAutomationId !== MultiSelectDefaultAutomationId ? testAutomationId : Date.now());
    var dropdownMenuClassName = stretchDropdownMenu ? 'stretch' : null;
    return React.createElement(Dropdown, _extends({
      id: id,
      onToggle: this.onToggle,
      onKeyDown: this.onKeyDown,
      open: this.state.isOpen,
      ref: this.saveMultiSelectRef,
      "data-test-automation-id": this.props.hasFormGroupContainer ? undefined : testAutomationId,
      className: classnames('multi-select', className, {
        'btn-block': stretch || block,
        stretch: stretch
      })
    }, this.getSafeProps(otherProps)), React.createElement(Dropdown.Toggle, {
      ref: this.focusHelper.setEl,
      "data-test-automation-id": "toggle",
      "aria-labelledby": ariaLabelledById,
      noCaret: true,
      block: true,
      disabled: this.props.disabled,
      "aria-label": this.getAriaLabel(),
      "aria-describedby": otherProps['aria-describedby'] || null,
      title: title
    }, React.createElement("span", {
      className: "icon-wrapper",
      "aria-hidden": "true"
    }, React.createElement(Icon, {
      name: "chevron-down-small"
    })), React.createElement("div", {
      className: "label-wrapper"
    }, React.createElement("div", {
      className: "label-wrapper-inner"
    }, React.createElement("div", {
      className: "label-text-overflow"
    }, displayLabel)))), React.createElement(Dropdown.Menu, {
      className: dropdownMenuClassName,
      "data-test-automation-id": "list"
    }, header, !hasChildren || isNoResults ? React.createElement("li", {
      className: "no-results",
      "data-test-automation-id": "noResult",
      role: "none"
    }, noResultsText) : React.createElement("li", {
      className: "multi-select-list-content",
      role: "menuitem"
    }, React.createElement("ul", {
      role: "tree",
      "aria-multiselectable": !this.props.isSingleSelect,
      "aria-activedescendant": this.state.ariaActivedescendant
    }, appendAriaPropsForMultiSelectChildren(children))), hasChildren && !isNoResults ? this.renderShowMore() : null));
  };

  return MultiSelect;
}(FormControl);

_defineProperty(MultiSelect, "propTypes", Object.assign({}, FormControl.propTypes, {
  id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
  isFilterable: PropTypes.bool,
  searchText: PropTypes.string,
  noResultsText: PropTypes.string,
  label: PropTypes.string,
  value: PropTypes.any,
  testAutomationId: PropTypes.string,
  className: PropTypes.string,
  block: PropTypes.bool,
  stretch: PropTypes.bool,
  listHeader: PropTypes.any,
  listItemsLimit: PropTypes.number,
  labelItemsLimit: PropTypes.number,
  onChange: PropTypes.func,
  isSingleSelect: PropTypes.bool,
  showMoreCountTextTemplate: PropTypes.string,
  toggleAriaLabel: PropTypes.string,
  selectedValuesPrefix: PropTypes.string,
  applyLabelPrefixForSingleMode: PropTypes.bool,
  applyLabelPrefixForMultiMode: PropTypes.bool,
  ariaLabelledById: PropTypes.string,
  stretchDropdownMenu: PropTypes.bool
}));

_defineProperty(MultiSelect, "childContextTypes", {
  multiSelect: PropTypes.object,
  level: PropTypes.number,
  getOptionIdPrefix: PropTypes.func,
  setAriaActivedescendant: PropTypes.func
});

_defineProperty(MultiSelect, "Option", MultiSelectOption);

_defineProperty(MultiSelect, "MasterOption", MultiSelectMasterOption);

_defineProperty(MultiSelect, "Group", MultiSelectOptionGroup);

_defineProperty(MultiSelect, "MultiSelectField", MultiSelectField);

_defineProperty(MultiSelect, "defaultProps", Object.assign({}, FC.defaultProps, {
  isFilterable: false,
  labelItemsLimit: 3,
  testAutomationId: MultiSelectDefaultAutomationId,
  searchText: 'TRANSLATE:SEARCH',
  noResultsText: 'TRANSLATE:NO_RESULTS',
  disabled: false,
  isSingleSelect: false,
  showMoreCountTextTemplate: 'TRANSLATE:SHOW_MORE_COUNT',

  /** example string format: "{filterName} filter" */
  toggleAriaLabel: 'TRANSLATE:MULTI_SELECT_ARIA_LABEL',

  /**  example string format: "selected {filterName}: {values}" */
  selectedValuesPrefix: 'TRANSLATE:MULTI_SELECT_SELECTED_TITLE_LABEL',
  applyLabelPrefixForSingleMode: false,
  applyLabelPrefixForMultiMode: true,
  stretchDropdownMenu: false
}));

function appendAriaPropsForMultiSelectChildren(children) {
  var arr = _.flatten(toArray(children));

  return _.map(arr, function (child, index) {
    if (_.isEmpty(child)) {
      return child;
    }

    var childProps = child.props || {};
    return React.cloneElement(child, {
      ariaPosition: index + 1,
      ariaLevel: 1,
      ariaSetSize: arr.length
    }, childProps.children);
  });
}

function toArray(value) {
  return _.isArray(value) ? value : [value];
}