function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }

function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }

function _get(target, property, receiver) { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get; } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(receiver); } return desc.value; }; } return _get(target, property, receiver || target); }

function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; }

function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }

function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

/* eslint-disable valid-jsdoc */
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { func, obj, KEYCODE, env, str } from '../util';
import Tag from '../tag';
import Input from '../input';
import Icon from '../icon';
import zhCN from '../locale/zh-cn';
import Base from './base';
import { isNull, getValueDataSource, valueToSelectKey } from './util';
var noop = func.noop;
var isIE9 = env.ieVersion === 9;
/**
 * 无障碍化注意事项:
 * 1. Select 无搜索情况下，不应该让 Input 可focus，此时外层wrap必须可focus，并且需要相应focus事件让外边框发生变化
 *
 * TODO: hightLight 后续改造注意点
 * 1. hightLight 跟随点击变化(fixed) 2. 弹窗打开时根据 是否高亮第一个选项的 api开关设置是否hightLight 第一项
 */
// 自定义弹层：1. 不需要关心Menu的点击事件 2. 不需要关心dataSource变化

/**
 * Select
 */

var Select =
/*#__PURE__*/
function (_Base) {
  _inherits(Select, _Base);

  function Select(props) {
    var _this;

    _classCallCheck(this, Select);

    _this = _possibleConstructorReturn(this, _getPrototypeOf(Select).call(this, props)); // @extend Base state

    _defineProperty(_assertThisInitialized(_this), "ie9Hack", function () {
      try {
        var width = _this.selectDOM.currentStyle.width;

        _this.setState({
          fixWidth: width !== 'auto'
        });
      } catch (e) {//
      }
    });

    _defineProperty(_assertThisInitialized(_this), "useDetailValue", function () {
      var _this$props = _this.props,
          popupContent = _this$props.popupContent,
          useDetailValue = _this$props.useDetailValue,
          dataSource = _this$props.dataSource;
      return useDetailValue || popupContent && !dataSource;
    });

    _defineProperty(_assertThisInitialized(_this), "hasSearch", function () {
      var _this$props2 = _this.props,
          showSearch = _this$props2.showSearch,
          mode = _this$props2.mode;
      return showSearch || mode === 'tag';
    });

    _defineProperty(_assertThisInitialized(_this), "handleMenuSelect", function (keys, item) {
      var _this$props3 = _this.props,
          mode = _this$props3.mode,
          readOnly = _this$props3.readOnly,
          disabled = _this$props3.disabled;

      if (readOnly || disabled) {
        return false;
      }

      var isSingle = mode === 'single';

      if (isSingle) {
        // 单选
        return _this.handleSingleSelect(keys[0], 'itemClick');
      } else {
        // 正常多选
        return _this.handleMultipleSelect(keys, 'itemClick', item.props && item.props._key);
      }
    });

    _defineProperty(_assertThisInitialized(_this), "handleItemClick", function () {
      _this.focusInput();
    });

    _defineProperty(_assertThisInitialized(_this), "handleSingleSelect", function (key, triggerType) {
      var cacheValue = _this.props.cacheValue; // get data only from dataStore while cacheValue=false

      var itemObj = getValueDataSource(key, cacheValue ? _this.valueDataSource.mapValueDS : {}, _this.dataStore.getMapDS());
      _this.valueDataSource = itemObj;

      _this.setVisible(false, triggerType);

      if (_this.useDetailValue()) {
        return _this.handleChange(itemObj.valueDS, triggerType);
      } else {
        _this.handleChange(itemObj.value, triggerType, itemObj.valueDS);
      }

      _this.setState({
        highlightKey: key
      }); // 清空搜索


      if (!('searchValue' in _this.props) && _this.state.searchValue) {
        _this.handleSearchClear(triggerType);
      }
    });

    _defineProperty(_assertThisInitialized(_this), "handleMultipleSelect", function (keys, triggerType, key) {
      var itemObj = getValueDataSource(keys, _this.valueDataSource.mapValueDS, _this.dataStore.getMapDS());
      var _this$props4 = _this.props,
          cacheValue = _this$props4.cacheValue,
          mode = _this$props4.mode,
          hiddenSelected = _this$props4.hiddenSelected; // cache those value maybe not exists in dataSource

      if (cacheValue || mode === 'tag') {
        _this.valueDataSource = itemObj;
      }

      if (hiddenSelected) {
        _this.setVisible(false, triggerType);
      }

      key && _this.state.visible && _this.setState({
        highlightKey: key
      });

      if (_this.useDetailValue()) {
        _this.handleChange(itemObj.valueDS, triggerType);
      } else {
        _this.handleChange(itemObj.value, triggerType, itemObj.valueDS);
      }

      _this.updateSelectAllYet(itemObj.value); // 清空搜索


      if (!('searchValue' in _this.props) && _this.state.searchValue) {
        // 因为 SearchValue 被 clear 后会重新渲染 Menu，所以在 Overlay 检测 safeNode 的时候 e.target 可能会找不到导致弹窗关闭
        setTimeout(function () {
          _this.handleSearchClear(triggerType);
        });
      }
    });

    _defineProperty(_assertThisInitialized(_this), "updateSelectAllYet", function (value) {
      // multiple mode
      // is current state select all or not
      _this.selectAllYet = false;

      if (_this.props.hasSelectAll && Array.isArray(value)) {
        var selectAllValues = _this.dataStore.getEnableDS().map(function (item) {
          return item.value;
        });

        if (selectAllValues.length <= value.length) {
          _this.selectAllYet = true;
          selectAllValues.forEach(function (val) {
            if (value.indexOf(val) === -1) {
              _this.selectAllYet = false;
            }
          });
        }
      }
    });

    _defineProperty(_assertThisInitialized(_this), "handleSearchValue", function (value) {
      if (_this.state.searchValue === value) {
        return;
      }

      var filterLocal = _this.props.filterLocal;

      if (filterLocal) {
        if (!('searchValue' in _this.props)) {
          _this.setState({
            searchValue: value,
            dataSource: _this.dataStore.updateByKey(value)
          });

          _this.setFirstHightLightKeyForMenu();
        }
      } else if (!('searchValue' in _this.props)) {
        _this.setState({
          searchValue: value
        });
      }
    });

    _defineProperty(_assertThisInitialized(_this), "handleSearch", function (value) {
      _this.handleSearchValue(value); // inputing should trigger popup open


      if (!_this.state.visible && value) {
        _this.setVisible(true);
      }

      _this.props.onSearch(value);
    });

    _defineProperty(_assertThisInitialized(_this), "handleSearchClear", function (triggerType) {
      _this.handleSearchValue('');

      _this.props.onSearchClear(triggerType);
    });

    _defineProperty(_assertThisInitialized(_this), "handleSearchKeyDown", function (e) {
      var _this$props5 = _this.props,
          popupContent = _this$props5.popupContent,
          onKeyDown = _this$props5.onKeyDown,
          showSearch = _this$props5.showSearch,
          mode = _this$props5.mode,
          hasClear = _this$props5.hasClear,
          onToggleHighlightItem = _this$props5.onToggleHighlightItem;

      if (popupContent) {
        return onKeyDown(e);
      }

      var proxy = 'search';

      var hasSearch = _this.hasSearch();

      switch (e.keyCode) {
        case KEYCODE.UP:
          e.preventDefault();
          onToggleHighlightItem(_this.toggleHighlightItem(-1, e), 'up');
          break;

        case KEYCODE.DOWN:
          e.preventDefault();
          onToggleHighlightItem(_this.toggleHighlightItem(1, e), 'down');
          break;

        case KEYCODE.ENTER:
          e.preventDefault();

          _this.chooseHighlightItem(proxy, e);

          break;

        case KEYCODE.ESC:
          e.preventDefault();
          _this.state.visible && _this.setVisible(false, 'keyDown');
          break;

        case KEYCODE.SPACE:
          e.stopPropagation();
          !hasSearch && e.preventDefault();
          break;

        case KEYCODE.BACKSPACE:
          if (mode === 'multiple' && showSearch || mode === 'tag') {
            // 在多选并且有搜索的情况下，删除最后一个 tag
            _this.handleDeleteTag(e);
          } else if (mode === 'single' && hasClear && !_this.state.visible) {
            // 单选、非展开、并且可清除的情况，允许按删除键清除
            _this.handleClear(e);
          }

          break;

        default:
          break;
      }

      onKeyDown(e);
    });

    _defineProperty(_assertThisInitialized(_this), "chooseMultipleItem", function (key) {
      var value = _this.state.value || [];
      var keys = value.map(function (v) {
        return valueToSelectKey(v);
      });
      var index = keys.map(function (v) {
        return "".concat(v);
      }).indexOf(key);

      if (index > -1) {
        // unselect
        keys.splice(index, 1);
      } else {
        // select
        keys.push(key);
      }

      _this.handleMultipleSelect(keys, 'enter');
    });

    _defineProperty(_assertThisInitialized(_this), "chooseHighlightItem", function (proxy, e) {
      var prevVisible = _this.state.visible;
      var mode = _this.props.mode;

      if (!prevVisible) {
        // input tag by itself
        if (mode === 'tag' && _this.state.searchValue) {
          _this.chooseMultipleItem(_this.state.searchValue);
        }

        return false;
      }

      var highlightKey = _this.state.highlightKey; // 没有高亮选项 或者 没有可选菜单

      if (highlightKey === null || !_this.dataStore.getMenuDS().length) {
        return;
      }

      if (mode === 'single') {
        _this.handleSingleSelect(highlightKey, 'enter');
      } else {
        _this.chooseMultipleItem(highlightKey); // 阻止事件冒泡到最外层，让Popup 监听到触发弹层关闭


        e && e.stopPropagation();
      }
    });

    _defineProperty(_assertThisInitialized(_this), "handleTagClose", function (item) {
      if (_this.useDetailValue()) {
        var value = _this.state.value.filter(function (v) {
          return item.value !== v.value;
        });

        _this.handleChange(value, 'tag');
      } else {
        // filter out current item, and then call handleMenuSelect
        var _value = _this.state.value.filter(function (v) {
          return item.value !== v;
        });

        _this.handleMultipleSelect(_value, 'tag');
      }

      _this.props.onRemove(item); // prevent tag close


      return false;
    });

    _defineProperty(_assertThisInitialized(_this), "handleDeleteTag", function (e) {
      var value = _this.state.value;
      var searchValue = _this.state.searchValue;

      if (searchValue || !value || !value.length) {
        return false;
      }

      e.preventDefault();
      var nextValues = value.slice(0, value.length - 1); // 手动调用 handleMenuSelect 时直接传入原生的 value，可以减少 toString 的操作

      if (_this.useDetailValue()) {
        _this.handleChange(nextValues, 'tag');
      } else {
        _this.handleMultipleSelect(nextValues, 'tag');
      }
    });

    _defineProperty(_assertThisInitialized(_this), "handleSelectAll", function (e) {
      e && e.preventDefault();
      var nextValues;

      if (_this.selectAllYet) {
        nextValues = [];
      } else {
        nextValues = _this.dataStore.getEnableDS().map(function (item) {
          return item.value;
        });
      } // 直接传 values，减少 toString 操作


      _this.handleMultipleSelect(nextValues, 'selectAll');
    });

    _defineProperty(_assertThisInitialized(_this), "handleVisibleChange", function (visible, type) {
      _this.setVisible(visible, type);
    });

    _defineProperty(_assertThisInitialized(_this), "afterClose", function () {
      // 关闭的时候清空搜索值
      if (_this.hasSearch()) {
        _this.handleSearchClear('popupClose');
      } // 清空选项的获焦状态


      _this.setState({
        highlightKey: ''
      });
    });

    _defineProperty(_assertThisInitialized(_this), "maxTagPlaceholder", function (selectedValues, totalValues) {
      var locale = _this.props.locale;
      return "".concat(str.template(locale.maxTagPlaceholder, {
        selected: selectedValues.length,
        total: totalValues.length
      }));
    });

    _defineProperty(_assertThisInitialized(_this), "renderValues", function () {
      var _this$props6 = _this.props,
          prefix = _this$props6.prefix,
          mode = _this$props6.mode,
          size = _this$props6.size,
          valueRender = _this$props6.valueRender,
          fillProps = _this$props6.fillProps,
          disabled = _this$props6.disabled,
          maxTagCount = _this$props6.maxTagCount,
          maxTagPlaceholder = _this$props6.maxTagPlaceholder,
          tagInline = _this$props6.tagInline;
      var value = _this.state.value;

      if (isNull(value)) {
        return null;
      } // get detail value


      if (!_this.useDetailValue()) {
        if (value === _this.valueDataSource.value) {
          value = _this.valueDataSource.valueDS;
        } else {
          value = getValueDataSource(value, _this.valueDataSource.mapValueDS, _this.dataStore.getMapDS()).valueDS;
        }
      }

      if (mode === 'single') {
        if (!value) {
          return null;
        }

        var retvalue = fillProps && fillProps in value ? value[fillProps] : valueRender(value); // 0 => '0'

        return typeof retvalue === 'number' ? retvalue.toString() : retvalue;
      } else if (value) {
        var limitedCountValue = value;
        var maxTagPlaceholderEl;

        var totalValue = _this.dataStore.getFlattenDS();

        var holder = 'maxTagPlaceholder' in _this.props ? maxTagPlaceholder : _this.maxTagPlaceholder;

        if (maxTagCount !== undefined && value.length > maxTagCount && !tagInline) {
          limitedCountValue = limitedCountValue.slice(0, maxTagCount);
          maxTagPlaceholderEl = React.createElement(Tag, {
            key: "_count",
            type: "primary",
            size: size === 'large' ? 'medium' : 'small',
            animation: false
          }, holder(value, totalValue));
        }

        if (value.length > 0 && tagInline) {
          maxTagPlaceholderEl = React.createElement("div", {
            className: "".concat(prefix, "select-tag-compact"),
            key: "_count"
          }, holder(value, totalValue));
        }

        value = limitedCountValue;

        if (!Array.isArray(value)) {
          value = [value];
        }

        var selectedValueNodes = value.map(function (v) {
          if (!v) {
            return null;
          }

          var labelNode = fillProps ? v[fillProps] : valueRender(v);
          return React.createElement(Tag, {
            key: v.value,
            disabled: disabled || v.disabled,
            type: "primary",
            size: size === 'large' ? 'medium' : 'small',
            animation: false,
            onClose: _this.handleTagClose.bind(_assertThisInitialized(_this), v),
            closable: true
          }, labelNode);
        });

        if (maxTagPlaceholderEl) {
          if (tagInline) {
            selectedValueNodes.unshift(maxTagPlaceholderEl);
          } else {
            selectedValueNodes.push(maxTagPlaceholderEl);
          }
        }

        return selectedValueNodes;
      }

      return null;
    });

    _defineProperty(_assertThisInitialized(_this), "handleWrapClick", function (e) {
      // ignore click on input to choose text
      if (e.target.nodeName !== 'INPUT') {
        e.preventDefault();
      }

      _this.focusInput();
    });

    _defineProperty(_assertThisInitialized(_this), "handleArrowClick", function (e) {
      e.preventDefault();

      _this.focusInput(); // because of can not close Popup by click Input while hasSearch.
      // so when Popup open and hasSearch, we should close Popup intentionally


      _this.state.visible && _this.hasSearch() && _this.setVisible(false);
    });

    _defineProperty(_assertThisInitialized(_this), "handleClear", function (e) {
      e.stopPropagation();

      _this.handleChange(undefined, 'clear');
    });

    _defineProperty(_assertThisInitialized(_this), "hasClear", function () {
      var _this$props7 = _this.props,
          hasClear = _this$props7.hasClear,
          readOnly = _this$props7.readOnly,
          disabled = _this$props7.disabled,
          mode = _this$props7.mode,
          showSearch = _this$props7.showSearch;
      var _this$state = _this.state,
          value = _this$state.value,
          visible = _this$state.visible;
      return typeof value !== 'undefined' && hasClear && !readOnly && !disabled && mode === 'single' && !(showSearch && visible);
    });

    _defineProperty(_assertThisInitialized(_this), "renderExtraNode", function () {
      var _this$props8 = _this.props,
          hasArrow = _this$props8.hasArrow,
          hasClear = _this$props8.hasClear,
          prefix = _this$props8.prefix;
      var ret = [];

      if (hasArrow) {
        ret.push(React.createElement("span", {
          key: "arrow",
          "aria-hidden": true,
          onClick: _this.handleArrowClick,
          className: "".concat(prefix, "select-arrow")
        }, React.createElement(Icon, {
          type: "chevron-down-s"
        })));
      } // do not use this.hasClear() here, to make sure clear btn always exists, can not influenced by apis like `disabled` `readOnly`


      if (hasClear) {
        ret.push(React.createElement("span", {
          key: "clear",
          "aria-hidden": true,
          onClick: _this.handleClear,
          className: "".concat(prefix, "select-clear")
        }, React.createElement(Icon, {
          type: "remove-o-fill"
        })));
      }

      return ret;
    });

    _defineProperty(_assertThisInitialized(_this), "renderSelect", function () {
      var _classNames;

      var _this$props9 = _this.props,
          prefix = _this$props9.prefix,
          trigger = _this$props9.trigger,
          showSearch = _this$props9.showSearch,
          placeholder = _this$props9.placeholder,
          mode = _this$props9.mode,
          size = _this$props9.size,
          className = _this$props9.className,
          style = _this$props9.style,
          readOnly = _this$props9.readOnly,
          disabled = _this$props9.disabled,
          hasBorder = _this$props9.hasBorder,
          label = _this$props9.label,
          locale = _this$props9.locale,
          state = _this$props9.state,
          onBlur = _this$props9.onBlur,
          onFocus = _this$props9.onFocus,
          rtl = _this$props9.rtl;

      if (trigger) {
        return trigger;
      }

      var others = obj.pickOthers(Select.propTypes, _this.props);
      var othersData = obj.pickAttrsWith(others, 'data-');
      var visible = _this.state.visible;
      var isSingle = mode === 'single';

      var hasSearch = _this.hasSearch();

      var valueNodes = _this.renderValues();

      var _placeholder = placeholder || locale.selectPlaceholder;

      if (valueNodes && valueNodes.length) {
        _placeholder = null;
      } // 弹窗展开时将当前的值作为 placeholder，这个功能的前提是 valueNode 必须是一个字符串


      if (showSearch && visible && isSingle && typeof valueNodes === 'string') {
        _placeholder = valueNodes;
      } // 下拉箭头


      var extra = _this.renderExtraNode();

      var triggerClazz = classNames(["".concat(prefix, "select"), "".concat(prefix, "select-trigger"), "".concat(prefix, "select-").concat(mode), "".concat(prefix).concat(size), className], (_classNames = {}, _defineProperty(_classNames, "".concat(prefix, "active"), visible), _defineProperty(_classNames, "".concat(prefix, "inactive"), !visible), _defineProperty(_classNames, "".concat(prefix, "no-search"), !hasSearch), _defineProperty(_classNames, "".concat(prefix, "has-search"), hasSearch), _defineProperty(_classNames, "".concat(prefix, "select-in-ie"), isIE9), _defineProperty(_classNames, "".concat(prefix, "select-in-ie-fixwidth"), _this.state.fixWidth), _defineProperty(_classNames, "".concat(prefix, "has-clear"), _this.hasClear()), _classNames));
      var valuetext = _this.valueDataSource.valueDS ? _this.valueDataSource.valueDS.label : ''; // state 为loading时效果转到弹层面板中

      return React.createElement("span", _extends({}, othersData, {
        className: triggerClazz,
        style: style,
        dir: rtl ? 'rtl' : undefined,
        ref: _this.saveSelectRef,
        onClick: _this.handleWrapClick,
        onMouseDown: _this.handleWrapClick
      }), React.createElement(Input, _extends({
        "aria-valuetext": valuetext
      }, obj.pickOthers(othersData, others), {
        role: "combobox",
        tabIndex: 0,
        "aria-expanded": _this.state.visible,
        "aria-disabled": disabled,
        state: state === 'loading' ? undefined : state,
        label: label,
        extra: extra,
        value: _this.state.searchValue,
        size: size,
        readOnly: !_this.hasSearch() || readOnly,
        disabled: disabled,
        placeholder: _placeholder,
        hasBorder: hasBorder,
        hasClear: false,
        htmlSize: "1",
        inputRender: function inputRender(inputEl) {
          return _this.renderSearchInput(valueNodes, _placeholder, inputEl);
        },
        onChange: _this.handleSearch,
        onKeyDown: _this.handleSearchKeyDown,
        onFocus: onFocus,
        onBlur: onBlur,
        className: "".concat(prefix, "select-inner"),
        ref: _this.saveInputRef
      })), React.createElement("span", {
        className: "".concat(prefix, "sr-only"),
        "aria-live": "polite"
      }, _this.state.srReader));
    });

    _defineProperty(_assertThisInitialized(_this), "renderSearchInput", function (valueNodes, placeholder, inputEl) {
      var _classNames2;

      var _this$props10 = _this.props,
          prefix = _this$props10.prefix,
          mode = _this$props10.mode,
          tagInline = _this$props10.tagInline;
      var isSingle = mode === 'single';
      var mirrorText = _this.state.searchValue;
      var cls = classNames((_classNames2 = {}, _defineProperty(_classNames2, "".concat(prefix, "select-values"), true), _defineProperty(_classNames2, "".concat(prefix, "input-text-field"), true), _defineProperty(_classNames2, "".concat(prefix, "select-compact"), !isSingle && tagInline), _classNames2));
      var searchInput = [isSingle && valueNodes ? React.createElement("em", {
        key: "select-value"
      }, valueNodes) : valueNodes];
      var triggerSearch = React.createElement("span", {
        key: "trigger-search",
        className: "".concat(prefix, "select-trigger-search")
      }, inputEl, React.createElement("span", {
        "aria-hidden": true
      }, mirrorText || placeholder, "\xA0"));

      if (!isSingle && tagInline) {
        searchInput.unshift(triggerSearch);
      } else {
        searchInput.push(triggerSearch);
      }

      return React.createElement("span", {
        className: cls
      }, searchInput);
    });

    _defineProperty(_assertThisInitialized(_this), "renderMenuHeader", function () {
      var _classNames3;

      var _this$props11 = _this.props,
          prefix = _this$props11.prefix,
          hasSelectAll = _this$props11.hasSelectAll,
          mode = _this$props11.mode;

      var sourceCount = _this.dataStore.getEnableDS().length; // 多选模式下才有全选


      if (!hasSelectAll || mode === 'single' || !sourceCount) {
        return null;
      }

      var text = typeof hasSelectAll === 'boolean' ? 'Select All' : hasSelectAll;

      var _assertThisInitialize = _assertThisInitialized(_this),
          selectAllYet = _assertThisInitialize.selectAllYet;

      var cls = classNames((_classNames3 = {}, _defineProperty(_classNames3, "".concat(prefix, "select-all"), true), _defineProperty(_classNames3, "".concat(prefix, "selected"), selectAllYet), _classNames3));
      var clsInner = classNames(_defineProperty({}, "".concat(prefix, "select-all-inner"), true)); // remove style={{'lineHeight': 'unset'}} in next Y
      // remove style={{'display': 'none'}} in next Y

      return React.createElement("div", {
        key: "all",
        onClick: _this.handleSelectAll,
        className: cls,
        style: {
          lineHeight: 'unset'
        }
      }, selectAllYet ? React.createElement(Icon, {
        className: "".concat(prefix, "menu-icon-selected"),
        style: {
          display: 'none'
        },
        type: "tick"
      }) : null, React.createElement("span", {
        className: clsInner
      }, text));
    });

    _extends(_this.state, {
      // search keyword
      searchValue: 'searchValue' in props ? props.searchValue : ''
    }); // because dataSource maybe updated while select a item, so we should cache choosen value's item


    _this.valueDataSource = {
      valueDS: [],
      // [{value,label}]
      mapValueDS: {} // {value: {value,label}}

    };
    return _this;
  }

  _createClass(Select, [{
    key: "UNSAFE_componentWillMount",
    value: function UNSAFE_componentWillMount() {
      this.dataStore.setOptions({
        key: this.state.searchValue,
        addonKey: this.props.mode === 'tag' // tag 模式手动输入的数据

      });

      if (_get(_getPrototypeOf(Select.prototype), "UNSAFE_componentWillMount", this)) {
        _get(_getPrototypeOf(Select.prototype), "UNSAFE_componentWillMount", this).call(this);
      } // 根据value和计算后的dataSource，更新value对应的详细数据valueDataSource


      if (typeof this.state.value !== 'undefined') {
        this.valueDataSource = getValueDataSource(this.state.value, this.valueDataSource.mapValueDS, this.dataStore.getMapDS());
      }

      if (isIE9) {
        this.ie9Hack();
      }
    }
  }, {
    key: "UNSAFE_componentWillReceiveProps",
    value: function UNSAFE_componentWillReceiveProps(nextProps) {
      if ('searchValue' in nextProps) {
        this.dataStore.setOptions({
          key: nextProps.searchValue
        });
        this.setState({
          searchValue: typeof nextProps.searchValue === 'undefined' ? '' : nextProps.searchValue
        });
      }

      if (this.props.mode !== nextProps.mode) {
        this.dataStore.setOptions({
          addonKey: nextProps.mode === 'tag'
        });
      }

      this.dataStore.setOptions({
        filter: nextProps.filter,
        filterLocal: nextProps.filterLocal
      });

      if (nextProps.children !== this.props.children || nextProps.dataSource !== this.props.dataSource) {
        var dataSource = this.setDataSource(nextProps);
        this.setState({
          dataSource: dataSource
        }); // 远程数据有更新，并且还有搜索框

        if (nextProps.showSearch && !nextProps.filterLocal && !nextProps.popupContent) {
          this.setFirstHightLightKeyForMenu();
        }
      }

      if ('value' in nextProps) {
        this.setState({
          value: nextProps.value
        });
        this.valueDataSource = getValueDataSource(nextProps.value, this.valueDataSource.mapValueDS, this.dataStore.getMapDS());
        this.updateSelectAllYet(this.valueDataSource.value);
      } else if ('defaultValue' in nextProps && nextProps.defaultValue === this.valueDataSource.value && (nextProps.children !== this.props.children || nextProps.dataSource !== this.props.dataSource)) {
        // has defaultValue and value not changed and dataSource changed
        this.valueDataSource = getValueDataSource(nextProps.defaultValue, this.valueDataSource.mapValueDS, this.dataStore.getMapDS());
      }

      if ('visible' in nextProps) {
        this.setState({
          visible: nextProps.visible
        });
      }

      if (!this.props.visible && nextProps.visible) {
        // 当面板由收起到展开时，面板显示完整的数据（无过滤效果）
        this.setState({
          dataSource: this.dataStore.getOriginDS()
        }); // 更新菜单数据

        this.dataStore.updateByKey('');
      }
    }
  }, {
    key: "componentDidMount",
    value: function componentDidMount() {
      if (isIE9) {
        this.ie9Hack();
      }

      _get(_getPrototypeOf(Select.prototype), "componentDidMount", this).call(this);
    } // ie9 下 table-cell 布局不支持宽度超出隐藏

  }, {
    key: "componentDidUpdate",
    value: function componentDidUpdate(prevProps, prevState) {
      var props = this.props; // 随着输入自动伸展

      if (/tag|multiple/.test(props.mode) && prevState.searchValue !== this.state.searchValue) {
        this.syncWidth();
      } else {
        return _get(_getPrototypeOf(Select.prototype), "componentDidUpdate", this).call(this, prevProps, prevState);
      }
    }
  }, {
    key: "render",
    value: function render() {
      var mode = this.props.mode;

      var props = _objectSpread({}, this.props); // forbid to close Popup by click Input while hasSearch


      if (this.hasSearch()) {
        props.canCloseByTrigger = false;
      }

      if (mode === 'single') {
        props.cache = true;
      }

      return _get(_getPrototypeOf(Select.prototype), "render", this).call(this, props);
    }
  }]);

  return Select;
}(Base);

