import * as _vue from "vue";

function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }

function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }

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(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

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; }

import { provide, inject } from 'vue';
import warning from '../_util/warning';
import omit from 'omit.js';
import PropTypes from '../_util/vue-types';
import { Select as VcSelect, Option, OptGroup } from '../vc-select';
import { ConfigConsumerProps } from '../config-provider';
import { getComponent, getOptionProps, isValidElement, getSlot } from '../_util/props-util';
import CloseOutlined from '@ant-design/icons-vue/CloseOutlined';
import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled';
import CheckOutlined from '@ant-design/icons-vue/CheckOutlined';
import DownOutlined from '@ant-design/icons-vue/DownOutlined';
import LoadingOutlined from '@ant-design/icons-vue/LoadingOutlined';
import { cloneElement } from '../_util/vnode';

var AbstractSelectProps = function AbstractSelectProps() {
  return {
    prefixCls: PropTypes.string,
    size: PropTypes.oneOf(['small', 'large', 'default']),
    showAction: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(String)]),
    notFoundContent: PropTypes.any,
    transitionName: PropTypes.string,
    choiceTransitionName: PropTypes.string,
    showSearch: PropTypes.bool,
    allowClear: PropTypes.bool,
    disabled: PropTypes.bool,
    tabindex: PropTypes.number,
    placeholder: PropTypes.any,
    defaultActiveFirstOption: PropTypes.bool,
    dropdownClassName: PropTypes.string,
    dropdownStyle: PropTypes.any,
    dropdownMenuStyle: PropTypes.any,
    dropdownMatchSelectWidth: PropTypes.bool,
    // onSearch: (value: string) => any,
    filterOption: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),
    autofocus: PropTypes.bool,
    backfill: PropTypes.bool,
    showArrow: PropTypes.bool,
    getPopupContainer: PropTypes.func,
    open: PropTypes.bool,
    defaultOpen: PropTypes.bool,
    autoClearSearchValue: PropTypes.bool,
    dropdownRender: PropTypes.func,
    loading: PropTypes.bool
  };
};

var Value = PropTypes.shape({
  key: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
}).loose;
var SelectValue = PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.arrayOf(PropTypes.oneOfType([Value, PropTypes.string, PropTypes.number])), Value]);

var SelectProps = _objectSpread(_objectSpread({}, AbstractSelectProps()), {}, {
  value: SelectValue,
  defaultValue: SelectValue,
  // mode: PropTypes.oneOf(['default', 'multiple', 'tags', 'combobox']),
  mode: PropTypes.string,
  optionLabelProp: PropTypes.string,
  firstActiveValue: PropTypes.oneOfType([String, PropTypes.arrayOf(String)]),
  maxTagCount: PropTypes.number,
  maxTagPlaceholder: PropTypes.any,
  maxTagTextLength: PropTypes.number,
  dropdownMatchSelectWidth: PropTypes.bool,
  optionFilterProp: PropTypes.string,
  labelInValue: PropTypes.boolean,
  getPopupContainer: PropTypes.func,
  tokenSeparators: PropTypes.arrayOf(PropTypes.string),
  getInputElement: PropTypes.func,
  options: PropTypes.array,
  suffixIcon: PropTypes.any,
  removeIcon: PropTypes.any,
  clearIcon: PropTypes.any,
  menuItemSelectedIcon: PropTypes.any
});

