feat: update vc-select
							parent
							
								
									e706170669
								
							
						
					
					
						commit
						435b8a19e6
					
				|  | @ -52,9 +52,11 @@ const getSlots = (ele) => { | |||
|   const children = ele.children || componentOptions.children || [] | ||||
|   const slots = {} | ||||
|   children.forEach(child => { | ||||
|     const name = (child.data && child.data.slot) || 'default' | ||||
|     slots[name] = slots[name] || [] | ||||
|     slots[name].push(child) | ||||
|     if (!isEmptyElement(child)) { | ||||
|       const name = (child.data && child.data.slot) || 'default' | ||||
|       slots[name] = slots[name] || [] | ||||
|       slots[name].push(child) | ||||
|     } | ||||
|   }) | ||||
|   return slots | ||||
| } | ||||
|  | @ -213,12 +215,12 @@ export function getComponentName (opts) { | |||
|   return opts && (opts.Ctor.options.name || opts.tag) | ||||
| } | ||||
| 
 | ||||
| export function isEmptyElement (ele) { | ||||
|   return !(ele.tag || ele.text.trim() !== '') | ||||
| export function isEmptyElement (c) { | ||||
|   return !(c.tag || (c.text && c.text.trim() !== '')) | ||||
| } | ||||
| 
 | ||||
| export function filterEmpty (children = []) { | ||||
|   return children.filter(c => c.tag || (c.text && c.text.trim() !== '')) | ||||
|   return children.filter(c => !isEmptyElement(c)) | ||||
| } | ||||
| const initDefaultProps = (propTypes, defaultProps) => { | ||||
|   Object.keys(defaultProps).forEach(k => { | ||||
|  |  | |||
|  | @ -11,6 +11,7 @@ export default { | |||
|   name: 'DropdownMenu', | ||||
|   mixins: [BaseMixin], | ||||
|   props: { | ||||
|     ariaId: PropTypes.string, | ||||
|     defaultActiveFirstOption: PropTypes.bool, | ||||
|     value: PropTypes.any, | ||||
|     dropdownMenuStyle: PropTypes.object, | ||||
|  | @ -28,8 +29,10 @@ export default { | |||
|     menuItemSelectedIcon: PropTypes.any, | ||||
|   }, | ||||
| 
 | ||||
|   beforeMount () { | ||||
|   created () { | ||||
|     this.rafInstance = { cancel: () => null } | ||||
|     this.lastInputValue = this.$props.inputValue | ||||
|     this.lastVisible = false | ||||
|   }, | ||||
| 
 | ||||
|   mounted () { | ||||
|  | @ -101,6 +104,7 @@ export default { | |||
|         firstActiveValue, | ||||
|         dropdownMenuStyle, | ||||
|         backfillValue, | ||||
|         visible, | ||||
|       } = props | ||||
|       const menuItemSelectedIcon = getComponentFromProp(this, 'menuItemSelectedIcon') | ||||
|       const { menuDeselect, menuSelect, popupScroll } = this.$listeners | ||||
|  | @ -136,6 +140,8 @@ export default { | |||
|         if (selectedKeys.length || firstActiveValue) { | ||||
|           if (props.visible && !this.lastVisible) { | ||||
|             activeKeyProps.activeKey = selectedKeys[0] !== undefined ? selectedKeys[0] : firstActiveValue | ||||
|           } else if (!visible) { | ||||
|             activeKeyProps.activeKey = undefined | ||||
|           } | ||||
|           let foundFirst = false | ||||
|           // set firstActiveItem via cloning menus | ||||
|  | @ -143,9 +149,7 @@ export default { | |||
|           const clone = item => { | ||||
|             if ( | ||||
|               (!foundFirst && selectedKeys.indexOf(item.key) !== -1) || | ||||
|             (!foundFirst && | ||||
|               !selectedKeys.length && | ||||
|               firstActiveValue.indexOf(item.key) !== -1) | ||||
|               (!foundFirst && !selectedKeys.length && firstActiveValue.indexOf(item.key) !== -1) | ||||
|             ) { | ||||
|               foundFirst = true | ||||
|               return cloneElement(item, { | ||||
|  | @ -198,6 +202,8 @@ export default { | |||
|           overflow: 'auto', | ||||
|           transform: 'translateZ(0)', | ||||
|         }} | ||||
|         id={this.$props.ariaId} | ||||
|         tabIndex='-1' | ||||
|         onFocus={popupFocus} | ||||
|         onMousedown={preventDefaultEvent} | ||||
|         onScroll={popupScroll} | ||||
|  |  | |||
|  | @ -2,7 +2,14 @@ | |||
| import PropTypes from '../_util/vue-types' | ||||
| export default { | ||||
|   props: { | ||||
|     label: PropTypes.any, | ||||
|     value: PropTypes.oneOfType([ | ||||
|       PropTypes.string, | ||||
|       PropTypes.number, | ||||
|     ]), | ||||
|     label: PropTypes.oneOfType([ | ||||
|       PropTypes.string, | ||||
|       PropTypes.number, | ||||
|     ]), | ||||
|   }, | ||||
|   isSelectOptGroup: true, | ||||
| } | ||||
|  |  | |||
|  | @ -7,8 +7,15 @@ export default { | |||
|       PropTypes.string, | ||||
|       PropTypes.number, | ||||
|     ]), | ||||
|     label: PropTypes.oneOfType([ | ||||
|       PropTypes.string, | ||||
|       PropTypes.number, | ||||
|     ]), | ||||
|     disabled: PropTypes.bool, | ||||
|     title: PropTypes.string, | ||||
|     title: PropTypes.oneOfType([ | ||||
|       PropTypes.string, | ||||
|       PropTypes.number, | ||||
|     ]), | ||||
|   }, | ||||
|   isSelectOption: true, | ||||
| } | ||||
|  |  | |||
|  | @ -31,6 +31,7 @@ export const SelectPropTypes = { | |||
|   placeholder: PropTypes.any, | ||||
|   // onDeselect: PropTypes.func,
 | ||||
|   labelInValue: PropTypes.bool, | ||||
|   loading: PropTypes.bool, | ||||
|   value: PropTypes.any, | ||||
|   defaultValue: PropTypes.any, | ||||
|   dropdownStyle: PropTypes.object, | ||||
|  | @ -47,4 +48,12 @@ export const SelectPropTypes = { | |||
|   inputIcon: PropTypes.any, | ||||
|   removeIcon: PropTypes.any, | ||||
|   menuItemSelectedIcon: PropTypes.any, | ||||
|   dropdownRender: PropTypes.func, | ||||
|   mode: PropTypes.oneOf(['multiple', 'tags']), | ||||
|   backfill: PropTypes.bool, | ||||
|   dropdownAlign: PropTypes.any, | ||||
|   dropdownMatchSelectWidth: PropTypes.bool, | ||||
|   dropdownMenuStyle: PropTypes.object, | ||||
|   notFoundContent: PropTypes.oneOfType([String, Number]), | ||||
|   tabIndex: PropTypes.oneOfType([String, Number]), | ||||
| } | ||||
|  |  | |||
|  | @ -7,56 +7,58 @@ 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 OptGroup from './OptGroup' | ||||
| import { hasProp, getSlotOptions, getPropsData, getValueByProp as getValue, getComponentFromProp, getEvents, getClass, getStyle, getAttrs, getOptionProps, getSlots } 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 ref from 'vue-ref' | ||||
| 
 | ||||
| Vue.use(ref, { name: 'ant-ref' }) | ||||
| 
 | ||||
| import SelectTrigger from './SelectTrigger' | ||||
| import { | ||||
|   defaultFilterFn, | ||||
|   findFirstMenuItem, | ||||
|   findIndexInValueBySingleValue, | ||||
|   generateUUID, | ||||
|   getLabelFromPropsValue, | ||||
|   getMapKey, | ||||
|   getPropValue, | ||||
|   getValuePropValue, | ||||
|   includesSeparators, | ||||
|   isCombobox, | ||||
|   isMultipleOrTags, | ||||
|   isMultipleOrTagsOrCombobox, | ||||
|   isSingleMode, | ||||
|   preventDefaultEvent, | ||||
|   saveRef, | ||||
|   splitBySeparators, | ||||
|   toArray, | ||||
|   getMapKey, | ||||
|   findIndexInValueBySingleValue, | ||||
|   getLabelFromPropsValue, | ||||
|   toTitle, | ||||
|   UNSELECTABLE_ATTRIBUTE, | ||||
|   UNSELECTABLE_STYLE, | ||||
|   preventDefaultEvent, | ||||
|   findFirstMenuItem, | ||||
|   includesSeparators, | ||||
|   splitBySeparators, | ||||
|   defaultFilterFn, | ||||
|   validateOptionValue, | ||||
|   saveRef, | ||||
|   toTitle, | ||||
| } from './util' | ||||
| import SelectTrigger from './SelectTrigger' | ||||
| import { SelectPropTypes } from './PropTypes' | ||||
| 
 | ||||
| Vue.use(ref, { name: 'ant-ref' }) | ||||
| const SELECT_EMPTY_VALUE_KEY = 'RC_SELECT_EMPTY_VALUE_KEY' | ||||
| 
 | ||||
| function noop () {} | ||||
| const noop = () => null | ||||
| 
 | ||||
| function chaining (...fns) { | ||||
|   return function (...args) { // eslint-disable-line | ||||
|     // eslint-disable-line | ||||
|     for (let i = 0; i < fns.length; i++) { | ||||
|       if (fns[i] && typeof fns[i] === 'function') { | ||||
|         fns[i].apply(this, args) | ||||
|         fns[i].apply(chaining, args) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| const Select = { | ||||
|   inheritAttrs: false, | ||||
|   Option, | ||||
|   OptGroup, | ||||
|   name: 'Select', | ||||
|   mixins: [BaseMixin], | ||||
|   props: { | ||||
|  | @ -80,6 +82,8 @@ const Select = { | |||
|     combobox: PropTypes.bool.def(false), | ||||
|     tokenSeparators: PropTypes.arrayOf(PropTypes.string).def([]), | ||||
|     autoClearSearchValue: PropTypes.bool.def(true), | ||||
|     tabIndex: PropTypes.any.def(0), | ||||
|     dropdownRender: PropTypes.func.def(menu => menu), | ||||
|     // onChange: noop, | ||||
|     // onFocus: noop, | ||||
|     // onBlur: noop, | ||||
|  | @ -99,6 +103,10 @@ const Select = { | |||
|     this.saveSelectTriggerRef = saveRef(this, 'selectTriggerRef') | ||||
|     this.saveRootRef = saveRef(this, 'rootRef') | ||||
|     this.saveSelectionRef = saveRef(this, 'selectionRef') | ||||
|     this.ariaId = generateUUID() | ||||
|     this._focused = false | ||||
|     this._mouseDown = false | ||||
|     this._options = [] | ||||
|   }, | ||||
|   data () { | ||||
|     const props = getOptionProps(this) | ||||
|  | @ -116,6 +124,7 @@ const Select = { | |||
|       ) : '', | ||||
|       _open: props.defaultOpen, | ||||
|       _optionsInfo: optionsInfo, | ||||
|       _backfillValue: '', | ||||
|       // a flag for aviod redundant getOptionsInfoFromProps call | ||||
|       _skipBuildOptionsInfo: true, | ||||
|     } | ||||
|  | @ -140,10 +149,10 @@ const Select = { | |||
|       if (isMultipleOrTags(this.$props)) { | ||||
|         const inputNode = this.getInputDOMNode() | ||||
|         const mirrorNode = this.getInputMirrorDOMNode() | ||||
|         if (inputNode.value) { | ||||
|         if (inputNode.value && inputNode.value && mirrorNode) { | ||||
|           inputNode.style.width = '' | ||||
|           inputNode.style.width = `${mirrorNode.clientWidth + 10}px` | ||||
|         } else { | ||||
|         } else if (inputNode) { | ||||
|           inputNode.style.width = '' | ||||
|         } | ||||
|       } | ||||
|  | @ -185,6 +194,91 @@ const Select = { | |||
|       } | ||||
|       return newState | ||||
|     }, | ||||
|     getOptionsFromChildren (children = [], options = []) { | ||||
|       children.forEach(child => { | ||||
|         if (!child.data || child.data.slot !== undefined) { | ||||
|           return | ||||
|         } | ||||
|         if (getSlotOptions(child).isSelectOptGroup) { | ||||
|           this.getOptionsFromChildren(child.componentOptions.children, options) | ||||
|         } else { | ||||
|           options.push(child) | ||||
|         } | ||||
|       }) | ||||
|       return options | ||||
|     }, | ||||
|     getInputValueForCombobox (props, optionsInfo, useDefaultValue) { | ||||
|       let 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 '' | ||||
|       } | ||||
|       let 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 (props, option) { | ||||
|       return getPropValue(option, props.optionLabelProp) | ||||
|     }, | ||||
| 
 | ||||
|     getOptionsInfoFromProps (props, preState) { | ||||
|       const options = this.getOptionsFromChildren(this.$props.children) | ||||
|       const optionsInfo = {} | ||||
|       options.forEach((option) => { | ||||
|         const singleValue = getValuePropValue(option) | ||||
|         optionsInfo[getMapKey(singleValue)] = { | ||||
|           option, | ||||
|           value: singleValue, | ||||
|           label: this.getLabelFromOption(props, option), | ||||
|           title: getValue(option, 'title'), | ||||
|         } | ||||
|       }) | ||||
|       if (preState) { | ||||
|         // keep option info in pre state value. | ||||
|         const oldOptionsInfo = preState._optionsInfo | ||||
|         const value = preState._value | ||||
|         if (value) { | ||||
|           value.forEach(v => { | ||||
|             const key = getMapKey(v) | ||||
|             if (!optionsInfo[key] && oldOptionsInfo[key] !== undefined) { | ||||
|               optionsInfo[key] = oldOptionsInfo[key] | ||||
|             } | ||||
|           }) | ||||
|         } | ||||
|       } | ||||
|       return optionsInfo | ||||
|     }, | ||||
| 
 | ||||
|     getValueFromProps (props, useDefaultValue) { | ||||
|       let 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((v) => { | ||||
|           return v.key | ||||
|         }) | ||||
|       } | ||||
|       return value | ||||
|     }, | ||||
| 
 | ||||
|     onInputChange (event) { | ||||
|       const { tokenSeparators } = this.$props | ||||
|  | @ -290,7 +384,7 @@ const Select = { | |||
|         return | ||||
|       } | ||||
| 
 | ||||
|       if (this.getRealOpenState(state)) { | ||||
|       if (this.getRealOpenState(state) && this.selectTriggerRef) { | ||||
|         const menu = this.selectTriggerRef.getInnerMenu() | ||||
|         if (menu && menu.onKeyDown(event, this.handleBackfill)) { | ||||
|           event.preventDefault() | ||||
|  | @ -324,12 +418,8 @@ const Select = { | |||
|         this.setOpenState(false, true) | ||||
|       } | ||||
|       this.fireChange(value) | ||||
|       let inputValue | ||||
|       if (isCombobox(props)) { | ||||
|         inputValue = getPropValue(item, props.optionLabelProp) | ||||
|       } else { | ||||
|         inputValue = '' | ||||
|       } | ||||
|       const inputValue = isCombobox(props) ? getPropValue(item, props.optionLabelProp) : '' | ||||
| 
 | ||||
|       if (props.autoClearSearchValue) { | ||||
|         this.setInputValue(inputValue, false) | ||||
|       } | ||||
|  | @ -357,7 +447,7 @@ const Select = { | |||
|     }, | ||||
| 
 | ||||
|     onPlaceholderClick (e) { | ||||
|       if (this.getInputDOMNode()) { | ||||
|       if (this.getInputDOMNode() && this.getInputDOMNode()) { | ||||
|         this.getInputDOMNode().focus() | ||||
|       } | ||||
|     }, | ||||
|  | @ -389,89 +479,6 @@ const Select = { | |||
|     onChoiceAnimationLeave () { | ||||
|       this.forcePopupAlign() | ||||
|     }, | ||||
|     getOptionsFromChildren (children = [], options = []) { | ||||
|       children.forEach(child => { | ||||
|         if (!child.data || child.data.slot !== undefined) { | ||||
|           return | ||||
|         } | ||||
|         if (getSlotOptions(child).isSelectOptGroup) { | ||||
|           this.getOptionsFromChildren(child.componentOptions.children, options) | ||||
|         } else { | ||||
|           options.push(child) | ||||
|         } | ||||
|       }) | ||||
|       return options | ||||
|     }, | ||||
|     getInputValueForCombobox (props, optionsInfo, useDefaultValue) { | ||||
|       let 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 '' | ||||
|       } | ||||
|       let 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 (props, option) { | ||||
|       return getPropValue(option, props.optionLabelProp) | ||||
|     }, | ||||
| 
 | ||||
|     getOptionsInfoFromProps (props, preState) { | ||||
|       const options = this.getOptionsFromChildren(this.$props.children) | ||||
|       const optionsInfo = {} | ||||
|       options.forEach((option) => { | ||||
|         const singleValue = getValuePropValue(option) | ||||
|         optionsInfo[getMapKey(singleValue)] = { | ||||
|           option, | ||||
|           value: singleValue, | ||||
|           label: this.getLabelFromOption(props, option), | ||||
|           title: getValue(option, 'title'), | ||||
|         } | ||||
|       }) | ||||
|       if (preState) { | ||||
|         // keep option info in pre state value. | ||||
|         const oldOptionsInfo = preState._optionsInfo | ||||
|         const value = preState._value | ||||
|         value.forEach(v => { | ||||
|           const key = getMapKey(v) | ||||
|           if (!optionsInfo[key] && oldOptionsInfo[key] !== undefined) { | ||||
|             optionsInfo[key] = oldOptionsInfo[key] | ||||
|           } | ||||
|         }) | ||||
|       } | ||||
|       return optionsInfo | ||||
|     }, | ||||
| 
 | ||||
|     getValueFromProps (props, useDefaultValue) { | ||||
|       let 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((v) => { | ||||
|           return v.key | ||||
|         }) | ||||
|       } | ||||
|       return value | ||||
|     }, | ||||
| 
 | ||||
|     getOptionInfoBySingleValue  (value, optionsInfo) { | ||||
|       let info | ||||
|  | @ -515,7 +522,8 @@ const Select = { | |||
|       let value = null | ||||
|       Object.keys(this.$data._optionsInfo).forEach(key => { | ||||
|         const info = this.$data._optionsInfo[key] | ||||
|         if (toArray(info.label).join('') === label) { | ||||
|         const oldLable = toArray(info.label) | ||||
|         if (oldLable && oldLable.join('') === label) { | ||||
|           value = info.value | ||||
|         } | ||||
|       }) | ||||
|  | @ -532,8 +540,8 @@ const Select = { | |||
|       return value | ||||
|     }, | ||||
| 
 | ||||
|     getVLForOnChange (vls_) { | ||||
|       let vls = vls_ | ||||
|     getVLForOnChange (vlsS) { | ||||
|       let vls = vlsS | ||||
|       if (vls !== undefined) { | ||||
|         if (!this.labelInValue) { | ||||
|           vls = vls.map(v => v) | ||||
|  | @ -567,10 +575,11 @@ const Select = { | |||
|       if (state._inputValue) { | ||||
|         hidden = true | ||||
|       } | ||||
|       if (state._value.length) { | ||||
|       const value = state._value | ||||
|       if (value.length) { | ||||
|         hidden = true | ||||
|       } | ||||
|       if (isCombobox(props) && state._value.length === 1 && !state._value[0]) { | ||||
|       if (isCombobox(props) && value.length === 1 && (state._value && !state._value[0])) { | ||||
|         hidden = false | ||||
|       } | ||||
|       const placeholder = props.placeholder | ||||
|  | @ -634,10 +643,16 @@ const Select = { | |||
|             this.setInputValue('') | ||||
|           } else { | ||||
|             // why not use setState? | ||||
|             this.$data._inputValue = this.getInputDOMNode().value = '' | ||||
|             this.$data._inputValue = '' | ||||
|             this.$nextTick(() => { | ||||
|               if (this.getInputDOMNode && this.getInputDOMNode()) { | ||||
|                 this.getInputDOMNode().value = '' | ||||
|               } | ||||
|             }) | ||||
|           } | ||||
|           value = this.getValueByInput(inputValue) | ||||
|           if (value !== undefined) { | ||||
|           const tmpValue = this.getValueByInput(inputValue) | ||||
|           if (tmpValue !== undefined) { | ||||
|             value = tmpValue | ||||
|             this.fireChange(value) | ||||
|           } | ||||
|         } | ||||
|  | @ -677,9 +692,11 @@ const Select = { | |||
|       const props = this.$props | ||||
|       const { _inputValue: inputValue } = this.$data | ||||
|       const attrs = getAttrs(this) | ||||
|       const defaultInput = <input id={attrs.id} autoComplete='off' /> | ||||
| 
 | ||||
|       const inputElement = props.getInputElement | ||||
|         ? props.getInputElement() | ||||
|         : <input id={attrs.id} autoComplete='off'/> | ||||
|         : defaultInput | ||||
|       const inputCls = classnames(getClass(inputElement), { | ||||
|         [`${props.prefixCls}-search__field`]: true, | ||||
|       }) | ||||
|  | @ -749,34 +766,38 @@ const Select = { | |||
|     }, | ||||
| 
 | ||||
|     getPopupDOMNode () { | ||||
|       return this.selectTriggerRef.getPopupDOMNode() | ||||
|       if (this.selectTriggerRef) { | ||||
|         return this.selectTriggerRef.getPopupDOMNode() | ||||
|       } | ||||
|     }, | ||||
| 
 | ||||
|     getPopupMenuComponent () { | ||||
|       return this.selectTriggerRef.getInnerMenu() | ||||
|       if (this.selectTriggerRef) { | ||||
|         return this.selectTriggerRef.getInnerMenu() | ||||
|       } | ||||
|     }, | ||||
| 
 | ||||
|     setOpenState (open, needFocus) { | ||||
|       const { $props: props, $data: state } = this | ||||
|       if (state._open === open) { | ||||
|         this.maybeFocus(open, needFocus) | ||||
|         this.maybeFocus(open, !!needFocus) | ||||
|         return | ||||
|       } | ||||
|       this.__emit('dropdownVisibleChange', open) | ||||
|       const nextState = { | ||||
|         _open: open, | ||||
|         _backfillValue: undefined, | ||||
|         _backfillValue: '', | ||||
|       } | ||||
|       // 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.maybeFocus(open, !!needFocus) | ||||
|       } | ||||
|       this.setState(nextState, () => { | ||||
|         if (open) { | ||||
|           this.maybeFocus(open, needFocus) | ||||
|           this.maybeFocus(open, !!needFocus) | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | @ -791,11 +812,11 @@ const Select = { | |||
|         } | ||||
|       } | ||||
|     }, | ||||
|     getValueByInput  (string) { | ||||
|     getValueByInput  (str) { | ||||
|       const { multiple, tokenSeparators } = this.$props | ||||
|       let nextValue = this.$data._value | ||||
|       let hasNewValue = false | ||||
|       splitBySeparators(string, tokenSeparators).forEach(label => { | ||||
|       splitBySeparators(str, tokenSeparators).forEach(label => { | ||||
|         const selectedValue = [label] | ||||
|         if (multiple) { | ||||
|           const value = this.getValueByLabel(label) | ||||
|  | @ -804,13 +825,10 @@ const Select = { | |||
|             hasNewValue = true | ||||
|             this.fireSelect(value) | ||||
|           } | ||||
|         } else { | ||||
|           // tag | ||||
|           if (findIndexInValueBySingleValue(nextValue, label) === -1) { | ||||
|             nextValue = nextValue.concat(selectedValue) | ||||
|             hasNewValue = true | ||||
|             this.fireSelect(label) | ||||
|           } | ||||
|         } else if (findIndexInValueBySingleValue(nextValue, label) === -1) { | ||||
|           nextValue = nextValue.concat(selectedValue) | ||||
|           hasNewValue = true | ||||
|           this.fireSelect(label) | ||||
|         } | ||||
|       }) | ||||
|       return hasNewValue ? nextValue : undefined | ||||
|  | @ -833,17 +851,17 @@ const Select = { | |||
|     }, | ||||
| 
 | ||||
|     focus () { | ||||
|       if (isSingleMode(this.$props)) { | ||||
|       if (isSingleMode(this.$props) && this.selectionRef) { | ||||
|         this.selectionRef.focus() | ||||
|       } else { | ||||
|       } else if (this.getInputDOMNode()) { | ||||
|         this.getInputDOMNode().focus() | ||||
|       } | ||||
|     }, | ||||
| 
 | ||||
|     blur () { | ||||
|       if (isSingleMode(this.$props)) { | ||||
|       if (isSingleMode(this.$props) && this.selectionRef) { | ||||
|         this.selectionRef.blur() | ||||
|       } else { | ||||
|       } else if (this.getInputDOMNode()) { | ||||
|         this.getInputDOMNode().blur() | ||||
|       } | ||||
|     }, | ||||
|  | @ -880,11 +898,11 @@ const Select = { | |||
|       } | ||||
|       let filterFn = this.$props.filterOption | ||||
|       if (hasProp(this, 'filterOption')) { | ||||
|         if (this.filterOption === true) { | ||||
|           filterFn = defaultFilter | ||||
|         if (filterFn === true) { | ||||
|           filterFn = defaultFilter.bind(this) | ||||
|         } | ||||
|       } else { | ||||
|         filterFn = defaultFilter | ||||
|         filterFn = defaultFilter.bind(this) | ||||
|       } | ||||
|       if (!filterFn) { | ||||
|         return true | ||||
|  | @ -900,7 +918,7 @@ const Select = { | |||
|       if (this.focusTimer) { | ||||
|         this.clearFocusTime() | ||||
|       } | ||||
|       this.focusTimer = setTimeout(() => { | ||||
|       this.focusTimer = window.setTimeout(() => { | ||||
|         // this._focused = true | ||||
|         // this.updateFocusClassName() | ||||
|         this.$emit('focus') | ||||
|  | @ -940,7 +958,7 @@ const Select = { | |||
|             input.focus() | ||||
|             this._focused = true | ||||
|           } | ||||
|         } else if (activeElement !== this.selectionRef) { | ||||
|         } else if (activeElement !== this.selectionRef && this.selectionRef) { | ||||
|           this.selectionRef.focus() | ||||
|           this._focused = true | ||||
|         } | ||||
|  | @ -956,8 +974,8 @@ const Select = { | |||
|       if (e && e.stopPropagation) { | ||||
|         e.stopPropagation() | ||||
|       } | ||||
| 
 | ||||
|       const value = this.$data._value.filter(singleValue => { | ||||
|       const oldValue = this.$data._value | ||||
|       const value = oldValue.filter(singleValue => { | ||||
|         return singleValue !== selectedKey | ||||
|       }) | ||||
|       const canMultiple = isMultipleOrTags(props) | ||||
|  | @ -1006,7 +1024,9 @@ const Select = { | |||
|       if (!this.$data._open) { | ||||
|         return | ||||
|       } | ||||
|       this.selectTriggerRef && this.selectTriggerRef.triggerRef.forcePopupAlign() | ||||
|       if (this.selectTriggerRef && this.selectTriggerRef.triggerRef) { | ||||
|         this.selectTriggerRef.triggerRef.forcePopupAlign() | ||||
|       } | ||||
|     }, | ||||
|     renderFilterOptions () { | ||||
|       const { _inputValue: inputValue } = this.$data | ||||
|  | @ -1024,8 +1044,7 @@ const Select = { | |||
|         value = value.filter(singleValue => { | ||||
|           return ( | ||||
|             childrenKeys.indexOf(singleValue) === -1 && | ||||
|           (!inputValue || | ||||
|             String(singleValue).indexOf(String(inputValue)) > -1) | ||||
|           (!inputValue || String(singleValue).indexOf(String(inputValue)) > -1) | ||||
|           ) | ||||
|         }) | ||||
|         value.forEach(singleValue => { | ||||
|  | @ -1109,25 +1128,49 @@ const Select = { | |||
|           return | ||||
|         } | ||||
|         if (getSlotOptions(child).isSelectOptGroup) { | ||||
|           const innerItems = this.renderFilterOptionsFromChildren( | ||||
|             child.componentOptions.children, | ||||
|             childrenKeys, | ||||
|             menuItems, | ||||
|           ) | ||||
|           if (innerItems.length) { | ||||
|             let label = getComponentFromProp(child, 'label') | ||||
|             let key = child.key | ||||
|             if (!key && typeof label === 'string') { | ||||
|               key = label | ||||
|             } else if (!label && key) { | ||||
|               label = key | ||||
|             } | ||||
|           let label = getComponentFromProp(child, 'label') | ||||
|           let key = child.key | ||||
|           if (!key && typeof label === 'string') { | ||||
|             key = label | ||||
|           } else if (!label && key) { | ||||
|             label = key | ||||
|           } | ||||
|           const childChildren = getSlots(child).default | ||||
|           // Match option group label | ||||
|           if (inputValue && this._filterOption(inputValue, child)) { | ||||
|             const innerItems = childChildren.map( | ||||
|               (subChild) => { | ||||
|                 const childValueSub = getValuePropValue(subChild) || subChild.key | ||||
|                 return ( | ||||
|                   <MenuItem key={childValueSub} value={childValueSub} {...subChild.data}> | ||||
|                     {subChild.componentOptions.children} | ||||
|                   </MenuItem> | ||||
|                 ) | ||||
|               }, | ||||
|             ) | ||||
| 
 | ||||
|             sel.push( | ||||
|               <MenuItemGroup key={key} title={label} class ={getClass(child)}> | ||||
|                 {innerItems} | ||||
|               </MenuItemGroup> | ||||
|               </MenuItemGroup>, | ||||
|             ) | ||||
| 
 | ||||
|           // Not match | ||||
|           } else { | ||||
|             const innerItems = this.renderFilterOptionsFromChildren( | ||||
|               childChildren, | ||||
|               childrenKeys, | ||||
|               menuItems, | ||||
|             ) | ||||
|             if (innerItems.length) { | ||||
|               sel.push( | ||||
|                 <MenuItemGroup key={key} title={label} {...child.data}> | ||||
|                   {innerItems} | ||||
|                 </MenuItemGroup> | ||||
|               ) | ||||
|             } | ||||
|           } | ||||
| 
 | ||||
|           return | ||||
|         } | ||||
|         warning( | ||||
|  | @ -1242,11 +1285,14 @@ const Select = { | |||
|           let content = `+ ${value.length - maxTagCount} ...` | ||||
|           if (maxTagPlaceholder) { | ||||
|             content = typeof maxTagPlaceholder === 'function' | ||||
|               ? maxTagPlaceholder(omittedValues) : maxTagPlaceholder | ||||
|               ? maxTagPlaceholder(omittedValues) | ||||
|               : maxTagPlaceholder | ||||
|           } | ||||
|           maxTagPlaceholderEl = (<li | ||||
|             style={UNSELECTABLE_STYLE} | ||||
|             {...{ attrs: UNSELECTABLE_ATTRIBUTE }} | ||||
|             unselectable='unselectable' | ||||
|             role='presentation' | ||||
|             onMousedown={preventDefaultEvent} | ||||
|             class={`${prefixCls}-selection__choice ${prefixCls}-selection__choice__disabled`} | ||||
|             key='maxTagPlaceholder' | ||||
|  | @ -1274,9 +1320,11 @@ const Select = { | |||
|             return ( | ||||
|               <li | ||||
|                 style={UNSELECTABLE_STYLE} | ||||
|                 {...{ attrs: UNSELECTABLE_ATTRIBUTE }} | ||||
|                 unselectable='unselectable' | ||||
|                 onMousedown={preventDefaultEvent} | ||||
|                 class={choiceClassName} | ||||
|                 role='presentation' | ||||
|                 key={singleValue || SELECT_EMPTY_VALUE_KEY} | ||||
|                 title={toTitle(title)} | ||||
|               > | ||||
|  | @ -1321,11 +1369,7 @@ const Select = { | |||
|             </transition-group> | ||||
|           ) | ||||
|         } else { | ||||
|           innerNode = ( | ||||
|             <ul> | ||||
|               {selectedValueNodes} | ||||
|             </ul> | ||||
|           ) | ||||
|           innerNode = <ul>{selectedValueNodes}</ul> | ||||
|         } | ||||
|       } | ||||
|       return ( | ||||
|  | @ -1342,6 +1386,33 @@ const Select = { | |||
|         </div> | ||||
|       ) | ||||
|     }, | ||||
|     renderArrow (multiple) { | ||||
|       const { showArrow, loading, prefixCls } = this.$props | ||||
|       const inputIcon = getComponentFromProp(this, 'inputIcon') | ||||
|       if (!showArrow) { | ||||
|         return null | ||||
|       } | ||||
|       // if loading  have loading icon | ||||
|       if (multiple && !loading) { | ||||
|         return null | ||||
|       } | ||||
|       const defaultIcon = loading ? ( | ||||
|         <i class={`${prefixCls}-arrow-loading`} /> | ||||
|       ) : ( | ||||
|         <i class={`${prefixCls}-arrow-icon`} /> | ||||
|       ) | ||||
|       return ( | ||||
|         <span | ||||
|           key='arrow' | ||||
|           class={`${prefixCls}-arrow`} | ||||
|           style={UNSELECTABLE_STYLE} | ||||
|           {...{ attrs: UNSELECTABLE_ATTRIBUTE }} | ||||
|           onClick={this.onArrowClick} | ||||
|         > | ||||
|           {inputIcon || defaultIcon} | ||||
|         </span> | ||||
|       ) | ||||
|     }, | ||||
|     topCtrlContainerClick (e) { | ||||
|       if (this.$data._open && !isSingleMode(this.$props)) { | ||||
|         e.stopPropagation() | ||||
|  | @ -1412,7 +1483,6 @@ const Select = { | |||
|     const multiple = isMultipleOrTags(props) | ||||
|     const state = this.$data | ||||
|     const { disabled, prefixCls } = props | ||||
|     const inputIcon = getComponentFromProp(this, 'inputIcon') | ||||
|     const ctrlNode = this.renderTopControlNode() | ||||
|     const { _open: open, _inputValue: inputValue, _value: value } = this.$data | ||||
|     if (open) { | ||||
|  | @ -1429,6 +1499,7 @@ const Select = { | |||
|         'aria-autocomplete': 'list', | ||||
|         'aria-haspopup': 'true', | ||||
|         'aria-expanded': realOpen, | ||||
|         'aria-controls': this.ariaId, | ||||
|       }, | ||||
|       on: { | ||||
|         click: this.selectionRefClick, | ||||
|  | @ -1445,7 +1516,7 @@ const Select = { | |||
|       selectionProps.on.keydown = this.onKeyDown | ||||
|       selectionProps.on.focus = this.selectionRefFocus | ||||
|       selectionProps.on.blur = this.selectionRefBlur | ||||
|       selectionProps.attrs.tabIndex = props.disabled ? -1 : 0 | ||||
|       selectionProps.attrs.tabIndex = props.disabled ? -1 : props.tabIndex | ||||
|     } | ||||
|     const rootCls = { | ||||
|       [prefixCls]: true, | ||||
|  | @ -1492,6 +1563,8 @@ const Select = { | |||
|           name: 'ant-ref', | ||||
|           value: this.saveSelectTriggerRef, | ||||
|         }] }} | ||||
|         dropdownRender={props.dropdownRender} | ||||
|         ariaId={this.ariaId} | ||||
|       > | ||||
|         <div | ||||
|           {...{ directives: [{ | ||||
|  | @ -1510,16 +1583,7 @@ const Select = { | |||
|           <div {...selectionProps}> | ||||
|             {ctrlNode} | ||||
|             {this.renderClear()} | ||||
|             {multiple || !props.showArrow ? null : ( | ||||
|               <span | ||||
|                 key='arrow' | ||||
|                 class={`${prefixCls}-arrow`} | ||||
|                 style={UNSELECTABLE_STYLE} | ||||
|                 unselectable='unselectable' | ||||
|                 // onClick={this.onArrowClick} | ||||
|               > | ||||
|                 {inputIcon || <i class={`${prefixCls}-arrow-icon`} />} | ||||
|               </span>)} | ||||
|             {this.renderArrow(!!multiple)} | ||||
|           </div> | ||||
|         </div> | ||||
|       </SelectTrigger> | ||||
|  |  | |||
|  | @ -55,6 +55,8 @@ export default { | |||
|     getPopupContainer: PropTypes.func, | ||||
|     backfillValue: PropTypes.any, | ||||
|     menuItemSelectedIcon: PropTypes.any, | ||||
|     dropdownRender: PropTypes.func, | ||||
|     ariaId: PropTypes.string, | ||||
|   }, | ||||
|   created () { | ||||
|     this.saveDropdownMenuRef = saveRef(this, 'dropdownMenuRef') | ||||
|  | @ -62,7 +64,7 @@ export default { | |||
|   }, | ||||
|   data () { | ||||
|     return { | ||||
|       dropdownWidth: null, | ||||
|       dropdownWidth: 0, | ||||
|     } | ||||
|   }, | ||||
| 
 | ||||
|  | @ -99,9 +101,13 @@ export default { | |||
|         dropdownMenuStyle, getDropdownPrefixCls, backfillValue, menuItemSelectedIcon, | ||||
|       } = this | ||||
|       const { menuSelect, menuDeselect, popupScroll } = this.$listeners | ||||
|       const props = this.$props | ||||
| 
 | ||||
|       const { dropdownRender, ariaId } = props | ||||
|       const dropdownMenuProps = { | ||||
|         props: { | ||||
|           ...newProps.props, | ||||
|           ariaId, | ||||
|           prefixCls: getDropdownPrefixCls(), | ||||
|           value, firstActiveValue, defaultActiveFirstOption, dropdownMenuStyle, | ||||
|           backfillValue, | ||||
|  | @ -118,9 +124,12 @@ export default { | |||
|           value: this.saveDropdownMenuRef, | ||||
|         }], | ||||
|       } | ||||
|       return ( | ||||
|         <DropdownMenu {...dropdownMenuProps} /> | ||||
|       ) | ||||
|       const menuNode = <DropdownMenu {...dropdownMenuProps} /> | ||||
| 
 | ||||
|       if (dropdownRender) { | ||||
|         return dropdownRender(menuNode, props) | ||||
|       } | ||||
|       return null | ||||
|     }, | ||||
| 
 | ||||
|     getDropdownTransitionName () { | ||||
|  |  | |||
|  | @ -1,7 +1,16 @@ | |||
| @selectPrefixCls: rc-select; | ||||
| 
 | ||||
| @keyframes select-ring { | ||||
|   0% { | ||||
|     transform: rotate(0deg); | ||||
|   } | ||||
|   100% { | ||||
|     transform: rotate(360deg); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .effect() { | ||||
|   animation-duration: .3s; | ||||
|   animation-duration: 0.3s; | ||||
|   animation-fill-mode: both; | ||||
|   transform-origin: 0 0; | ||||
| } | ||||
|  | @ -14,7 +23,8 @@ | |||
|   color: #666; | ||||
|   line-height: 28px; | ||||
| 
 | ||||
|   ul, li { | ||||
|   ul, | ||||
|   li { | ||||
|     margin: 0; | ||||
|     padding: 0; | ||||
|     list-style: none; | ||||
|  | @ -35,17 +45,36 @@ | |||
|     outline: none; | ||||
|   } | ||||
| 
 | ||||
|   &-arrow &-arrow-loading { | ||||
|     display: inline-block; | ||||
|     width: 18px; | ||||
|     height: 18px; | ||||
|     margin-top: 6px; | ||||
|     margin-left: -4px; | ||||
|     &:after { | ||||
|       content: ' '; | ||||
|       display: block; | ||||
|       width: 12px; | ||||
|       height: 12px; | ||||
|       margin: 2px; | ||||
|       border-radius: 50%; | ||||
|       border: 2px solid #999999; | ||||
|       border-color: #999999 transparent #999999 transparent; | ||||
|       animation: select-ring 1.2s linear infinite; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   &-arrow &-arrow-icon { | ||||
|     border-color: #999999 transparent transparent transparent; | ||||
|       border-style: solid; | ||||
|       border-width: 5px 4px 0 4px; | ||||
|       height: 0; | ||||
|       width: 0; | ||||
|       margin-left: -4px; | ||||
|       margin-top: -2px; | ||||
|       position: absolute; | ||||
|       top: 50%; | ||||
|       left: 50%; | ||||
|     border-style: solid; | ||||
|     border-width: 5px 4px 0 4px; | ||||
|     height: 0; | ||||
|     width: 0; | ||||
|     margin-left: -4px; | ||||
|     margin-top: -2px; | ||||
|     position: absolute; | ||||
|     top: 50%; | ||||
|     left: 50%; | ||||
|   } | ||||
| 
 | ||||
|   &-selection { | ||||
|  | @ -251,15 +280,18 @@ | |||
|     margin-right: 4px; | ||||
|     position: relative; | ||||
|     overflow: hidden; | ||||
|     transition: padding .3s cubic-bezier(0.6, -0.28, 0.735, 0.045), width .3s cubic-bezier(0.6, -0.28, 0.735, 0.045); | ||||
|     transition: padding 0.3s cubic-bezier(0.6, -0.28, 0.735, 0.045), | ||||
|       width 0.3s cubic-bezier(0.6, -0.28, 0.735, 0.045); | ||||
| 
 | ||||
|     &__content { | ||||
|       margin-left: 0; | ||||
|       margin-right: 0; | ||||
|       transition: margin .3s cubic-bezier(0.165, 0.84, 0.44, 1); | ||||
|       transition: margin 0.3s cubic-bezier(0.165, 0.84, 0.44, 1); | ||||
|     } | ||||
| 
 | ||||
|     &-zoom-enter, &-zoom-appear, &-zoom-leave { | ||||
|     &-zoom-enter, | ||||
|     &-zoom-appear, | ||||
|     &-zoom-leave { | ||||
|       .effect(); | ||||
|       opacity: 0; | ||||
|       animation-play-state: paused; | ||||
|  | @ -310,7 +342,7 @@ | |||
|       transform: scale(0); | ||||
|       top: 0; | ||||
|       right: 2px; | ||||
|       transition: opacity .3s, transform .3s; | ||||
|       transition: opacity 0.3s, transform 0.3s; | ||||
| 
 | ||||
|       &-icon { | ||||
|         font-style: normal; | ||||
|  | @ -402,7 +434,8 @@ | |||
|       } | ||||
|     } | ||||
| 
 | ||||
|     &-slide-up-enter, &-slide-up-appear { | ||||
|     &-slide-up-enter, | ||||
|     &-slide-up-appear { | ||||
|       .effect(); | ||||
|       opacity: 0; | ||||
|       animation-timing-function: cubic-bezier(0.08, 0.82, 0.17, 1); | ||||
|  | @ -416,7 +449,8 @@ | |||
|       animation-play-state: paused; | ||||
|     } | ||||
| 
 | ||||
|     &-slide-up-enter&-slide-up-enter-active&-placement-bottomLeft, &-slide-up-appear&-slide-up-appear-active&-placement-bottomLeft { | ||||
|     &-slide-up-enter&-slide-up-enter-active&-placement-bottomLeft, | ||||
|     &-slide-up-appear&-slide-up-appear-active&-placement-bottomLeft { | ||||
|       animation-name: rcSelectDropdownSlideUpIn; | ||||
|       animation-play-state: running; | ||||
|     } | ||||
|  | @ -426,7 +460,8 @@ | |||
|       animation-play-state: running; | ||||
|     } | ||||
| 
 | ||||
|     &-slide-up-enter&-slide-up-enter-active&-placement-topLeft, &-slide-up-appear&-slide-up-appear-active&-placement-topLeft { | ||||
|     &-slide-up-enter&-slide-up-enter-active&-placement-topLeft, | ||||
|     &-slide-up-appear&-slide-up-appear-active&-placement-topLeft { | ||||
|       animation-name: rcSelectDropdownSlideDownIn; | ||||
|       animation-play-state: running; | ||||
|     } | ||||
|  | @ -493,5 +528,4 @@ | |||
|       border-width: 0 4px 5px 4px; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ export function toTitle (title) { | |||
|   if (typeof title === 'string') { | ||||
|     return title | ||||
|   } | ||||
|   return null | ||||
|   return '' | ||||
| } | ||||
| export function getValuePropValue (child) { | ||||
|   if (!child) { | ||||
|  | @ -24,9 +24,7 @@ export function getValuePropValue (child) { | |||
|       return label | ||||
|     } | ||||
|   } | ||||
|   throw new Error( | ||||
|     `Need at least a key or a value or a label(slot) (only for OptGroup) for ${child}` | ||||
|   ) | ||||
|   throw new Error(`Need at least a key or a value or a label (only for OptGroup) for ${child}`) | ||||
| } | ||||
| 
 | ||||
| export function getPropValue (child, prop) { | ||||
|  | @ -88,10 +86,12 @@ export function preventDefaultEvent (e) { | |||
| 
 | ||||
| export function findIndexInValueBySingleValue (value, singleValue) { | ||||
|   let index = -1 | ||||
|   for (let i = 0; i < value.length; i++) { | ||||
|     if (value[i] === singleValue) { | ||||
|       index = i | ||||
|       break | ||||
|   if (value) { | ||||
|     for (let i = 0; i < value.length; i++) { | ||||
|       if (value[i] === singleValue) { | ||||
|         index = i | ||||
|         break | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   return index | ||||
|  | @ -100,10 +100,12 @@ export function findIndexInValueBySingleValue (value, singleValue) { | |||
| export function getLabelFromPropsValue (value, key) { | ||||
|   let label | ||||
|   value = toArray(value) | ||||
|   for (let i = 0; i < value.length; i++) { | ||||
|     if (value[i].key === key) { | ||||
|       label = value[i].label | ||||
|       break | ||||
|   if (value) { | ||||
|     for (let i = 0; i < value.length; i++) { | ||||
|       if (value[i].key === key) { | ||||
|         label = value[i].label | ||||
|         break | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   return label | ||||
|  | @ -155,18 +157,18 @@ export function findFirstMenuItem (children) { | |||
|   return null | ||||
| } | ||||
| 
 | ||||
| export function includesSeparators (string, separators) { | ||||
| export function includesSeparators (str, separators) { | ||||
|   for (let i = 0; i < separators.length; ++i) { | ||||
|     if (string.lastIndexOf(separators[i]) > 0) { | ||||
|     if (str.lastIndexOf(separators[i]) > 0) { | ||||
|       return true | ||||
|     } | ||||
|   } | ||||
|   return false | ||||
| } | ||||
| 
 | ||||
| export function splitBySeparators (string, separators) { | ||||
| export function splitBySeparators (str, separators) { | ||||
|   const reg = new RegExp(`[${separators.join()}]`) | ||||
|   return string.split(reg).filter(token => token) | ||||
|   return str.split(reg).filter(token => token) | ||||
| } | ||||
| 
 | ||||
| export function defaultFilterFn (input, child) { | ||||
|  | @ -180,9 +182,7 @@ export function defaultFilterFn (input, child) { | |||
|   } else { | ||||
|     value = String(value) | ||||
|   } | ||||
|   return ( | ||||
|     value.toLowerCase().indexOf(input.toLowerCase()) > -1 | ||||
|   ) | ||||
|   return value.toLowerCase().indexOf(input.toLowerCase()) > -1 | ||||
| } | ||||
| 
 | ||||
| export function validateOptionValue (value, props) { | ||||
|  | @ -192,7 +192,7 @@ export function validateOptionValue (value, props) { | |||
|   if (typeof value !== 'string') { | ||||
|     throw new Error( | ||||
|       `Invalid \`value\` of type \`${typeof value}\` supplied to Option, ` + | ||||
|       `expected \`string\` when \`tags/combobox\` is \`true\`.` | ||||
|         `expected \`string\` when \`tags/combobox\` is \`true\`.`, | ||||
|     ) | ||||
|   } | ||||
| } | ||||
|  | @ -202,3 +202,16 @@ export function saveRef (instance, name) { | |||
|     instance[name] = node | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export function generateUUID () { | ||||
|   if (process.env.NODE_ENV === 'test') { | ||||
|     return 'test-uuid' | ||||
|   } | ||||
|   let d = new Date().getTime() | ||||
|   const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => { | ||||
|     const r = (d + Math.random() * 16) % 16 | 0 | ||||
|     d = Math.floor(d / 16) | ||||
|     return (c === 'x' ? r : (r & 0x7) | 0x8).toString(16) | ||||
|   }) | ||||
|   return uuid | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 tangjinzhou
						tangjinzhou