_defineProperty(Select, "propTypes", _objectSpread({}, Base.propTypes, {
  trigger: PropTypes.element,

  /**
   * 选择器模式
   */
  mode: PropTypes.oneOf(['single', 'multiple', 'tag']),

  /**
   * 当前值，用于受控模式
   */
  value: PropTypes.any,

  /**
   * 初始的默认值
   */
  defaultValue: PropTypes.any,

  /**
   * Select发生改变时触发的回调
   * @param {*} value 选中的值
   * @param {String} actionType 触发的方式, 'itemClick', 'enter', 'tag'
   * @param {*} item 选中的值的对象数据 (useDetailValue=false有效)
   */
  onChange: PropTypes.func,

  /**
   * 传入的数据源，可以动态渲染子项，详见 [dataSource的使用](#dataSource的使用)
   */
  dataSource: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.shape({
    value: PropTypes.any,
    label: PropTypes.any,
    disabled: PropTypes.bool,
    children: PropTypes.array
  }), PropTypes.bool, PropTypes.number, PropTypes.string])),

  /**
   * 是否有边框
   */
  hasBorder: PropTypes.bool,

  /**
   * 是否有下拉箭头
   */
  hasArrow: PropTypes.bool,

  /**
   * 展开后是否能搜索（tag 模式下固定为true）
   */
  showSearch: PropTypes.bool,

  /**
   * 当搜索框值变化时回调
   * @param {String} value 数据
   */
  onSearch: PropTypes.func,

  /**
   * 当搜索框值被清空时候的回调
   * @param {String} actionType 触发的方式, 'select'(选择清空), 'popupClose'(弹窗关闭清空)
   */
  onSearchClear: PropTypes.func,

  /**
   * 多选模式下是否有全选功能
   */
  hasSelectAll: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),

  /**
   * 填充到选择框里的值的 key
   */
  fillProps: PropTypes.string,

  /**
   * onChange 返回的 value 使用 dataSource 的对象
   */
  useDetailValue: PropTypes.bool,

  /**
   * dataSource 变化的时是否保留已选的内容
   */
  cacheValue: PropTypes.bool,

  /**
   * 渲染 Select 展现内容的方法
   * @param {Object} item 渲染节点的item
   * @return {ReactNode} 展现内容
   * @default item => item.label \|\| item.value
   */
  valueRender: PropTypes.func,

  /**
   * 渲染 MenuItem 内容的方法
   * @param {Object} item 渲染节点的item
   * @param {String} searchValue 搜索关键字（如果开启搜索）
   * @return {ReactNode} item node
   */
  itemRender: PropTypes.func,

  /**
   * 弹层内容为空的文案
   */
  notFoundContent: PropTypes.node,
  style: PropTypes.object,

  /**
   * 受控搜索值，一般不需要设置
   * @type {[type]}
   */
  searchValue: PropTypes.string,

  /**
   * 是否一行显示，仅在 mode 为 multiple 的时候生效
   */
  tagInline: PropTypes.bool,

  /**
   * 最多显示多少个 tag
   */
  maxTagCount: PropTypes.number,

  /**
   * 隐藏多余 tag 时显示的内容，在 maxTagCount 生效时起作用
   * @param {number} selectedValues 当前已选中的元素
   * @param {number} totalValues 总待选元素
   */
  maxTagPlaceholder: PropTypes.func,

  /**
   * 选择后是否立即隐藏菜单 (mode=multiple/tag 模式生效)
   */
  hiddenSelected: PropTypes.bool,

  /**
   * tag 删除回调
   * @param {object} item 渲染节点的item
   */
  onRemove: PropTypes.func,

  /**
   * 焦点事件
   */
  onFocus: PropTypes.func,

  /**
   * 是否自动高亮第一个选项
   */
  // highlightFirstItem: PropTypes.bool,

  /**
   * 失去焦点事件
   */
  onBlur: PropTypes.func,
  onKeyDown: PropTypes.func,
  locale: PropTypes.object
}));

_defineProperty(Select, "defaultProps", _objectSpread({}, Base.defaultProps, {
  locale: zhCN.Select,
  mode: 'single',
  showSearch: false,
  cacheValue: true,
  tagInline: false,
  onSearch: noop,
  onSearchClear: noop,
  hasArrow: true,
  onRemove: noop,
  // highlightFirstItem: true,
  valueRender: function valueRender(item) {
    return item.label || item.value;
  },
  onKeyDown: noop,
  onFocus: noop,
  onBlur: noop
}));

_defineProperty(Select, "displayName", 'Select');

export default Select;