"use strict";

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

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

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

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

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

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

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

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

var _pick2 = _interopRequireDefault(require("lodash/pick"));

var _kebabCase2 = _interopRequireDefault(require("lodash/kebabCase"));

var _get2 = _interopRequireDefault(require("lodash/get"));

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

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

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

var _utils = require("rsuite-utils/lib/utils");

var _reactLifecyclesCompat = require("react-lifecycles-compat");

var _DropdownMenu = _interopRequireDefault(require("./DropdownMenu"));

var _Checkbox = _interopRequireDefault(require("../Checkbox"));

var _utils2 = _interopRequireDefault(require("./utils"));

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

var _treeUtils = require("../utils/treeUtils");

var _picker = require("../_picker");

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

  function Dropdown(props) {
    var _this;

    _this = _React$Component.call(this, props) || this;
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "isControlled", null);
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleCheck", function (item, event, checked) {
      var _this$props = _this.props,
          valueKey = _this$props.valueKey,
          onChange = _this$props.onChange,
          cascade = _this$props.cascade,
          uncheckableItemValues = _this$props.uncheckableItemValues;
      var itemValue = item[valueKey];
      var value = [];

      if (cascade) {
        value = Dropdown.utils.splitValue(item, checked, _this.getValue(), uncheckableItemValues).value;
      } else {
        value = _this.getValue();

        if (checked) {
          value.push(itemValue);
        } else {
          value = value.filter(function (n) {
            return n !== itemValue;
          });
        }
      }

      _this.setState({
        value: value
      });

      onChange && onChange(value, event, itemValue, checked);
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleChangeForSearchItem", function (value, checked, event) {
      _this.handleCheck(value, event, checked);
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleSelect", function (node, cascadeItems, activePaths, event) {
      var _this$props2 = _this.props,
          onSelect = _this$props2.onSelect,
          valueKey = _this$props2.valueKey;

      _this.setState({
        selectNode: node,
        items: cascadeItems,
        activePaths: activePaths
      });

      onSelect && onSelect(node, activePaths, (0, _picker.createConcatChildrenFunction)(node, node[valueKey]), event);
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleSearch", function (searchKeyword, event) {
      var onSearch = _this.props.onSearch;

      _this.setState({
        searchKeyword: searchKeyword
      });

      onSearch && onSearch(searchKeyword, event);
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "trigger", null);
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "bindTriggerRef", function (ref) {
      _this.trigger = ref;
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "menuContainer", null);
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "bindMenuContainerRef", function (ref) {
      _this.menuContainer = ref;
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "container", null);
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "bindContainerRef", function (ref) {
      _this.container = ref;
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "closeDropdown", function () {
      if (_this.trigger) {
        _this.trigger.hide();
      }
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleClean", function (event) {
      var _this$props3 = _this.props,
          disabled = _this$props3.disabled,
          onChange = _this$props3.onChange,
          data = _this$props3.data;

      if (disabled) {
        return;
      }

      var nextState = {
        items: [data],
        value: [],
        selectNode: null,
        activePaths: []
      };

      _this.setState(nextState, function () {
        onChange && onChange([], event);
      });
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleEntered", function () {
      var onOpen = _this.props.onOpen;
      onOpen && onOpen();

      _this.setState({
        active: true
      });
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleExit", function () {
      var onClose = _this.props.onClose;
      onClose && onClose();

      _this.setState({
        searchKeyword: '',
        active: false
      });
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "addPrefix", function (name) {
      return (0, _utils3.prefix)(_this.props.classPrefix)(name);
    });
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "renderSearchRow", function (item, key) {
      var _extends2, _classNames;

      var _this$props4 = _this.props,
          labelKey = _this$props4.labelKey,
          valueKey = _this$props4.valueKey,
          cascade = _this$props4.cascade,
          _this$props4$disabled = _this$props4.disabledItemValues,
          disabledItemValues = _this$props4$disabled === void 0 ? [] : _this$props4$disabled;
      var searchKeyword = _this.state.searchKeyword;

      var values = _this.getValue();

      var nodes = (0, _treeUtils.getNodeParents)(item);
      var regx = new RegExp(searchKeyword, 'ig');
      var labelElements = [];
      var a = item[labelKey].split(regx);
      var b = item[labelKey].match(regx);

      for (var i = 0; i < a.length; i++) {
        labelElements.push(a[i]);

        if (b[i]) {
          labelElements.push(React.createElement("strong", {
            key: i
          }, b[i]));
        }
      }

      nodes.push((0, _extends3.default)({}, item, (_extends2 = {}, _extends2[labelKey] = labelElements, _extends2)));
      var active = values.some(function (value) {
        return nodes.some(function (node) {
          return node[valueKey] === value;
        });
      });
      var disabled = disabledItemValues.some(function (value) {
        return nodes.some(function (node) {
          return node[valueKey] === value;
        });
      });
      var itemClasses = (0, _classnames.default)(_this.addPrefix('cascader-row'), (_classNames = {}, _classNames[_this.addPrefix('cascader-row-disabled')] = disabled, _classNames));
      return React.createElement("div", {
        key: key,
        className: itemClasses
      }, React.createElement(_Checkbox.default, {
        disabled: disabled,
        checked: active,
        value: item,
        indeterminate: cascade && !active && Dropdown.utils.isSomeChildChecked(item, values),
        onChange: _this.handleChangeForSearchItem
      }, React.createElement("span", {
        className: _this.addPrefix('cascader-cols')
      }, nodes.map(function (node, index) {
        return React.createElement("span", {
          key: "col-" + index,
          className: _this.addPrefix('cascader-col')
        }, node[labelKey]);
      }))));
    });
    var _data = props.data,
        _value = props.value,
        defaultValue = props.defaultValue,
        _activePaths = props.activePaths;
    var initState = {
      data: _data,
      searchKeyword: '',
      prevValue: _value,
      value: defaultValue,
      selectNode: null,

      /**
       * 选中值的路径
       */
      activePaths: _activePaths || []
    };
    Dropdown.utils = (0, _utils2.default)(props);
    var flattenData = (0, _treeUtils.flattenTree)(_data, props.childrenKey);
    _this.isControlled = !(0, _isUndefined2.default)(_value);
    _this.state = (0, _extends3.default)({}, initState, {
      flattenData: flattenData,

      /**
       * 用于展示面板的数据列表，是一个二维的数组
       * 是通过 data 树结构转换成的二维的数组，其中只包含页面上展示的数据
       */
      items: [flattenData.filter(function (item) {
        return !item.parent;
      })]
    }, Dropdown.getCascadeState(props, flattenData));
    return _this;
  }

  Dropdown.getCascadeState = function getCascadeState(nextProps, flattenData, nextValue) {
    var data = nextProps.data,
        cascade = nextProps.cascade,
        value = nextProps.value,
        defaultValue = nextProps.defaultValue,
        uncheckableItemValues = nextProps.uncheckableItemValues;
    var cascadeValue = nextValue || value || defaultValue || [];

    if (cascade && data) {
      cascadeValue = Dropdown.utils.transformValue(cascadeValue, flattenData, uncheckableItemValues);
    }

    return {
      value: cascadeValue
    };
  };

  Dropdown.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, prevState) {
    var data = nextProps.data,
        valueKey = nextProps.valueKey,
        childrenKey = nextProps.childrenKey;
    var value = nextProps.value || prevState.value || [];
    var prevValue = prevState.prevValue,
        flattenData = prevState.flattenData,
        _prevState$selectNode = prevState.selectNode,
        selectNode = _prevState$selectNode === void 0 ? {} : _prevState$selectNode,
        items = prevState.items;
    var isChangedData = data !== prevState.data;
    var isChangedValue = !(0, _utils.shallowEqualArray)(prevValue, nextProps.value);

    if (isChangedData || isChangedValue) {
      if (isChangedData) {
        flattenData = (0, _treeUtils.flattenTree)(data, nextProps.childrenKey);
      }
      /**
       * 如果更新了 data,
       * 首先获取到被点击节点的值 `selectNode`， 然后再拿到新增后的 `newChildren`,
       */


      var nextSelectNode = flattenData.find(function (n) {
        return selectNode && n[valueKey] === selectNode[valueKey];
      });
      var newChildren = ((0, _get2.default)(nextSelectNode, childrenKey) || []).map(function (item) {
        item.parent = nextSelectNode;
        return item;
      });

      if (newChildren.length && items) {
        items[items.length - 1] = newChildren;
      }

      var nextState = (0, _extends3.default)({
        selectNode: nextSelectNode,
        flattenData: flattenData,
        data: data,
        items: Dropdown.utils.getItems(nextSelectNode, flattenData)
      }, Dropdown.getCascadeState(nextProps, flattenData, value));

      if (isChangedValue) {
        nextState.prevValue = nextProps.value;
      }

      return nextState;
    }

    return null;
  };

  var _proto = Dropdown.prototype;

  _proto.getValue = function getValue() {
    var value = this.state.value;
    return value || [];
  };

  _proto.getSearchResult = function getSearchResult() {
    var _this$props5 = this.props,
        labelKey = _this$props5.labelKey,
        valueKey = _this$props5.valueKey,
        _this$props5$unchecka = _this$props5.uncheckableItemValues,
        uncheckableItemValues = _this$props5$unchecka === void 0 ? [] : _this$props5$unchecka;
    var _this$state = this.state,
        searchKeyword = _this$state.searchKeyword,
        flattenData = _this$state.flattenData;
    var items = [];
    var result = flattenData.filter(function (item) {
      if (uncheckableItemValues.some(function (value) {
        return item[valueKey] === value;
      })) {
        return false;
      }

      if (item[labelKey].match(new RegExp(searchKeyword, 'i'))) {
        return true;
      }

      return false;
    });

    for (var i = 0; i < result.length; i++) {
      items.push(result[i]);

      if (i === 99) {
        return items;
      }
    }

    return items;
  };

  _proto.renderSearchResultPanel = function renderSearchResultPanel() {
    var locale = this.props.locale;
    var searchKeyword = this.state.searchKeyword;

    if (searchKeyword === '') {
      return null;
    }

    var items = this.getSearchResult();
    return React.createElement("div", {
      className: this.addPrefix('cascader-search-panel')
    }, items.length ? items.map(this.renderSearchRow) : React.createElement("div", {
      className: this.addPrefix('none')
    }, locale.noResultsText));
  };

  _proto.renderDropdownMenu = function renderDropdownMenu() {
    var _this$state2 = this.state,
        items = _this$state2.items,
        activePaths = _this$state2.activePaths,
        searchKeyword = _this$state2.searchKeyword;
    var _this$props6 = this.props,
        renderMenu = _this$props6.renderMenu,
        placement = _this$props6.placement,
        searchPlaceholder = _this$props6.searchPlaceholder,
        renderExtraFooter = _this$props6.renderExtraFooter,
        menuClassName = _this$props6.menuClassName,
        menuStyle = _this$props6.menuStyle,
        classPrefix = _this$props6.classPrefix,
        searchable = _this$props6.searchable,
        locale = _this$props6.locale;
    var classes = (0, _classnames.default)(this.addPrefix('cascader-menu'), this.addPrefix('multi-cascader-menu'), this.addPrefix("placement-" + (0, _kebabCase2.default)(placement)), menuClassName);
    var menuProps = (0, _pick2.default)(this.props, _DropdownMenu.default.handledProps);
    return React.createElement(_picker.MenuWrapper, {
      className: classes,
      style: menuStyle
    }, searchable && React.createElement(_picker.SearchBar, {
      placeholder: searchPlaceholder || locale.searchPlaceholder,
      onChange: this.handleSearch,
      value: searchKeyword
    }), React.createElement(_DropdownMenu.default, (0, _extends3.default)({}, menuProps, {
      classPrefix: classPrefix,
      ref: this.bindMenuContainerRef,
      cascadeItems: items,
      cascadePathItems: activePaths,
      value: this.getValue(),
      onSelect: this.handleSelect,
      onCheck: this.handleCheck,
      renderMenu: renderMenu
    })), renderExtraFooter && renderExtraFooter());
  };

  _proto.render = function render() {
    var _this$props7 = this.props,
        valueKey = _this$props7.valueKey,
        labelKey = _this$props7.labelKey,
        childrenKey = _this$props7.childrenKey,
        placeholder = _this$props7.placeholder,
        renderValue = _this$props7.renderValue,
        disabled = _this$props7.disabled,
        cleanable = _this$props7.cleanable,
        locale = _this$props7.locale,
        toggleComponentClass = _this$props7.toggleComponentClass,
        style = _this$props7.style,
        onEnter = _this$props7.onEnter,
        onExited = _this$props7.onExited,
        onClean = _this$props7.onClean,
        countable = _this$props7.countable,
        cascade = _this$props7.cascade,
        rest = (0, _objectWithoutPropertiesLoose2.default)(_this$props7, ["valueKey", "labelKey", "childrenKey", "placeholder", "renderValue", "disabled", "cleanable", "locale", "toggleComponentClass", "style", "onEnter", "onExited", "onClean", "countable", "cascade"]);
    var flattenData = this.state.flattenData;
    var unhandled = (0, _utils3.getUnhandledProps)(Dropdown, rest);
    var value = this.getValue();
    var selectedItems = flattenData.filter(function (item) {
      return value.some(function (v) {
        return v === item[valueKey];
      });
    }) || [];
    var count = selectedItems.length;
    var hasValue = !!count;
    var selectedElement = placeholder;

    if (count > 0) {
      selectedElement = React.createElement(_picker.SelectedElement, {
        selectedItems: selectedItems,
        countable: countable,
        valueKey: valueKey,
        labelKey: labelKey,
        childrenKey: childrenKey,
        prefix: this.addPrefix,
        cascade: cascade,
        locale: locale
      });

      if (renderValue) {
        selectedElement = renderValue(value, selectedItems, selectedElement);
      }
    }

    var classes = (0, _picker.getToggleWrapperClassName)('cascader', this.addPrefix, this.props, hasValue);
    return React.createElement("div", {
      className: classes,
      style: style,
      tabIndex: -1,
      role: "menu",
      ref: this.bindContainerRef
    }, React.createElement(_picker.PickerToggleTrigger, {
      pickerProps: this.props,
      innerRef: this.bindTriggerRef,
      onEnter: (0, _utils3.createChainedFunction)(this.handleEntered, onEnter),
      onExit: (0, _utils3.createChainedFunction)(this.handleExit, onExited),
      speaker: this.renderDropdownMenu()
    }, React.createElement(_picker.PickerToggle, (0, _extends3.default)({}, unhandled, {
      componentClass: toggleComponentClass,
      onClean: (0, _utils3.createChainedFunction)(this.handleClean, onClean),
      cleanable: cleanable && !disabled,
      hasValue: hasValue,
      active: this.state.active
    }), selectedElement || locale.placeholder)));
  };

  return Dropdown;
}(React.Component);

