|
|
|
@ -82,7 +82,7 @@ const Select = {
|
|
|
|
|
showSearch: SelectPropTypes.showSearch.def(true), |
|
|
|
|
allowClear: SelectPropTypes.allowClear.def(false), |
|
|
|
|
placeholder: SelectPropTypes.placeholder.def(''), |
|
|
|
|
showArrow: SelectPropTypes.showArrow.def(true), |
|
|
|
|
// showArrow: SelectPropTypes.showArrow.def(true), |
|
|
|
|
dropdownMatchSelectWidth: PropTypes.bool.def(true), |
|
|
|
|
dropdownStyle: SelectPropTypes.dropdownStyle.def({}), |
|
|
|
|
dropdownMenuStyle: PropTypes.object.def({}), |
|
|
|
@ -118,6 +118,7 @@ const Select = {
|
|
|
|
|
this._focused = false; |
|
|
|
|
this._mouseDown = false; |
|
|
|
|
this._options = []; |
|
|
|
|
this._empty = false; |
|
|
|
|
}, |
|
|
|
|
data() { |
|
|
|
|
const props = getOptionProps(this); |
|
|
|
@ -150,7 +151,11 @@ const Select = {
|
|
|
|
|
|
|
|
|
|
mounted() { |
|
|
|
|
this.$nextTick(() => { |
|
|
|
|
this.autoFocus && this.focus(); |
|
|
|
|
// when defaultOpen is true, we should auto focus search input |
|
|
|
|
// https://github.com/ant-design/ant-design/issues/14254 |
|
|
|
|
if(this.autoFocus || this._open) { |
|
|
|
|
this.focus(); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
}, |
|
|
|
|
watch: { |
|
|
|
@ -257,6 +262,7 @@ const Select = {
|
|
|
|
|
value: singleValue, |
|
|
|
|
label: this.getLabelFromOption(props, option), |
|
|
|
|
title: getValue(option, 'title'), |
|
|
|
|
disabled: getValue(option, 'disabled'), |
|
|
|
|
}; |
|
|
|
|
}); |
|
|
|
|
if (preState) { |
|
|
|
@ -359,6 +365,7 @@ const Select = {
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
const state = this.$data; |
|
|
|
|
const isRealOpen = this.getRealOpenState(state); |
|
|
|
|
const keyCode = event.keyCode; |
|
|
|
|
if (isMultipleOrTags(props) && !event.target.value && keyCode === KeyCode.BACKSPACE) { |
|
|
|
|
event.preventDefault(); |
|
|
|
@ -378,7 +385,10 @@ const Select = {
|
|
|
|
|
} 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(); |
|
|
|
|
// https://github.com/ant-design/ant-design/issues/14544 |
|
|
|
|
if (isRealOpen || !props.combobox) { |
|
|
|
|
event.preventDefault(); |
|
|
|
|
} |
|
|
|
|
} else if (keyCode === KeyCode.ESC) { |
|
|
|
|
if (state._open) { |
|
|
|
|
this.setOpenState(false); |
|
|
|
@ -388,7 +398,7 @@ const Select = {
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (this.getRealOpenState(state) && this.selectTriggerRef) { |
|
|
|
|
if (isRealOpen && this.selectTriggerRef) { |
|
|
|
|
const menu = this.selectTriggerRef.getInnerMenu(); |
|
|
|
|
if (menu && menu.onKeyDown(event, this.handleBackfill)) { |
|
|
|
|
event.preventDefault(); |
|
|
|
@ -413,6 +423,7 @@ const Select = {
|
|
|
|
|
value = value.concat([selectedValue]); |
|
|
|
|
} else { |
|
|
|
|
if ( |
|
|
|
|
!isCombobox(props) && |
|
|
|
|
lastValue !== undefined && |
|
|
|
|
lastValue === selectedValue && |
|
|
|
|
selectedValue !== this.$data._backfillValue |
|
|
|
@ -532,6 +543,10 @@ const Select = {
|
|
|
|
|
let value = null; |
|
|
|
|
Object.keys(this.$data._optionsInfo).forEach(key => { |
|
|
|
|
const info = this.$data._optionsInfo[key]; |
|
|
|
|
const { disabled } = info; |
|
|
|
|
if (disabled) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
const oldLable = toArray(info.label); |
|
|
|
|
if (oldLable && oldLable.join('') === label) { |
|
|
|
|
value = info.value; |
|
|
|
@ -1040,6 +1055,7 @@ const Select = {
|
|
|
|
|
const { children, tags, filterOption, notFoundContent } = this.$props; |
|
|
|
|
const menuItems = []; |
|
|
|
|
const childrenKeys = []; |
|
|
|
|
let empty = false; |
|
|
|
|
let options = this.renderFilterOptionsFromChildren(children, childrenKeys, menuItems); |
|
|
|
|
if (tags) { |
|
|
|
|
// tags value must be string |
|
|
|
@ -1050,6 +1066,12 @@ const Select = {
|
|
|
|
|
(!inputValue || String(singleValue).indexOf(String(inputValue)) > -1) |
|
|
|
|
); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
// sort by length |
|
|
|
|
value.sort((val1, val2) => { |
|
|
|
|
return val1.length - val2.length; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
value.forEach(singleValue => { |
|
|
|
|
const key = singleValue; |
|
|
|
|
const menuItem = ( |
|
|
|
@ -1094,6 +1116,7 @@ const Select = {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!options.length && notFoundContent) { |
|
|
|
|
empty = true; |
|
|
|
|
const p = { |
|
|
|
|
attrs: UNSELECTABLE_ATTRIBUTE, |
|
|
|
|
key: 'NOT_FOUND', |
|
|
|
@ -1106,7 +1129,7 @@ const Select = {
|
|
|
|
|
}; |
|
|
|
|
options = [<MenuItem {...p}>{notFoundContent}</MenuItem>]; |
|
|
|
|
} |
|
|
|
|
return options; |
|
|
|
|
return {empty, options}; |
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
renderFilterOptionsFromChildren(children = [], childrenKeys, menuItems) { |
|
|
|
@ -1370,15 +1393,16 @@ const Select = {
|
|
|
|
|
); |
|
|
|
|
}, |
|
|
|
|
renderArrow(multiple) { |
|
|
|
|
const { showArrow, loading, prefixCls } = this.$props; |
|
|
|
|
// showArrow : Set to true if not multiple by default but keep set value. |
|
|
|
|
const { showArrow = !multiple, loading, prefixCls } = this.$props; |
|
|
|
|
const inputIcon = getComponentFromProp(this, 'inputIcon'); |
|
|
|
|
if (!showArrow) { |
|
|
|
|
if (!showArrow && !loading ) { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
// if loading have loading icon |
|
|
|
|
if (multiple && !loading) { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
// if (multiple && !loading) { |
|
|
|
|
// return null; |
|
|
|
|
// } |
|
|
|
|
const defaultIcon = loading ? ( |
|
|
|
|
<i class={`${prefixCls}-arrow-loading`} /> |
|
|
|
|
) : ( |
|
|
|
@ -1466,14 +1490,19 @@ const Select = {
|
|
|
|
|
render() { |
|
|
|
|
const props = this.$props; |
|
|
|
|
const multiple = isMultipleOrTags(props); |
|
|
|
|
// Default set showArrow to true if not set (not set directly in defaultProps to handle multiple case) |
|
|
|
|
const { showArrow = true } = props; |
|
|
|
|
const state = this.$data; |
|
|
|
|
const { disabled, prefixCls } = props; |
|
|
|
|
const { disabled, prefixCls, loading } = props; |
|
|
|
|
const ctrlNode = this.renderTopControlNode(); |
|
|
|
|
const { _open: open, _inputValue: inputValue, _value: value } = this.$data; |
|
|
|
|
if (open) { |
|
|
|
|
this._options = this.renderFilterOptions(); |
|
|
|
|
const filterOptions = this.renderFilterOptions(); |
|
|
|
|
this._empty = filterOptions.empty; |
|
|
|
|
this._options = filterOptions.options; |
|
|
|
|
} |
|
|
|
|
const realOpen = this.getRealOpenState(); |
|
|
|
|
const empty = this._empty; |
|
|
|
|
const options = this._options || []; |
|
|
|
|
const { $listeners } = this; |
|
|
|
|
const { mouseenter = noop, mouseleave = noop, popupScroll = noop } = $listeners; |
|
|
|
@ -1512,7 +1541,8 @@ const Select = {
|
|
|
|
|
[`${prefixCls}-disabled`]: disabled, |
|
|
|
|
[`${prefixCls}-enabled`]: !disabled, |
|
|
|
|
[`${prefixCls}-allow-clear`]: !!props.allowClear, |
|
|
|
|
[`${prefixCls}-no-arrow`]: !props.showArrow, |
|
|
|
|
[`${prefixCls}-no-arrow`]: !showArrow, |
|
|
|
|
[`${prefixCls}-loading`]: !!loading, |
|
|
|
|
}; |
|
|
|
|
return ( |
|
|
|
|
<SelectTrigger |
|
|
|
@ -1528,6 +1558,7 @@ const Select = {
|
|
|
|
|
combobox={props.combobox} |
|
|
|
|
showSearch={props.showSearch} |
|
|
|
|
options={options} |
|
|
|
|
empty={empty} |
|
|
|
|
multiple={multiple} |
|
|
|
|
disabled={disabled} |
|
|
|
|
visible={realOpen} |
|
|
|
|