diff --git a/components/vc-select/DropdownMenu.jsx b/components/vc-select/DropdownMenu.jsx index cae6f5f99..b658760da 100644 --- a/components/vc-select/DropdownMenu.jsx +++ b/components/vc-select/DropdownMenu.jsx @@ -130,12 +130,17 @@ export default { } const activeKeyProps = {}; + let defaultActiveFirst = defaultActiveFirstOption; let clonedMenuItems = menuItems; if (selectedKeys.length || firstActiveValue) { if (props.visible && !this.lastVisible) { activeKeyProps.activeKey = selectedKeys[0] !== undefined ? selectedKeys[0] : firstActiveValue; } else if (!visible) { + // Do not trigger auto active since we already have selectedKeys + if (selectedKeys[0]) { + defaultActiveFirst = false; + } activeKeyProps.activeKey = undefined; } let foundFirst = false; @@ -180,7 +185,7 @@ export default { if (inputValue !== this.lastInputValue && (!lastValue || lastValue !== backfillValue)) { activeKeyProps.activeKey = ''; } - menuProps.props = { ...activeKeyProps, ...menuProps.props }; + menuProps.props = { ...activeKeyProps, ...menuProps.props, defaultActiveFirst }; return
; } return null; diff --git a/components/vc-select/Select.jsx b/components/vc-select/Select.jsx index db2e2bc70..f4663523b 100644 --- a/components/vc-select/Select.jsx +++ b/components/vc-select/Select.jsx @@ -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 = []; } - 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 ? ( ) : ( @@ -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 (