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