fix select

pull/165/head
tangjinzhou 2018-02-09 18:42:19 +08:00
parent 75bf88dbe4
commit 19b108db83
6 changed files with 79 additions and 38 deletions

View File

@ -59,19 +59,23 @@ export function cloneElement (n, nodeProps, clone) {
return null return null
} }
const node = clone ? cloneVNode(ele, true) : ele const node = clone ? cloneVNode(ele, true) : ele
const { props = {}, key, on = {}} = nodeProps const { props = {}, key, on = {}, children } = nodeProps
const data = node.data || {} const data = node.data || {}
const { style = data.style, const { style = data.style,
class: cls = data.class, class: cls = data.class,
attrs = data.attrs, attrs = data.attrs,
ref, ref,
domProps = data.domProps,
} = nodeProps } = nodeProps
node.data = Object.assign({}, data, { style, attrs, class: cls }) node.data = Object.assign({}, data, { style, attrs, class: cls, domProps })
if (node.componentOptions) { if (node.componentOptions) {
node.componentOptions.propsData = node.componentOptions.propsData || {} node.componentOptions.propsData = node.componentOptions.propsData || {}
node.componentOptions.listeners = node.componentOptions.listeners || {} node.componentOptions.listeners = node.componentOptions.listeners || {}
node.componentOptions.propsData = { ...node.componentOptions.propsData, ...props } node.componentOptions.propsData = { ...node.componentOptions.propsData, ...props }
node.componentOptions.listeners = { ...node.componentOptions.listeners, ...on } node.componentOptions.listeners = { ...node.componentOptions.listeners, ...on }
if (children) {
node.componentOptions.children = children
}
} else { } else {
node.data.on = { ...(node.data.on || {}), ...on } node.data.on = { ...(node.data.on || {}), ...on }
} }

View File

