ant-design-vue
Version:
An enterprise-class UI design language and Vue-based implementation
1,553 lines (1,457 loc) • 57.1 kB
JavaScript
import _mergeJSXProps from 'babel-helper-vue-jsx-merge-props';
import _defineProperty from 'babel-runtime/helpers/defineProperty';
import _extends from 'babel-runtime/helpers/extends';
import KeyCode from '../_util/KeyCode';
import PropTypes from '../_util/vue-types';
import classnames from 'classnames';
import classes from 'component-classes';
import { Item as MenuItem, ItemGroup as MenuItemGroup } from '../vc-menu';
import warning from 'warning';
import Vue from 'vue';
import Option from './Option';
import { hasProp, getSlotOptions, getPropsData, getValueByProp as getValue, getComponentFromProp, getEvents, getClass, getStyle, getAttrs, getOptionProps } from '../_util/props-util';
import getTransitionProps from '../_util/getTransitionProps';
import { cloneElement } from '../_util/vnode';
import BaseMixin from '../_util/BaseMixin';
import proxyComponent from '../_util/proxyComponent';
import antRefDirective from '../_util/antRefDirective';
Vue.use(antRefDirective);
import { getPropValue, getValuePropValue, isCombobox, isMultipleOrTags, isMultipleOrTagsOrCombobox, isSingleMode, toArray, getMapKey, findIndexInValueBySingleValue, getLabelFromPropsValue, UNSELECTABLE_ATTRIBUTE, UNSELECTABLE_STYLE, preventDefaultEvent, findFirstMenuItem, includesSeparators, splitBySeparators, defaultFilterFn, validateOptionValue, saveRef, toTitle } from './util';
import SelectTrigger from './SelectTrigger';
import { SelectPropTypes } from './PropTypes';
function noop() {}
function chaining() {
for (var _len = arguments.length, fns = Array(_len), _key = 0; _key < _len; _key++) {
fns[_key] = arguments[_key];
}
return function () {
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
// eslint-disable-line
// eslint-disable-line
for (var i = 0; i < fns.length; i++) {
if (fns[i] && typeof fns[i] === 'function') {
fns[i].apply(this, args);
}
}
};
}
var Select = {
inheritAttrs: false,
name: 'Select',
mixins: [BaseMixin],
props: _extends({}, SelectPropTypes, {
prefixCls: SelectPropTypes.prefixCls.def('rc-select'),
defaultOpen: PropTypes.bool.def(false),
labelInValue: SelectPropTypes.labelInValue.def(false),
defaultActiveFirstOption: SelectPropTypes.defaultActiveFirstOption.def(true),
showSearch: SelectPropTypes.showSearch.def(true),
allowClear: SelectPropTypes.allowClear.def(false),
placeholder: SelectPropTypes.placeholder.def(''),
showArrow: SelectPropTypes.showArrow.def(true),
dropdownMatchSelectWidth: PropTypes.bool.def(true),
dropdownStyle: SelectPropTypes.dropdownStyle.def({}),
dropdownMenuStyle: PropTypes.object.def({}),
optionFilterProp: SelectPropTypes.optionFilterProp.def('value'),
optionLabelProp: SelectPropTypes.optionLabelProp.def('value'),
notFoundContent: PropTypes.any.def('Not Found'),
backfill: PropTypes.bool.def(false),
showAction: SelectPropTypes.showAction.def(['click']),
combobox: PropTypes.bool.def(false),
tokenSeparators: PropTypes.arrayOf(PropTypes.string).def([]),
autoClearSearchValue: PropTypes.bool.def(true)
// onChange: noop,
// onFocus: noop,
// onBlur: noop,
// onSelect: noop,
// onSearch: noop,
// onDeselect: noop,
// onInputKeydown: noop,
}),
model: {
prop: 'value',
event: 'change'
},
created: function created() {
this.saveInputRef = saveRef(this, 'inputRef');
this.saveInputMirrorRef = saveRef(this, 'inputMirrorRef');
this.saveTopCtrlRef = saveRef(this, 'topCtrlRef');
this.saveSelectTriggerRef = saveRef(this, 'selectTriggerRef');
this.saveRootRef = saveRef(this, 'rootRef');
this.saveSelectionRef = saveRef(this, 'selectionRef');
},
data: function data() {
var props = getOptionProps(this);
var optionsInfo = this.getOptionsInfoFromProps(props);
warning(this.__propsSymbol__, 'Replace slots.default with props.children and pass props.__propsSymbol__');
return {
_value: this.getValueFromProps(props, true), // true: use default value
_inputValue: props.combobox ? this.getInputValueForCombobox(props, optionsInfo, true // use default value
) : '',
_open: props.defaultOpen,
_optionsInfo: optionsInfo,
// a flag for aviod redundant getOptionsInfoFromProps call
_skipBuildOptionsInfo: true
};
},
beforeMount: function beforeMount() {
var state = this.getDerivedStateFromProps(getOptionProps(this), this.$data);
_extends(this.$data, state);
},
mounted: function mounted() {
var _this = this;
this.$nextTick(function () {
_this.autoFocus && _this.focus();
});
},
watch: {
__propsSymbol__: function __propsSymbol__() {
_extends(this.$data, this.getDerivedStateFromProps(getOptionProps(this), this.$data));
}
},
updated: function updated() {
var _this2 = this;
this.$nextTick(function () {
if (isMultipleOrTags(_this2.$props)) {
var inputNode = _this2.getInputDOMNode();
var mirrorNode = _this2.getInputMirrorDOMNode();
if (inputNode.value) {
inputNode.style.width = '';
inputNode.style.width = mirrorNode.clientWidth + 10 + 'px';
} else {
inputNode.style.width = '';
}
}
_this2.forcePopupAlign();
});
},
beforeDestroy: function beforeDestroy() {
this.clearFocusTime();
this.clearBlurTime();
if (this.dropdownContainer) {
document.body.removeChild(this.dropdownContainer);
this.dropdownContainer = null;
}
},
methods: {
getDerivedStateFromProps: function getDerivedStateFromProps(nextProps, prevState) {
var optionsInfo = prevState._skipBuildOptionsInfo ? prevState._optionsInfo : this.getOptionsInfoFromProps(nextProps, prevState);
var newState = {
_optionsInfo: optionsInfo,
_skipBuildOptionsInfo: false
};
if ('open' in nextProps) {
newState._open = nextProps.open;
}
if ('value' in nextProps) {
var value = this.getValueFromProps(nextProps);
newState._value = value;
if (nextProps.combobox) {
newState._inputValue = this.getInputValueForCombobox(nextProps, optionsInfo);
}
}
return newState;
},
// initLabelAndTitleMap (sValue) {
// // 保留已选中的label and title
// const labelArr = []
// const titleArr = []
// const values = sValue || this.sValue
// values.forEach((val) => {
// const key = val.key
// let { label, title } = val
// label = label === undefined ? this.labelMap.get(key) : label
// title = title === undefined ? this.titleMap.get(key) : title
// title = typeof title === 'string' ? title.trim() : title
// labelArr.push([key, label === undefined ? key : label])
// titleArr.push([key, title])
// })
// this.labelMap = new Map(labelArr)
// this.titleMap = new Map(titleArr)
// this.updateLabelAndTitleMap(this.$props.children)
// },
// updateLabelAndTitleMap (children = []) {
// children.forEach(child => {
// if (!child.data || child.data.slot !== undefined) {
// return
// }
// if (getSlotOptions(child).isSelectOptGroup) {
// this.updateLabelAndTitleMap(child.componentOptions.children)
// } else {
// const key = getValuePropValue(child)
// this.titleMap.set(key, getValue(child, 'title'))
// this.labelMap.set(key, this.getLabelFromOption(child))
// }
// })
// },
onInputChange: function onInputChange(event) {
var tokenSeparators = this.$props.tokenSeparators;
var val = event.target.value;
if (isMultipleOrTags(this.$props) && tokenSeparators.length && includesSeparators(val, tokenSeparators)) {
var nextValue = this.getValueByInput(val);
if (nextValue !== undefined) {
this.fireChange(nextValue);
}
this.setOpenState(false, true);
this.setInputValue('', false);
return;
}
this.setInputValue(val);
this.setState({
_open: true
});
if (isCombobox(this.$props)) {
this.fireChange([val]);
}
},
onDropdownVisibleChange: function onDropdownVisibleChange(open) {
if (open && !this._focused) {
this.clearBlurTime();
this.timeoutFocus();
this._focused = true;
this.updateFocusClassName();
}
this.setOpenState(open);
},
// combobox ignore
onKeyDown: function onKeyDown(event) {
var props = this.$props;
if (props.disabled) {
return;
}
var keyCode = event.keyCode;
if (this.$data._open && !this.getInputDOMNode()) {
this.onInputKeydown(event);
} else if (keyCode === KeyCode.ENTER || keyCode === KeyCode.DOWN) {
// vue state是同步更新,onKeyDown在onMenuSelect后会再次调用,单选时不在调用setOpenState
if (keyCode === KeyCode.ENTER && !isMultipleOrTags(props)) {
this.maybeFocus(true);
} else {
this.setOpenState(true);
}
event.preventDefault();
}
},
onInputKeydown: function onInputKeydown(event) {
var props = this.$props;
if (props.disabled) {
return;
}
var state = this.$data;
var keyCode = event.keyCode;
if (isMultipleOrTags(props) && !event.target.value && keyCode === KeyCode.BACKSPACE) {
event.preventDefault();
var value = state._value;
if (value.length) {
this.removeSelected(value[value.length - 1]);
}
return;
}
if (keyCode === KeyCode.DOWN) {
if (!state._open) {
this.openIfHasChildren();
event.preventDefault();
event.stopPropagation();
return;
}
} else if (keyCode === KeyCode.ENTER && state._open) {
// Aviod trigger form submit when select item
// https://github.com/ant-design/ant-design/issues/10861
event.preventDefault();
} else if (keyCode === KeyCode.ESC) {
if (state._open) {
this.setOpenState(false);
event.preventDefault();
event.stopPropagation();
}
return;
}
if (state._open) {
var menu = this.selectTriggerRef.getInnerMenu();
if (menu && menu.onKeyDown(event, this.handleBackfill)) {
event.preventDefault();
event.stopPropagation();
}
}
},
onMenuSelect: function onMenuSelect(_ref) {
var item = _ref.item;
if (!item) {
return;
}
var value = this.$data._value;
var props = this.$props;
var selectedValue = getValuePropValue(item);
var lastValue = value[value.length - 1];
this.fireSelect(selectedValue);
if (isMultipleOrTags(props)) {
if (findIndexInValueBySingleValue(value, selectedValue) !== -1) {
return;
}
value = value.concat([selectedValue]);
} else {
if (lastValue && lastValue === selectedValue && selectedValue !== this.$data._backfillValue) {
this.setOpenState(false, true);
return;
}
value = [selectedValue];
this.setOpenState(false, true);
}
this.fireChange(value);
var inputValue = void 0;
if (isCombobox(props)) {
inputValue = getPropValue(item, props.optionLabelProp);
} else {
inputValue = '';
}
if (props.autoClearSearchValue) {
this.setInputValue(inputValue, false);
}
},
onMenuDeselect: function onMenuDeselect(_ref2) {
var item = _ref2.item,
domEvent = _ref2.domEvent;
if (domEvent.type === 'click') {
this.removeSelected(getValuePropValue(item));
}
if (this.autoClearSearchValue) {
this.setInputValue('', false);
}
},
onArrowClick: function onArrowClick(e) {
e.stopPropagation();
e.preventDefault();
if (!this.disabled) {
this.setOpenState(!this.$data._open, !this.$data._open);
}
},
onPlaceholderClick: function onPlaceholderClick(e) {
// if (this.openStatus) {
// e.stopPropagation()
// }
if (this.getInputDOMNode()) {
this.getInputDOMNode().focus();
}
},
// onOuterFocus (e) {
// if (this.disabled) {
// e.preventDefault()
// return
// }
// this.clearBlurTime()
// if (
// !isMultipleOrTagsOrCombobox(this.$props) &&
// e.target === this.getInputDOMNode()
// ) {
// return
// }
// if (this._focused) {
// return
// }
// this._focused = true
// this.updateFocusClassName()
// this.timeoutFocus()
// },
onPopupFocus: function onPopupFocus() {
// fix ie scrollbar, focus element again
this.maybeFocus(true, true);
},
// onOuterBlur (e) {
// if (this.disabled) {
// e.preventDefault()
// return
// }
// this.blurTimer = setTimeout(() => {
// this._focused = false
// this.updateFocusClassName()
// const props = this.$props
// let { sValue } = this
// const { inputValue } = this
// if (
// isSingleMode(props) &&
// props.showSearch &&
// inputValue &&
// props.defaultActiveFirstOption
// ) {
// const options = this._options || []
// if (options.length) {
// const firstOption = findFirstMenuItem(options)
// if (firstOption) {
// sValue = [
// {
// key: firstOption.key,
// label: this.getLabelFromOption(firstOption),
// },
// ]
// this.fireChange(sValue)
// }
// }
// } else if (isMultipleOrTags(props) && inputValue) {
// this.inputValue = this.getInputDOMNode().value = ''
// }
// this.$emit('blur', this.getVLForOnChange(sValue))
// this.setOpenState(false)
// }, 10)
// },
onClearSelection: function onClearSelection(event) {
var props = this.$props;
var state = this.$data;
if (props.disabled) {
return;
}
var inputValue = state._inputValue,
value = state._value;
event.stopPropagation();
if (inputValue || value.length) {
if (value.length) {
this.fireChange([]);
}
this.setOpenState(false, true);
if (inputValue) {
this.setInputValue('');
}
}
},
onChoiceAnimationLeave: function onChoiceAnimationLeave() {
this.forcePopupAlign();
},
getOptionsFromChildren: function getOptionsFromChildren() {
var _this3 = this;
var children = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
children.forEach(function (child) {
if (!child.data || child.data.slot !== undefined) {
return;
}
if (getSlotOptions(child).isSelectOptGroup) {
_this3.getOptionsFromChildren(child.componentOptions.children, options);
} else {
options.push(child);
}
});
return options;
},
getInputValueForCombobox: function getInputValueForCombobox(props, optionsInfo, useDefaultValue) {
var value = [];
if ('value' in props && !useDefaultValue) {
value = toArray(props.value);
}
if ('defaultValue' in props && useDefaultValue) {
value = toArray(props.defaultValue);
}
if (value.length) {
value = value[0];
} else {
return '';
}
var label = value;
if (props.labelInValue) {
label = value.label;
} else if (optionsInfo[getMapKey(value)]) {
label = optionsInfo[getMapKey(value)].label;
}
if (label === undefined) {
label = '';
}
return label;
},
getLabelFromOption: function getLabelFromOption(props, option) {
return getPropValue(option, props.optionLabelProp);
},
getOptionsInfoFromProps: function getOptionsInfoFromProps(props, preState) {
var _this4 = this;
var options = this.getOptionsFromChildren(this.$props.children);
var optionsInfo = {};
options.forEach(function (option) {
var singleValue = getValuePropValue(option);
optionsInfo[getMapKey(singleValue)] = {
option: option,
value: singleValue,
label: _this4.getLabelFromOption(props, option),
title: getValue(option, 'title')
};
});
if (preState) {
// keep option info in pre state value.
var oldOptionsInfo = preState._optionsInfo;
var value = preState._value;
value.forEach(function (v) {
var key = getMapKey(v);
if (!optionsInfo[key] && oldOptionsInfo[key] !== undefined) {
optionsInfo[key] = oldOptionsInfo[key];
}
});
}
return optionsInfo;
},
getValueFromProps: function getValueFromProps(props, useDefaultValue) {
var value = [];
if ('value' in props && !useDefaultValue) {
value = toArray(props.value);
}
if ('defaultValue' in props && useDefaultValue) {
value = toArray(props.defaultValue);
}
if (props.labelInValue) {
value = value.map(function (v) {
return v.key;
});
}
return value;
},
getOptionInfoBySingleValue: function getOptionInfoBySingleValue(value, optionsInfo) {
var h = this.$createElement;
var info = void 0;
optionsInfo = optionsInfo || this.$data._optionsInfo;
if (optionsInfo[getMapKey(value)]) {
info = optionsInfo[getMapKey(value)];
}
if (info) {
return info;
}
var defaultLabel = value;
if (this.$props.labelInValue) {
var label = getLabelFromPropsValue(this.$props.value, value);
if (label !== undefined) {
defaultLabel = label;
}
}
var defaultInfo = {
option: h(
Option,
{
attrs: { value: value },
key: value },
[value]
),
value: value,
label: defaultLabel
};
return defaultInfo;
},
getOptionBySingleValue: function getOptionBySingleValue(value) {
var _getOptionInfoBySingl = this.getOptionInfoBySingleValue(value),
option = _getOptionInfoBySingl.option;
return option;
},
getOptionsBySingleValue: function getOptionsBySingleValue(values) {
var _this5 = this;
return values.map(function (value) {
return _this5.getOptionBySingleValue(value);
});
},
// getSingleOptionByValueKey (key) {
// return this.getOptionsFromChildren({
// key,
// label: key,
// }, this.$props.children)
// },
// getOptionsByValue (value) {
// if (value === undefined) {
// return undefined
// }
// if (value.length === 0) {
// return []
// }
// return this.getOptionsFromChildren(value, this.$props.children)
// },
// getLabelBySingleValue (children = [], value) {
// if (value === undefined) {
// return null
// }
// let label = null
// children.forEach(child => {
// if (!child.data || child.data.slot !== undefined) {
// return
// }
// if (getSlotOptions(child).isSelectOptGroup) {
// const maybe = this.getLabelBySingleValue(child.componentOptions.children, value)
// if (maybe !== null) {
// label = maybe
// }
// } else if (getValuePropValue(child) === value) {
// label = this.getLabelFromOption(child)
// }
// })
// return label
// },
getValueByLabel: function getValueByLabel(label) {
var _this6 = this;
if (label === undefined) {
return null;
}
var value = null;
Object.keys(this.$data._optionsInfo).forEach(function (key) {
var info = _this6.$data._optionsInfo[key];
if (toArray(info.label).join('') === label) {
value = info.value;
}
});
return value;
},
// getValueByLabel (children = [], label) {
// if (label === undefined) {
// return null
// }
// let value = null
// children.forEach(child => {
// if (!child.data || child.data.slot !== undefined) {
// return
// }
// if (getSlotOptions(child).isSelectOptGroup) {
// const maybe = this.getValueByLabel(child.componentOptions.children, label)
// if (maybe !== null) {
// value = maybe
// }
// } else if (toArray(this.getLabelFromOption(child)).join('') === label) {
// value = getValuePropValue(child)
// }
// })
// return value
// },
// getLabelFromOption (child) {
// let label = getPropValue(child, this.optionLabelProp)
// if (Array.isArray(label) && label.length === 1 && !label[0].tag) {
// label = label[0].text
// }
// return label
// },
getVLBySingleValue: function getVLBySingleValue(value) {
if (this.$props.labelInValue) {
return {
key: value,
label: this.getLabelBySingleValue(value)
};
}
return value;
},
// getLabelFromProps (value) {
// return this.getLabelByValue(this.$props.children || [], value)
// },
getVLForOnChange: function getVLForOnChange(vls_) {
var _this7 = this;
var vls = vls_;
if (vls !== undefined) {
if (!this.labelInValue) {
vls = vls.map(function (v) {
return v;
});
} else {
vls = vls.map(function (vl) {
return {
key: vl,
label: _this7.getLabelBySingleValue(vl)
};
});
}
return isMultipleOrTags(this.$props) ? vls : vls[0];
}
return vls;
},
getLabelBySingleValue: function getLabelBySingleValue(value, optionsInfo) {
var _getOptionInfoBySingl2 = this.getOptionInfoBySingleValue(value, optionsInfo),
label = _getOptionInfoBySingl2.label;
return label;
},
// getLabelByValue (children, value) {
// const label = this.getLabelBySingleValue(children, value)
// if (label === null) {
// return value
// }
// return label
// },
getDropdownContainer: function getDropdownContainer() {
if (!this.dropdownContainer) {
this.dropdownContainer = document.createElement('div');
document.body.appendChild(this.dropdownContainer);
}
return this.dropdownContainer;
},
getPlaceholderElement: function getPlaceholderElement() {
var h = this.$createElement;
var props = this.$props,
state = this.$data;
var hidden = false;
if (state._inputValue) {
hidden = true;
}
if (state._value.length) {
hidden = true;
}
if (isCombobox(props) && state._value.length === 1 && !state._value[0]) {
hidden = false;
}
var placeholder = props.placeholder;
if (placeholder) {
var p = {
on: {
mousedown: preventDefaultEvent,
click: this.onPlaceholderClick
},
attrs: UNSELECTABLE_ATTRIBUTE,
style: _extends({
display: hidden ? 'none' : 'block'
}, UNSELECTABLE_STYLE),
'class': props.prefixCls + '-selection__placeholder'
};
return h(
'div',
p,
[placeholder]
);
}
return null;
},
inputClick: function inputClick(e) {
if (this.$data._open) {
this.clearBlurTime();
e.stopPropagation();
} else {
this._focused = false;
}
},
inputBlur: function inputBlur(e) {
var _this8 = this;
this.clearBlurTime();
if (this.disabled) {
return;
}
this.blurTimer = setTimeout(function () {
_this8._focused = false;
_this8.updateFocusClassName();
var props = _this8.$props;
var value = _this8.$data._value;
var inputValue = _this8.$data._inputValue;
if (isSingleMode(props) && props.showSearch && inputValue && props.defaultActiveFirstOption) {
var options = _this8._options || [];
if (options.length) {
var firstOption = findFirstMenuItem(options);
if (firstOption) {
value = [getValuePropValue(firstOption)];
_this8.fireChange(value);
}
}
} else if (isMultipleOrTags(props) && inputValue) {
_this8.$data._inputValue = _this8.getInputDOMNode().value = '';
value = _this8.getValueByInput(inputValue);
if (value !== undefined) {
_this8.fireChange(value);
}
}
_this8.$emit('blur', _this8.getVLForOnChange(value));
_this8.setOpenState(false);
}, 10);
},
inputFocus: function inputFocus(e) {
this.clearBlurTime();
this.clearFocusTime();
this.timeoutFocus();
},
_getInputElement: function _getInputElement() {
var h = this.$createElement;
var props = this.$props;
var inputValue = this.$data._inputValue;
var attrs = getAttrs(this);
var inputElement = props.getInputElement ? props.getInputElement() : h('input', {
attrs: { id: attrs.id, autoComplete: 'off' }
});
var inputCls = classnames(getClass(inputElement), _defineProperty({}, props.prefixCls + '-search__field', true));
var inputEvents = getEvents(inputElement);
// https://github.com/ant-design/ant-design/issues/4992#issuecomment-281542159
// Add space to the end of the inputValue as the width measurement tolerance
inputElement.data = inputElement.data || {};
return h(
'div',
{ 'class': props.prefixCls + '-search__field__wrap', on: {
'click': this.inputClick
}
},
[cloneElement(inputElement, {
props: {
disabled: props.disabled,
value: inputValue
},
attrs: _extends({}, inputElement.data.attrs || {}, {
disabled: props.disabled,
value: inputValue
}),
domProps: {
value: inputValue
},
'class': inputCls,
directives: [{
name: 'ant-ref',
value: this.saveInputRef
}],
on: {
input: this.onInputChange,
keydown: chaining(this.onInputKeydown, inputEvents.keydown, this.$listeners.inputKeydown),
focus: chaining(this.inputFocus, inputEvents.focus),
blur: chaining(this.inputBlur, inputEvents.blur)
}
}), h(
'span',
_mergeJSXProps([{ directives: [{
name: 'ref',
value: this.saveInputMirrorRef
}] }, {
// ref='inputMirrorRef'
'class': props.prefixCls + '-search__field__mirror'
}]),
[inputValue, '\xA0']
)]
);
},
getInputDOMNode: function getInputDOMNode() {
return this.topCtrlRef ? this.topCtrlRef.querySelector('input,textarea,div[contentEditable]') : this.inputRef;
},
getInputMirrorDOMNode: function getInputMirrorDOMNode() {
return this.inputMirrorRef;
},
getPopupDOMNode: function getPopupDOMNode() {
return this.selectTriggerRef.getPopupDOMNode();
},
getPopupMenuComponent: function getPopupMenuComponent() {
return this.selectTriggerRef.getInnerMenu();
},
setOpenState: function setOpenState(open, needFocus) {
var _this9 = this;
var props = this.$props,
state = this.$data;
if (state._open === open) {
this.maybeFocus(open, needFocus);
return;
}
var nextState = {
_open: open,
_backfillValue: undefined
// clear search input value when open is false in singleMode.
};if (!open && isSingleMode(props) && props.showSearch) {
this.setInputValue('', false);
}
if (!open) {
this.maybeFocus(open, needFocus);
}
this.setState(nextState, function () {
if (open) {
_this9.maybeFocus(open, needFocus);
}
});
},
setInputValue: function setInputValue(inputValue) {
var fireSearch = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
if (inputValue !== this.$data._inputValue) {
this.setState({
_inputValue: inputValue
}, this.forcePopupAlign);
if (fireSearch) {
this.$emit('search', inputValue);
}
}
},
getValueByInput: function getValueByInput(string) {
var _this10 = this;
var _$props = this.$props,
multiple = _$props.multiple,
tokenSeparators = _$props.tokenSeparators;
var nextValue = this.$data._value;
var hasNewValue = false;
splitBySeparators(string, tokenSeparators).forEach(function (label) {
var selectedValue = [label];
if (multiple) {
var value = _this10.getValueByLabel(label);
if (value && findIndexInValueBySingleValue(nextValue, value) === -1) {
nextValue = nextValue.concat(value);
hasNewValue = true;
_this10.fireSelect(value);
}
} else {
// tag
if (findIndexInValueBySingleValue(nextValue, label) === -1) {
nextValue = nextValue.concat(selectedValue);
hasNewValue = true;
_this10.fireSelect(label);
}
}
});
return hasNewValue ? nextValue : undefined;
},
getRealOpenState: function getRealOpenState() {
var open = this.$data._open;
var options = this._options || [];
if (isMultipleOrTagsOrCombobox(this.$props) || !this.$props.showSearch) {
if (open && !options.length) {
open = false;
}
}
return open;
},
// getValueByInput (string) {
// const { multiple, tokenSeparators, $slots } = this
// let nextValue = this.sValue
// splitBySeparators(string, tokenSeparators).forEach(label => {
// const selectedValue = { key: label, label }
// if (findIndexInValueByLabel(nextValue, label) === -1) {
// if (multiple) {
// const value = this.getValueByLabel($props.children, label)
// if (value) {
// selectedValue.key = value
// nextValue = nextValue.concat(selectedValue)
// }
// } else {
// nextValue = nextValue.concat(selectedValue)
// }
// }
// this.fireSelect({
// key: label,
// label,
// })
// })
// return nextValue
// },
focus: function focus() {
if (isSingleMode(this.$props)) {
this.selectionRef.focus();
} else {
this.getInputDOMNode().focus();
}
},
blur: function blur() {
if (isSingleMode(this.$props)) {
this.selectionRef.blur();
} else {
this.getInputDOMNode().blur();
}
},
handleBackfill: function handleBackfill(item) {
if (!this.backfill || !(isSingleMode(this.$props) || isCombobox(this.$props))) {
return;
}
var key = getValuePropValue(item);
if (isCombobox(this.$props)) {
this.setInputValue(key, false);
}
this.setState({
_value: [key],
_backfillValue: key
});
},
_filterOption: function _filterOption(input, child) {
var defaultFilter = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : defaultFilterFn;
var _$data = this.$data,
value = _$data._value,
backfillValue = _$data._backfillValue;
var lastValue = value[value.length - 1];
if (!input || lastValue && lastValue === backfillValue) {
return true;
}
var filterFn = this.$props.filterOption;
if (hasProp(this, 'filterOption')) {
if (this.filterOption === true) {
filterFn = defaultFilter;
}
} else {
filterFn = defaultFilter;
}
if (!filterFn) {
return true;
} else if (typeof filterFn === 'function') {
return filterFn.call(this, input, child);
} else if (getValue(child, 'disabled')) {
return false;
}
return true;
},
timeoutFocus: function timeoutFocus() {
var _this11 = this;
if (this.focusTimer) {
this.clearFocusTime();
}
this.focusTimer = setTimeout(function () {
_this11._focused = true;
_this11.updateFocusClassName();
_this11.$emit('focus');
}, 10);
},
clearFocusTime: function clearFocusTime() {
if (this.focusTimer) {
clearTimeout(this.focusTimer);
this.focusTimer = null;
}
},
clearBlurTime: function clearBlurTime() {
if (this.blurTimer) {
clearTimeout(this.blurTimer);
this.blurTimer = null;
}
},
updateFocusClassName: function updateFocusClassName() {
var rootRef = this.rootRef,
prefixCls = this.prefixCls;
// avoid setState and its side effect
if (this._focused) {
classes(rootRef).add(prefixCls + '-focused');
} else {
classes(rootRef).remove(prefixCls + '-focused');
}
},
maybeFocus: function maybeFocus(open, needFocus) {
if (needFocus || open) {
var input = this.getInputDOMNode();
var _document = document,
activeElement = _document.activeElement;
if (input && (open || isMultipleOrTagsOrCombobox(this.$props))) {
if (activeElement !== input) {
input.focus();
this._focused = true;
}
} else {
if (activeElement !== this.selectionRef) {
this.selectionRef.focus();
this._focused = true;
}
}
}
},
// addLabelToValue (value_) {
// let value = value_
// if (this.labelInValue) {
// value.forEach(v => {
// v.label = v.label || this.getLabelFromProps(v.key)
// })
// } else {
// value = value.map(v => {
// return {
// key: v,
// label: this.getLabelFromProps(v),
// }
// })
// }
// return value
// },
// addTitleToValue (children = [], values) {
// let nextValues = values
// const keys = values.map(v => v.key)
// children.forEach(child => {
// if (!child) {
// return
// }
// if (getSlotOptions(child).isSelectOptGroup) {
// nextValues = this.addTitleToValue(child.componentOptions.children, nextValues)
// } else {
// const value = getValuePropValue(child)
// const valueIndex = keys.indexOf(value)
// if (valueIndex > -1) {
// nextValues[valueIndex].title = getValue(child, 'title')
// }
// }
// })
// return nextValues
// },
removeSelected: function removeSelected(selectedKey, e) {
var props = this.$props;
if (props.disabled || this.isChildDisabled(selectedKey)) {
return;
}
// Do not trigger Trigger popup
if (e && e.stopPropagation) {
e.stopPropagation();
}
var value = this.$data._value.filter(function (singleValue) {
return singleValue !== selectedKey;
});
var canMultiple = isMultipleOrTags(props);
if (canMultiple) {
var event = selectedKey;
if (props.labelInValue) {
event = {
key: selectedKey,
label: this.getLabelBySingleValue(selectedKey)
};
}
this.$emit('deselect', event, this.getOptionBySingleValue(selectedKey));
}
this.fireChange(value);
},
openIfHasChildren: function openIfHasChildren() {
var $props = this.$props;
if ($props.children && $props.children.length || isSingleMode($props)) {
this.setOpenState(true);
}
},
fireSelect: function fireSelect(value) {
this.$emit('select', this.getVLBySingleValue(value), this.getOptionBySingleValue(value));
},
fireChange: function fireChange(value) {
if (!hasProp(this, 'value')) {
this.setState({
_value: value
}, this.forcePopupAlign);
}
var vls = this.getVLForOnChange(value);
var options = this.getOptionsBySingleValue(value);
this._valueOptions = options;
this.$emit('change', vls, isMultipleOrTags(this.$props) ? options : options[0]);
},
isChildDisabled: function isChildDisabled(key) {
return (this.$props.children || []).some(function (child) {
var childValue = getValuePropValue(child);
return childValue === key && getValue(child, 'disabled');
});
},
forcePopupAlign: function forcePopupAlign() {
this.selectTriggerRef && this.selectTriggerRef.triggerRef.forcePopupAlign();
},
// getOptionsAndOpenStatus () {
// let sOpen = this.sOpen
// if (this.skipAdjustOpen) {
// this.openStatus = sOpen
// return {
// options: this._options,
// open: sOpen,
// }
// }
// const { $props, showSearch } = this
// let options = []
// // If hidden menu due to no options, then it should be calculated again
// if (sOpen || this.hiddenForNoOptions) {
// options = this.renderFilterOptions()
// }
// this._options = options
// if (isMultipleOrTagsOrCombobox($props) || !showSearch) {
// if (sOpen && !options.length) {
// sOpen = false
// this.hiddenForNoOptions = true
// }
// // Keep menu open if there are options and hidden for no options before
// if (this.hiddenForNoOptions && options.length) {
// sOpen = true
// this.hiddenForNoOptions = false
// }
// }
// this.openStatus = sOpen
// return {
// options,
// open: sOpen,
// }
// },
renderFilterOptions: function renderFilterOptions() {
var _this12 = this;
var h = this.$createElement;
var inputValue = this.$data._inputValue;
var _$props2 = this.$props,
children = _$props2.children,
tags = _$props2.tags,
filterOption = _$props2.filterOption,
notFoundContent = _$props2.notFoundContent;
var menuItems = [];
var childrenKeys = [];
var options = this.renderFilterOptionsFromChildren(children, childrenKeys, menuItems);
if (tags) {
// tags value must be string
var value = this.$data._value;
value = value.filter(function (singleValue) {
return childrenKeys.indexOf(singleValue) === -1 && (!inputValue || String(singleValue).indexOf(String(inputValue)) > -1);
});
value.forEach(function (singleValue) {
var key = singleValue;
var menuItem = h(
MenuItem,
_mergeJSXProps([{
style: UNSELECTABLE_STYLE
}, { attrs: UNSELECTABLE_ATTRIBUTE }, {
attrs: {
value: key,
role: 'option'
},
key: key }]),
[key]
);
options.push(menuItem);
menuItems.push(menuItem);
});
if (inputValue) {
var notFindInputItem = menuItems.every(function (option) {
// this.filterOption return true has two meaning,
// 1, some one exists after filtering
// 2, filterOption is set to false
// condition 2 does not mean the option has same value with inputValue
var filterFn = function filterFn() {
return getValuePropValue(option) === inputValue;
};
if (filterOption !== false) {
return !_this12._filterOption(inputValue, option, filterFn);
}
return !filterFn();
});
if (notFindInputItem) {
var p = {
attrs: UNSELECTABLE_ATTRIBUTE,
key: inputValue,
props: {
value: inputValue,
role: 'option'
},
style: UNSELECTABLE_STYLE
};
options.unshift(h(
MenuItem,
p,
[inputValue]
));
}
}
}
if (!options.length && notFoundContent) {
var _p = {
attrs: UNSELECTABLE_ATTRIBUTE,
key: 'NOT_FOUND',
props: {
value: 'NOT_FOUND',
disabled: true,
role: 'option'
},
style: UNSELECTABLE_STYLE
};
options = [h(
MenuItem,
_p,
[notFoundContent]
)];
}
return options;
},
renderFilterOptionsFromChildren: function renderFilterOptionsFromChildren() {
var children = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
var _this13 = this;
var childrenKeys = arguments[1];
var menuItems = arguments[2];
var h = this.$createElement;
var sel = [];
var props = this.$props;
var inputValue = this.$data._inputValue;
var tags = props.tags;
children.forEach(function (child) {
if (!child.data || child.data.slot !== undefined) {
return;
}
if (getSlotOptions(child).isSelectOptGroup) {
var innerItems = _this13.renderFilterOptionsFromChildren(child.componentOptions.children, childrenKeys, menuItems);
if (innerItems.length) {
var label = getComponentFromProp(child, 'label');
var key = child.key;
if (!key && typeof label === 'string') {
key = label;
} else if (!label && key) {
label = key;
}
sel.push(h(
MenuItemGroup,
{ key: key, attrs: { title: label },
'class': getClass(child) },
[innerItems]
));
}
return;
}
warning(getSlotOptions(child).isSelectOption, 'the children of `Select` should be `Select.Option` or `Select.OptGroup`, ' + ('instead of `' + (getSlotOptions(child).name || getSlotOptions(child)) + '`.'));
var childValue = getValuePropValue(child);
validateOptionValue(childValue, _this13.$props);
if (_this13._filterOption(inputValue, child)) {
var p = {
attrs: _extends({}, UNSELECTABLE_ATTRIBUTE, getAttrs(child)),
key: childValue,
props: _extends({
value: childValue
}, getPropsData(child), {
role: 'option'
}),
style: UNSELECTABLE_STYLE,
on: getEvents(child),
'class': getClass(child)
};
var menuItem = h(
MenuItem,
p,
[child.componentOptions.children]
);
sel.push(menuItem);
menuItems.push(menuItem);
}
if (tags) {
childrenKeys.push(childValue);
}
});
return sel;
},
renderTopControlNode: function renderTopControlNode() {
var _this14 = this;
var h = this.$createElement;
var props = this.$props;
var _$data2 = this.$data,
value = _$data2._value,
inputValue = _$data2._inputValue,
open = _$data2._open;
var choiceTransitionName = props.choiceTransitionName,
prefixCls = props.prefixCls,
maxTagTextLength = props.maxTagTextLength,
maxTagCount = props.maxTagCount,
maxTagPlaceholder = props.maxTagPlaceholder,
showSearch = props.showSearch;
var className = prefixCls + '-selection__rendered';
// search input is inside topControlNode in single, multiple & combobox. 2016/04/13
var innerNode = null;
if (isSingleMode(props)) {
var selectedValue = null;
if (value.length) {
var showSelectedValue = false;
var opacity = 1;
if (!showSearch) {
showSelectedValue = true;
} else {
if (open) {
showSelectedValue = !inputValue;
if (showSelectedValue) {
opacity = 0.4;
}
} else {
showSelectedValue = true;
}
}
var singleValue = value[0];
var _getOptionInfoBySingl3 = this.getOptionInfoBySingleValue(singleValue),
label = _getOptionInfoBySingl3.label,
title = _getOptionInfoBySingl3.title;
selectedValue = h(
'div',
{
key: 'value',
'class': prefixCls + '-selection-selected-value',
attrs: { title: toTitle(title || label)
},
style: {
display: showSelectedValue ? 'block' : 'none',
opacity: opacity
}
},
[label]
);
}
if (!showSearch) {
innerNode = [selectedValue];
} else {
innerNode = [selectedValue, h(
'div',
{
'class': prefixCls + '-search ' + prefixCls + '-search--inline',
key: 'input',
style: {
display: open ? 'block' : 'none'
}
},
[this._getInputElement()]
)];
}
} else {
var selectedValueNodes = [];
var limitedCountValue = value;
var maxTagPlaceholderEl = void 0;
if (maxTagCount !== undefined && value.length > maxTagCount) {
limitedCountValue = limitedCountValue.slice(0, maxTagCount);
var omittedValues = this.getVLForOnChange(value.slice(maxTagCount, value.length));
var content = '+ ' + (value.length - maxTagCount) + ' ...';
if (maxTagPlaceholder) {
content = typeof maxTagPlaceholder === 'function' ? maxTagPlaceholder(omittedValues) : maxTagPlaceholder;
}
maxTagPlaceholderEl = h(
'li',
{
style: UNSELECTABLE_STYLE,
attrs: { unselectable: 'unselectable',
title: toTitle(content)
},
on: {
'mousedown': preventDefaultEvent
},
'class': prefixCls + '-selection__choice ' + prefixCls + '-selection__choice__disabled',
key: 'maxTagPlaceholder' },
[h(
'div',
{ 'class': prefixCls + '-selection__choice__content' },
[content]
)]
);
}
if (isMultipleOrTags(props)) {
selectedValueNodes = limitedCountValue.map(function (singleValue) {
var info = _this14.getOptionInfoBySingleValue(singleValue);
var content = info.label;
var title = info.title || content;
if (maxTagTextLength && typeof content === 'string' && content.length > maxTagTextLength) {
content = content.slice(0, maxTagTextLength) + '...';
}
var disabled = _this14.isChildDisabled(singleValue);
var choiceClassName = disabled ? prefixCls + '-selection__choice ' + prefixCls + '-selection__choice__disabled' : prefixCls + '-selection__choice';
return h(
'li',
{
style: UNSELECTABLE_STYLE,
attrs: { unselectable: 'unselectable',
title: toTitle(title)
},
on: {
'mousedown': preventDefaultEvent
},
'class': choiceClassName,
key: singleValue },
[h(
'div',
{ 'class': prefixCls + '-selection__choice__content' },
[content]
), disabled ? null : h('span', {
'class': prefixCls + '-selection__choice__remove',
on: {
'click': function click(event) {
_this14.removeSelected(singleValue, event);
}
}
})]
);
});
}
if (maxTagPlaceholderEl) {
selectedValueNodes.push(maxTagPlaceholderEl);
}
selectedValueNodes.push(h(
'li',
{
'class': prefixCls + '-search ' + prefixCls + '-search--inline',
key: '__input'
},
[this._getInputElement()]
));
if (isMultipleOrTags(props) && choiceTransitionName) {
var transitionProps = getTransitionProps(choiceTransitionName, {
tag: 'ul',
afterLeave: this.onChoiceAnimationLeave
});
innerNode = h(
'transition-group',
transitionProps,
[selectedValueNodes]
);
} else {
innerNode = h('ul', [selectedValueNodes]);
}
}
return h(
'div',
_mergeJSXProps([{
'class': className
}, { directives: [{
name: 'ref',
value: this.saveTopCtrlRef
}] }, {
on: {
'click