var SelectPropTypes = {
  prefixCls: PropTypes.string,
  size: PropTypes.oneOf(['default', 'large', 'small']),
  // combobox: PropTypes.bool,
  notFoundContent: PropTypes.any,
  showSearch: PropTypes.bool,
  optionLabelProp: PropTypes.string,
  transitionName: PropTypes.string,
  choiceTransitionName: PropTypes.string
};
export { AbstractSelectProps, SelectValue, SelectProps };
var SECRET_COMBOBOX_MODE_DO_NOT_USE = 'SECRET_COMBOBOX_MODE_DO_NOT_USE';
var Select = {
  SECRET_COMBOBOX_MODE_DO_NOT_USE: SECRET_COMBOBOX_MODE_DO_NOT_USE,
  Option: _objectSpread(_objectSpread({}, Option), {}, {
    name: 'ASelectOption'
  }),
  OptGroup: _objectSpread(_objectSpread({}, OptGroup), {}, {
    name: 'ASelectOptGroup'
  }),
  name: 'ASelect',
  props: _objectSpread(_objectSpread({}, SelectProps), {}, {
    showSearch: PropTypes.bool.def(false),
    transitionName: PropTypes.string.def('slide-up'),
    choiceTransitionName: PropTypes.string.def('zoom')
  }),
  propTypes: SelectPropTypes,
  setup: function setup() {
    return {
      configProvider: inject('configProvider', ConfigConsumerProps)
    };
  },
  created: function created() {
    provide('savePopupRef', this.savePopupRef);
    warning(this.$props.mode !== 'combobox', 'Select', 'The combobox mode of Select is deprecated,' + 'it will be removed in next major version,' + 'please use AutoComplete instead');
  },
  methods: {
    getNotFoundContent: function getNotFoundContent(renderEmpty) {
      var notFoundContent = getComponent(this, 'notFoundContent');

      if (notFoundContent !== undefined) {
        return notFoundContent;
      }

      if (this.isCombobox()) {
        return null;
      }

      return renderEmpty('Select');
    },
    savePopupRef: function savePopupRef(ref) {
      this.popupRef = ref;
    },
    focus: function focus() {
      this.$refs.vcSelect.focus();
    },
    blur: function blur() {
      this.$refs.vcSelect.blur();
    },
    isCombobox: function isCombobox() {
      var mode = this.mode;
      return mode === 'combobox' || mode === SECRET_COMBOBOX_MODE_DO_NOT_USE;
    },
    renderSuffixIcon: function renderSuffixIcon(prefixCls) {
      var loading = this.$props.loading;
      var suffixIcon = getComponent(this, 'suffixIcon');
      suffixIcon = Array.isArray(suffixIcon) ? suffixIcon[0] : suffixIcon;

      if (suffixIcon) {
        return isValidElement(suffixIcon) ? cloneElement(suffixIcon, {
          class: "".concat(prefixCls, "-arrow-icon")
        }) : suffixIcon;
      }

      if (loading) {
        return _vue.createVNode(LoadingOutlined, null, null);
      }

      return _vue.createVNode(DownOutlined, {
        "class": "".concat(prefixCls, "-arrow-icon")
      }, null);
    }
  },
  render: function render() {
    var _cls;

    var _getOptionProps = getOptionProps(this),
        customizePrefixCls = _getOptionProps.prefixCls,
        size = _getOptionProps.size,
        mode = _getOptionProps.mode,
        options = _getOptionProps.options,
        getPopupContainer = _getOptionProps.getPopupContainer,
        showArrow = _getOptionProps.showArrow,
        restProps = _objectWithoutProperties(_getOptionProps, ["prefixCls", "size", "mode", "options", "getPopupContainer", "showArrow"]);

    var className = this.$attrs.class;
    var getPrefixCls = this.configProvider.getPrefixCls;
    var renderEmpty = this.configProvider.renderEmpty;
    var prefixCls = getPrefixCls('select', customizePrefixCls);
    var getContextPopupContainer = this.configProvider.getPopupContainer;
    var removeIcon = getComponent(this, 'removeIcon');
    removeIcon = Array.isArray(removeIcon) ? removeIcon[0] : removeIcon;
    var clearIcon = getComponent(this, 'clearIcon');
    clearIcon = Array.isArray(clearIcon) ? clearIcon[0] : clearIcon;
    var menuItemSelectedIcon = getComponent(this, 'menuItemSelectedIcon');
    menuItemSelectedIcon = Array.isArray(menuItemSelectedIcon) ? menuItemSelectedIcon[0] : menuItemSelectedIcon;
    var rest = omit(restProps, ['inputIcon', 'removeIcon', 'clearIcon', 'suffixIcon', 'menuItemSelectedIcon']);
    var cls = (_cls = {}, _defineProperty(_cls, className, className), _defineProperty(_cls, "".concat(prefixCls, "-lg"), size === 'large'), _defineProperty(_cls, "".concat(prefixCls, "-sm"), size === 'small'), _defineProperty(_cls, "".concat(prefixCls, "-show-arrow"), showArrow), _cls);
    var optionLabelProp = this.$props.optionLabelProp;

    if (this.isCombobox()) {
      // children 带 dom 结构时，无法填入输入框
      optionLabelProp = optionLabelProp || 'value';
    }

    var modeConfig = {
      multiple: mode === 'multiple',
      tags: mode === 'tags',
      combobox: this.isCombobox()
    };

    var finalRemoveIcon = removeIcon && (isValidElement(removeIcon) ? cloneElement(removeIcon, {
      class: "".concat(prefixCls, "-remove-icon")
    }) : removeIcon) || _vue.createVNode(CloseOutlined, {
      "class": "".concat(prefixCls, "-remove-icon")
    }, null);

    var finalClearIcon = clearIcon && (isValidElement(clearIcon) ? cloneElement(clearIcon, {
      class: "".concat(prefixCls, "-clear-icon")
    }) : clearIcon) || _vue.createVNode(CloseCircleFilled, {
      "class": "".concat(prefixCls, "-clear-icon")
    }, null);

    var finalMenuItemSelectedIcon = menuItemSelectedIcon && (isValidElement(menuItemSelectedIcon) ? cloneElement(menuItemSelectedIcon, {
      class: "".concat(prefixCls, "-selected-icon")
    }) : menuItemSelectedIcon) || _vue.createVNode(CheckOutlined, {
      "class": "".concat(prefixCls, "-selected-icon")
    }, null);

    var selectProps = _objectSpread(_objectSpread(_objectSpread(_objectSpread({
      inputIcon: this.renderSuffixIcon(prefixCls),
      removeIcon: finalRemoveIcon,
      clearIcon: finalClearIcon,
      menuItemSelectedIcon: finalMenuItemSelectedIcon,
      showArrow: showArrow
    }, rest), modeConfig), {}, {
      prefixCls: prefixCls,
      optionLabelProp: optionLabelProp || 'children',
      notFoundContent: this.getNotFoundContent(renderEmpty),
      maxTagPlaceholder: getComponent(this, 'maxTagPlaceholder'),
      placeholder: getComponent(this, 'placeholder'),
      children: options ? options.map(function (option) {
        var key = option.key,
            _option$label = option.label,
            label = _option$label === void 0 ? option.title : _option$label,
            cls = option.class,
            style = option.style,
            restOption = _objectWithoutProperties(option, ["key", "label", "class", "style"]);

        return _vue.createVNode(Option, _vue.mergeProps(_objectSpread({
          class: cls,
          style: style
        }, restOption), {
          "key": key
        }), {
          default: function _default() {
            return [label];
          }
        });
      }) : getSlot(this),
      dropdownRender: getComponent(this, 'dropdownRender', {}, false),
      getPopupContainer: getPopupContainer || getContextPopupContainer
    }, this.$attrs), {}, {
      class: cls,
      ref: 'vcSelect'
    });

    return _vue.createVNode(VcSelect, _vue.mergeProps(selectProps, {
      "__propsSymbol__": []
    }), null);
  }
};
/* istanbul ignore next */

Select.install = function (app) {
  app.component(Select.name, Select);
  app.component(Select.Option.name, Select.Option);
  app.component(Select.OptGroup.name, Select.OptGroup);
};

export default Select;