(0, _defineProperty2.default)(Dropdown, "defaultProps", {
  cascade: true,
  appearance: 'default',
  data: [],
  disabledItemValues: [],
  uncheckableItemValues: [],
  childrenKey: 'children',
  valueKey: 'value',
  labelKey: 'label',
  locale: {
    placeholder: 'Select',
    checkAll: 'All',
    searchPlaceholder: 'Search',
    noResultsText: 'No results found'
  },
  cleanable: true,
  searchable: true,
  countable: true,
  placement: 'bottomLeft'
});
(0, _defineProperty2.default)(Dropdown, "utils", {});
(0, _defineProperty2.default)(Dropdown, "handledProps", ["activePaths", "appearance", "block", "cascade", "childrenKey", "className", "classPrefix", "cleanable", "container", "containerPadding", "countable", "data", "defaultOpen", "defaultValue", "disabled", "disabledItemValues", "labelKey", "locale", "menuClassName", "menuHeight", "menuStyle", "menuWidth", "onChange", "onClean", "onClose", "onEnter", "onEntered", "onEntering", "onExit", "onExited", "onExiting", "onHide", "onOpen", "onSearch", "onSelect", "open", "placeholder", "placement", "renderExtraFooter", "renderMenu", "renderMenuItem", "renderValue", "searchPlaceholder", "searchable", "style", "toggleComponentClass", "uncheckableItemValues", "value", "valueKey"]);
(0, _reactLifecyclesCompat.polyfill)(Dropdown);
var enhance = (0, _utils3.defaultProps)({
  classPrefix: 'picker'
});

var _default = enhance(Dropdown);

exports.default = _default;