import _extends from "@babel/runtime/helpers/extends";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
import _inherits from "@babel/runtime/helpers/inherits";
import _createSuper from "@babel/runtime/helpers/createSuper";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
var _excluded = ["prefixCls", "transitionName", "popupClassName", "options", "disabled", "builtinPlacements", "popupPlacement", "children", "locale", "menuMode", "singleMenuStyle", "singleMenuItemStyle"];
import React, { cloneElement, Component } from 'react';
import arrayTreeFilter from 'array-tree-filter';
import isEqual from 'shallowequal';
import Trigger from '../trigger';
import Icon from '../../icon';
import Menus from './Menus';
import MenusSingle from './MenusSingle';
import KeyCode from '../../_util/KeyCode';
import Locale from './locale/en_US';
export var defaultFieldNames = {
  label: 'label',
  value: 'value',
  children: 'children'
};
var BUILT_IN_PLACEMENTS = {
  bottomLeft: {
    points: ['tl', 'bl'],
    offset: [0, 4],
    overflow: {
      adjustX: 1,
      adjustY: 1
    }
  },
  topLeft: {
    points: ['bl', 'tl'],
    offset: [0, -4],
    overflow: {
      adjustX: 1,
      adjustY: 1
    }
  },
  bottomRight: {
    points: ['tr', 'br'],
    offset: [0, 4],
    overflow: {
      adjustX: 1,
      adjustY: 1
    }
  },
  topRight: {
    points: ['br', 'tr'],
    offset: [0, -4],
    overflow: {
      adjustX: 1,
      adjustY: 1
    }
  }
};

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

  var _super = _createSuper(Cascader);

  function Cascader(props) {
    var _this;

    _classCallCheck(this, Cascader);

    _this = _super.call(this, props);

    _defineProperty(_assertThisInitialized(_this), "setPopupVisible", function (popupVisible) {
      if (!('popupVisible' in _this.props)) {
        _this.setState({
          popupVisible: popupVisible
        });
      } // sync activeValue with value when panel open


      if (popupVisible && !_this.state.popupVisible) {
        _this.setState({
          activeValue: _this.state.value
        });
      }

      _this.props.onPopupVisibleChange(popupVisible);
    });

    _defineProperty(_assertThisInitialized(_this), "handleChange", function (options, setProps, e) {
      if (e.type !== 'keydown' || e.keyCode === KeyCode.ENTER) {
        var valueField = _this.getFieldName('value');

        _this.props.onChange(options.map(function (o) {
          return o[valueField];
        }), options);

        _this.setPopupVisible(setProps.visible);
      }
    });

    _defineProperty(_assertThisInitialized(_this), "handlePopupVisibleChange", function (popupVisible) {
      _this.setPopupVisible(popupVisible);
    });

    _defineProperty(_assertThisInitialized(_this), "handleMenuSelect", function (targetOption, menuIndex) {
      var isTabSelected = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
      var e = arguments.length > 3 ? arguments[3] : undefined;

      // Keep focused state for keyboard support
      var triggerNode = _this.trigger.getRootDomNode();

      if (triggerNode && triggerNode.focus) {
        triggerNode.focus();
      }

      var _this$props = _this.props,
          changeOnSelect = _this$props.changeOnSelect,
          loadData = _this$props.loadData,
          expandTrigger = _this$props.expandTrigger;

      if (!targetOption || targetOption.disabled) {
        return;
      }

      var activeValue = _this.state.activeValue;

      var valueField = _this.getFieldName('value');

      var childrenField = _this.getFieldName('children');

      activeValue = activeValue.slice(0, menuIndex + 1);
      activeValue[menuIndex] = targetOption[valueField];

      var activeOptions = _this.getActiveOptions(activeValue);

      if (targetOption.isLeaf === false && !targetOption[childrenField] && loadData) {
        if (changeOnSelect) {
          _this.handleChange(activeOptions, {
            visible: true
          }, e);
        }

        _this.setState({
          activeValue: activeValue,
          isTabSelected: isTabSelected
        });

        loadData(activeOptions);
        return;
      }

      var newState = {};

      if (!targetOption[childrenField] || !targetOption[childrenField].length) {
        _this.handleChange(activeOptions, {
          visible: false
        }, e); // set value to activeValue when select leaf option


        newState.value = activeValue; // add e.type judgement to prevent `onChange` being triggered by mouseEnter
      } else if (changeOnSelect && (e.type === 'click' || e.type === 'keydown')) {
        if (expandTrigger === 'hover') {
          _this.handleChange(activeOptions, {
            visible: false
          }, e);
        } else {
          _this.handleChange(activeOptions, {
            visible: true
          }, e);
        } // set value to activeValue on every select


        newState.value = activeValue;
      }

      newState.activeValue = activeValue; //  not change the value by keyboard

      if ('value' in _this.props || e.type === 'keydown' && e.keyCode !== KeyCode.ENTER) {
        delete newState.value;
      }

      newState.isTabSelected = isTabSelected;

      _this.setState(newState);
    });

    _defineProperty(_assertThisInitialized(_this), "handleKeyDown", function (e) {
      var children = _this.props.children; // Don't bind keyboard support when children specify the onKeyDown

      if (children && children.props.onKeyDown) {
        children.props.onKeyDown(e);
        return;
      }

      var activeValue = _toConsumableArray(_this.state.activeValue);

      var currentLevel = activeValue.length - 1 < 0 ? 0 : activeValue.length - 1;

      var currentOptions = _this.getCurrentLevelOptions();

      if (e.keyCode !== KeyCode.DOWN && e.keyCode !== KeyCode.UP && e.keyCode !== KeyCode.LEFT && e.keyCode !== KeyCode.RIGHT && e.keyCode !== KeyCode.ENTER && e.keyCode !== KeyCode.BACKSPACE && e.keyCode !== KeyCode.ESC) {
        return;
      } // Press any keys above to reopen menu


      if (!_this.state.popupVisible && e.keyCode !== KeyCode.BACKSPACE && e.keyCode !== KeyCode.LEFT && e.keyCode !== KeyCode.RIGHT && e.keyCode !== KeyCode.ESC) {
        _this.setPopupVisible(true);

        return;
      }

      var valueField = _this.getFieldName('value');

      var childrenField = _this.getFieldName('children');

      var currentIndex = currentOptions.map(function (o) {
        return o[valueField];
      }).indexOf(activeValue[currentLevel]);

      if (e.keyCode === KeyCode.DOWN || e.keyCode === KeyCode.UP) {
        var nextIndex = currentIndex;

        if (nextIndex !== -1) {
          if (e.keyCode === KeyCode.DOWN) {
            nextIndex += 1;
            nextIndex = nextIndex >= currentOptions.length ? 0 : nextIndex;
          } else {
            nextIndex -= 1;
            nextIndex = nextIndex < 0 ? currentOptions.length - 1 : nextIndex;
          }
        } else {
          nextIndex = 0;
        }

        activeValue[currentLevel] = currentOptions[nextIndex][valueField];
      } else if (e.keyCode === KeyCode.LEFT || e.keyCode === KeyCode.BACKSPACE) {
        activeValue.splice(activeValue.length - 1, 1);
      } else if (e.keyCode === KeyCode.RIGHT) {
        if (currentOptions[currentIndex] && currentOptions[currentIndex][childrenField]) {
          activeValue.push(currentOptions[currentIndex][childrenField][0][valueField]);
        }
      } else if (e.keyCode === KeyCode.ESC) {
        _this.setPopupVisible(false);

        return;
      }

      if (!activeValue || activeValue.length === 0) {
        _this.setPopupVisible(false);
      }

      var activeOptions = _this.getActiveOptions(activeValue);

      var targetOption = activeOptions[activeOptions.length - 1];

      _this.handleMenuSelect(targetOption, activeOptions.length - 1, false, e);

      if (_this.props.onKeyDown) {
        _this.props.onKeyDown(e);
      }
    });

    _defineProperty(_assertThisInitialized(_this), "saveTrigger", function (node) {
      _this.trigger = node;
    });

    var initialValue = [];

    if ('value' in props) {
      initialValue = props.value || [];
    } else if ('defaultValue' in props) {
      initialValue = props.defaultValue || [];
    }

    _this.state = {
      popupVisible: props.popupVisible,
      activeValue: initialValue,
      value: initialValue,
      isTabSelected: false
    };
    return _this;
  }

  _createClass(Cascader, [{
    key: "componentWillReceiveProps",
    value: function componentWillReceiveProps(nextProps) {
      if ('value' in nextProps && !isEqual(this.props.value, nextProps.value)) {
        var newValues = {
          value: nextProps.value || [],
          activeValue: nextProps.value || []
        }; // allow activeValue diff from value

        if ('loadData' in nextProps) {
          delete newValues.activeValue;
        }

        this.setState(newValues);
      }

      if ('popupVisible' in nextProps) {
        this.setState({
          popupVisible: nextProps.popupVisible
        });
      }
    }
  }, {
    key: "getPopupDOMNode",
    value: function getPopupDOMNode() {
      return this.trigger.getPopupDomNode();
    }
  }, {
    key: "getFieldName",
    value: function getFieldName(name) {
      var _this$props2 = this.props,
          fieldNames = _this$props2.fieldNames,
          filedNames = _this$props2.filedNames;

      if ('filedNames' in this.props) {
        return filedNames[name] || defaultFieldNames[name]; // For old compatibility
      }

      return fieldNames[name] || defaultFieldNames[name];
    }
  }, {
    key: "getFieldNames",
    value: function getFieldNames() {
      var _this$props3 = this.props,
          fieldNames = _this$props3.fieldNames,
          filedNames = _this$props3.filedNames;

      if ('filedNames' in this.props) {
        return filedNames; // For old compatibility
      }

      return fieldNames;
    }
  }, {
    key: "getCurrentLevelOptions",
    value: function getCurrentLevelOptions() {
      var options = this.props.options;
      var _this$state$activeVal = this.state.activeValue,
          activeValue = _this$state$activeVal === void 0 ? [] : _this$state$activeVal;
      var valueField = this.getFieldName('value');
      var childrenField = this.getFieldName('children');
      var result = arrayTreeFilter(options, function (o, level) {
        return o[valueField] === activeValue[level];
      }, {
        childrenKeyName: childrenField
      });

      if (result[result.length - 2]) {
        return result[result.length - 2][childrenField];
      }

      return _toConsumableArray(options).filter(function (o) {
        return !o.disabled;
      });
    }
  }, {
    key: "getActiveOptions",
    value: function getActiveOptions(activeValue) {
      var valueField = this.getFieldName('value');
      var childrenField = this.getFieldName('children');
      return arrayTreeFilter(this.props.options, function (o, level) {
        return o[valueField] === activeValue[level];
      }, {
        childrenKeyName: childrenField
      });
    }
  }, {
    key: "render",
    value: function render() {
      var _this$props4 = this.props,
          prefixCls = _this$props4.prefixCls,
          transitionName = _this$props4.transitionName,
          popupClassName = _this$props4.popupClassName,
          options = _this$props4.options,
          disabled = _this$props4.disabled,
          builtinPlacements = _this$props4.builtinPlacements,
          popupPlacement = _this$props4.popupPlacement,
          children = _this$props4.children,
          locale = _this$props4.locale,
          menuMode = _this$props4.menuMode,
          singleMenuStyle = _this$props4.singleMenuStyle,
          singleMenuItemStyle = _this$props4.singleMenuItemStyle,
          restProps = _objectWithoutProperties(_this$props4, _excluded); // Did not show popup when there is no options


      var menus = /*#__PURE__*/React.createElement("div", null);
      var emptyMenuClassName = '';

      if (options && options.length > 0) {
        if (menuMode === 'multiple') {
          menus = /*#__PURE__*/React.createElement(Menus, _extends({}, this.props, {
            fieldNames: this.getFieldNames(),
            defaultFieldNames: defaultFieldNames,
            value: this.state.value,
            activeValue: this.state.activeValue,
            onSelect: this.handleMenuSelect,
            visible: this.state.popupVisible
          }));
        } else if (menuMode === 'single') {
          menus = /*#__PURE__*/React.createElement(MenusSingle, _extends({}, this.props, {
            fieldNames: this.getFieldNames(),
            defaultFieldNames: defaultFieldNames,
            isTabSelected: this.state.isTabSelected,
            value: this.state.value,
            activeValue: this.state.activeValue,
            onSelect: this.handleMenuSelect,
            visible: this.state.popupVisible,
            locale: locale,
            singleMenuStyle: singleMenuStyle,
            singleMenuItemStyle: singleMenuItemStyle
          }));
        } else {
          throw new Error('please use correct mode for menu ex "single" and "multiple"');
        }
      } else {
        emptyMenuClassName = " ".concat(prefixCls, "-menus-empty");
      }

      return /*#__PURE__*/React.createElement(Trigger, _extends({
        ref: this.saveTrigger
      }, restProps, {
        options: options,
        disabled: disabled,
        popupPlacement: popupPlacement,
        builtinPlacements: builtinPlacements,
        popupTransitionName: transitionName,
        action: disabled ? [] : ['click'],
        popupVisible: disabled ? false : this.state.popupVisible,
        onPopupVisibleChange: this.handlePopupVisibleChange,
        prefixCls: "".concat(prefixCls, "-menus"),
        popupClassName: popupClassName + emptyMenuClassName,
        popup: menus
      }), /*#__PURE__*/cloneElement(children, {
        onKeyDown: this.handleKeyDown,
        tabIndex: disabled ? undefined : 0
      }));
    }
  }]);

  return Cascader;
}(Component);

_defineProperty(Cascader, "defaultProps", {
  options: [],
  onChange: function onChange() {},
  onPopupVisibleChange: function onPopupVisibleChange() {},
  disabled: false,
  transitionName: '',
  prefixCls: 'rc-cascader',
  popupClassName: '',
  popupPlacement: 'bottomLeft',
  builtinPlacements: BUILT_IN_PLACEMENTS,
  expandTrigger: 'click',
  fieldNames: defaultFieldNames,
  expandIcon: /*#__PURE__*/React.createElement(Icon, {
    type: "navigate_next"
  }),
  menuMode: 'multiple',
  locale: Locale
});

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