@ -118,13 +118,14 @@ export default {
ref: 'popupInstance', ref: 'popupInstance',
style: { ...this.getZIndexStyle(), ...popupStyle }, style: { ...this.getZIndexStyle(), ...popupStyle },
} }
const transitionProps = { let transitionProps = {
props: Object.assign({ props: Object.assign({
appear: true, appear: true,
css: false, css: false,
}), }),
} }
const transitionName = getTransitionName() const transitionName = getTransitionName()
let useTransition = !!transitionName
const transitionEvent = { const transitionEvent = {
beforeEnter: (el) => { beforeEnter: (el) => {
el.style.display = el.__vOriginalDisplay el.style.display = el.__vOriginalDisplay
@ -144,6 +145,7 @@ export default {
} }
if (typeof animation === 'object') { if (typeof animation === 'object') {
useTransition = true
const { on = {}, props = {}} = animation const { on = {}, props = {}} = animation
transitionProps.props = { ...transitionProps.props, ...props } transitionProps.props = { ...transitionProps.props, ...props }
transitionProps.on = { ...transitionEvent, ...on, afterLeave: (el) => { transitionProps.on = { ...transitionEvent, ...on, afterLeave: (el) => {
@ -153,6 +155,9 @@ export default {
} else { } else {
transitionProps.on = transitionEvent transitionProps.on = transitionEvent
} }
if (!useTransition) {
transitionProps = {}
}
return (<transition return (<transition
{...transitionProps} {...transitionProps}
> >

View File

@ -33,7 +33,7 @@ const MenuItem = {
onKeyDown (e) { onKeyDown (e) {
const keyCode = e.keyCode const keyCode = e.keyCode
if (keyCode === KeyCode.ENTER) { if (keyCode === KeyCode.ENTER) {
this.__emit('click', e) this.onClick(e)
return true return true
} }
}, },

View File

@ -5,6 +5,7 @@ import scrollIntoView from 'dom-scroll-into-view'
import { getSelectKeys, preventDefaultEvent } from './util' import { getSelectKeys, preventDefaultEvent } from './util'
import { cloneElement } from '../_util/vnode' import { cloneElement } from '../_util/vnode'
import BaseMixin from '../_util/BaseMixin' import BaseMixin from '../_util/BaseMixin'
import { hasProp, getSlotOptions } from '../_util/props-util'
export default { export default {
name: 'DropdownMenu', name: 'DropdownMenu',
@ -144,9 +145,9 @@ export default {
} }
clonedMenuItems = menuItems.map(item => { clonedMenuItems = menuItems.map(item => {
if (item.type.isMenuItemGroup) { if (getSlotOptions(item).isMenuItemGroup) {
const children = item.$slots.default.map(clone) const children = item.componentOptions.children.map(clone)
return cloneElement(item, {}, children) return cloneElement(item, { children })
} }
return clone(item) return clone(item)
}) })

View File

@ -7,6 +7,7 @@ export default {
PropTypes.string, PropTypes.string,
PropTypes.number, PropTypes.number,
]), ]),
disabled: PropTypes.bool,
}, },
isSelectOption: true, isSelectOption: true,
} }

View File

@ -31,7 +31,6 @@ import {
} from './util' } from './util'
import SelectTrigger from './SelectTrigger' import SelectTrigger from './SelectTrigger'
import { SelectPropTypes } from './PropTypes' import { SelectPropTypes } from './PropTypes'
import { setTimeout } from 'timers'
function noop () {} function noop () {}
@ -128,7 +127,7 @@ export default {
}) })
} }
} }
this.adjustOpenState() // this.adjustOpenState()
}, },
deep: true, deep: true,
}, },
@ -190,6 +189,7 @@ export default {
}, },
onDropdownVisibleChange (open) { onDropdownVisibleChange (open) {
console.log('onDropdownVisibleChange', open)
if (open && !this._focused) { if (open && !this._focused) {
this.clearBlurTime() this.clearBlurTime()
this.timeoutFocus() this.timeoutFocus()
@ -321,10 +321,10 @@ export default {
}, },
onArrowClick (e) { onArrowClick (e) {
// e.stopPropagation() e.stopPropagation()
// if (!this.disabled) { if (!this.disabled) {
// this.setOpenState(!this.openStatus, !this.openStatus) this.setOpenState(!this.openStatus, !this.openStatus)
// } }
}, },
onPlaceholderClick (e) { onPlaceholderClick (e) {
@ -363,11 +363,13 @@ export default {
}, },
onOuterBlur (e) { onOuterBlur (e) {
console.log('onOuterBlur')
if (this.disabled) { if (this.disabled) {
e.preventDefault() e.preventDefault()
return return
} }
this.blurTimer = setTimeout(() => { this.blurTimer = setTimeout(() => {
console.log('onOuterBlur setTimeout')
this._focused = false this._focused = false
this.updateFocusClassName() this.updateFocusClassName()
const props = this.$props const props = this.$props
@ -399,6 +401,7 @@ export default {
this.__emit('blur', this.getVLForOnChange(sValue)) this.__emit('blur', this.getVLForOnChange(sValue))
this.setOpenState(false) this.setOpenState(false)
}, 10) }, 10)
console.log('this.blurTimer', this.blurTimer)
}, },
onClearSelection (event) { onClearSelection (event) {
@ -406,15 +409,21 @@ export default {
if (disabled) { if (disabled) {
return return
} }
event.stopPropagation()
if (inputValue || sValue.length) { if (inputValue || sValue.length) {
if (sValue.length) { if (sValue.length) {
this.fireChange([]) this.fireChange([])
} }
this.setOpenState(false, true) // this.setOpenState(false, true)
if (inputValue) { if (inputValue) {
this.setInputValue('') this.setInputValue('')
} }
if (this._focused) {
this._focused = false
} else {
event.stopPropagation()
}
} else {
event.stopPropagation()
} }
}, },
@ -516,9 +525,6 @@ export default {
} }
if (placeholder) { if (placeholder) {
const p = { const p = {
props: {
},
on: { on: {
mousedown: preventDefaultEvent, mousedown: preventDefaultEvent,
click: this.onPlaceholderClick, click: this.onPlaceholderClick,
@ -540,37 +546,47 @@ export default {
}, },
inputClick (e) { inputClick (e) {
if (this._focused) { if (this._focused) {
e.stopPropagation() if (this.openStatus) {
e.stopPropagation()
} else {
this._focused = false
}
} }
}, },
inputBlur (e) { inputBlur (e) {
// console.log(e.target)
this.clearBlurTime() this.clearBlurTime()
this.blurTimer = setTimeout(() => { this.blurTimer = setTimeout(() => {
this.onOuterBlur()
if (!this.disabled) { if (!this.disabled) {
this.setOpenState(!this.openStatus, !this.openStatus) this._focused = false
this.setOpenState(false, false)
} }
}, 10) }, 10)
}, },
inputFocus (e) {
this.clearBlurTime()
},
_getInputElement () { _getInputElement () {
const props = this.$props const props = this.$props
const inputElement = props.getInputElement const inputElement = props.getInputElement
? props.getInputElement() ? props.getInputElement()
: <input id={props.id} autoComplete='off' /> : <input id={props.id} autoComplete='off' value='1111'/>
const inputCls = classnames(getClass(inputElement), { const inputCls = classnames(getClass(inputElement), {
[`${props.prefixCls}-search__field`]: true, [`${props.prefixCls}-search__field`]: true,
}) })
const inputEvents = getEvents(inputElement) const inputEvents = getEvents(inputElement)
// https://github.com/ant-design/ant-design/issues/4992#issuecomment-281542159 // https://github.com/ant-design/ant-design/issues/4992#issuecomment-281542159
// Add space to the end of the inputValue as the width measurement tolerance // Add space to the end of the inputValue as the width measurement tolerance
inputElement.data = inputElement.data || {}
return ( return (
<div class={`${props.prefixCls}-search__field__wrap`}> <div class={`${props.prefixCls}-search__field__wrap`}>
{cloneElement(inputElement, { {cloneElement(inputElement, {
attrs: { attrs: {
value: this.inputValue, ...(inputElement.data.attrs || {}),
disabled: props.disabled, disabled: props.disabled,
}, },
domProps: {
value: this.inputValue,
},
class: inputCls, class: inputCls,
ref: 'inputRef', ref: 'inputRef',
on: { on: {
@ -580,10 +596,10 @@ export default {
inputEvents.keydown || noop, inputEvents.keydown || noop,
this.$listeners.inputKeydown this.$listeners.inputKeydown
), ),
// focus: chaining( focus: chaining(
// this.onOuterFocus, this.inputFocus,
// inputEvents.focus || noop, inputEvents.focus || noop,
// ), ),
blur: chaining( blur: chaining(
this.inputBlur, this.inputBlur,
inputEvents.blur || noop, inputEvents.blur || noop,
@ -622,9 +638,9 @@ export default {
return this.$refs.selectTriggerRef.getInnerMenu() return this.$refs.selectTriggerRef.getInnerMenu()
}, },
setOpenState (open, needFocus) { setOpenState (open, needFocus, forceSet) {
const { $props: props, openStatus } = this const { $props: props, openStatus } = this
if (openStatus === open) { if (!forceSet && openStatus === open) {
this.maybeFocus(open, needFocus) this.maybeFocus(open, needFocus)
return return
} }
@ -894,9 +910,7 @@ export default {
// If hidden menu due to no options, then it should be calculated again // If hidden menu due to no options, then it should be calculated again
if (sOpen || this.hiddenForNoOptions) { if (sOpen || this.hiddenForNoOptions) {
options = this.renderFilterOptions() options = this.renderFilterOptions()
console.log('options', options)
} }
console.log('options1', options)
this._options = options this._options = options
if (isMultipleOrTagsOrCombobox($props) || !showSearch) { if (isMultipleOrTagsOrCombobox($props) || !showSearch) {
@ -915,15 +929,16 @@ export default {
getOptionsAndOpenStatus () { getOptionsAndOpenStatus () {
let sOpen = this.sOpen let sOpen = this.sOpen
if (this.skipAdjustOpen) { if (this.skipAdjustOpen) {
this.openStatus = sOpen
return { return {
option: this._options, options: this._options,
open: sOpen, open: sOpen,
} }
} }
const { $props, showSearch } = this const { $props, showSearch } = this
let options = [] let options = []
// If hidden menu due to no options, then it should be calculated again // If hidden menu due to no options, then it should be calculated again
if (true || sOpen || this.hiddenForNoOptions) { if (sOpen || this.hiddenForNoOptions) {
options = this.renderFilterOptions() options = this.renderFilterOptions()
} }
this._options = options this._options = options
@ -1299,6 +1314,21 @@ export default {
// this.getInputDOMNode().focus() // this.getInputDOMNode().focus()
} }
}, },
selectionRefClick (e) {
e.stopPropagation()
this.clearBlurTime()
if (!this.disabled) {
if (this._focused && this.openStatus) {
this._focused = false
this.setOpenState(false, false, true)
this.getInputDOMNode().blur()
} else {
this._focused = true
this.setOpenState(true, true, true)
this.getInputDOMNode().focus()
}
}
},
}, },
render () { render () {
@ -1324,7 +1354,6 @@ export default {
[`${prefixCls}-enabled`]: !disabled, [`${prefixCls}-enabled`]: !disabled,
[`${prefixCls}-allow-clear`]: !!props.allowClear, [`${prefixCls}-allow-clear`]: !!props.allowClear,
} }
console.log(options)
return ( return (
<SelectTrigger <SelectTrigger
dropdownAlign={props.dropdownAlign} dropdownAlign={props.dropdownAlign}
@ -1360,8 +1389,9 @@ export default {
ref='rootRef' ref='rootRef'
// onBlur={this.onOuterBlur} // onBlur={this.onOuterBlur}
// onFocus={this.onOuterFocus} // onFocus={this.onOuterFocus}
onClick={this.rootRefClick} // onClick={this.rootRefClick}
class={classnames(rootCls)} class={classnames(rootCls)}
// tabindex='-1'
> >
<div <div
ref='selectionRef' ref='selectionRef'
@ -1373,7 +1403,7 @@ export default {
aria-haspopup='true' aria-haspopup='true'
aria-expanded={openStatus} aria-expanded={openStatus}
{...extraSelectionProps} {...extraSelectionProps}
// onClick={this.stopPropagation} onClick={this.selectionRefClick}
> >
{ctrlNode} {ctrlNode}
{this.renderClear()} {this.renderClear()}
@ -1383,7 +1413,7 @@ export default {
class={`${prefixCls}-arrow`} class={`${prefixCls}-arrow`}
style={UNSELECTABLE_STYLE} style={UNSELECTABLE_STYLE}
unselectable='unselectable' unselectable='unselectable'
onClick={this.onArrowClick} // onClick={this.onArrowClick}
> >
<b /> <b />
</span>)} </span>)}