wangxueliang 7 years ago
commit 4e4695e985

@ -22,6 +22,7 @@ export default {
mask: PropTypes.bool, mask: PropTypes.bool,
zIndex: PropTypes.number, zIndex: PropTypes.number,
popupClassName: PropTypes.any, popupClassName: PropTypes.any,
popupStyle: PropTypes.object.def({}),
}, },
data () { data () {
return { return {
@ -99,7 +100,7 @@ export default {
}, },
getPopupElement () { getPopupElement () {
const { $props: props, $slots, $listeners, getTransitionName } = this const { $props: props, $slots, $listeners, getTransitionName } = this
const { align, visible, prefixCls, animation } = props const { align, visible, prefixCls, animation, popupStyle } = props
const { mouseenter, mouseleave } = $listeners const { mouseenter, mouseleave } = $listeners
const className = this.getClassName(props.getClassNameFromAlign(align)) const className = this.getClassName(props.getClassNameFromAlign(align))
// const hiddenClassName = `${prefixCls}-hidden` // const hiddenClassName = `${prefixCls}-hidden`
@ -115,7 +116,7 @@ export default {
mouseleave: mouseleave || noop, mouseleave: mouseleave || noop,
}, },
ref: 'popupInstance', ref: 'popupInstance',
style: { ...this.getZIndexStyle() }, style: { ...this.getZIndexStyle(), ...popupStyle },
} }
const transitionProps = { const transitionProps = {
props: Object.assign({ props: Object.assign({

@ -340,12 +340,12 @@ export default {
}, },
el: div, el: div,
render () { render () {
const { popupStyle, popupEvents, ...otherProps } = this.popupProps const { popupEvents, ...otherProps } = this.popupProps
const p = { const p = {
props: otherProps, props: otherProps,
on: popupEvents, on: popupEvents,
ref: 'popup', ref: 'popup',
style: popupStyle, // style: popupStyle,
} }
return ( return (
<Popup <Popup

@ -31,6 +31,7 @@ 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 () {}
@ -94,13 +95,15 @@ export default {
if (sOpen === undefined) { if (sOpen === undefined) {
sOpen = defaultOpen sOpen = defaultOpen
} }
this.adjustOpenState()
return { return {
sValue, sValue,
inputValue, inputValue,
sOpen, sOpen,
} }
}, },
beforeMount () {
// this.adjustOpenState()
},
mounted () { mounted () {
this.$nextTick(() => { this.$nextTick(() => {
this.autoFocus && this.focus() this.autoFocus && this.focus()
@ -144,7 +147,10 @@ export default {
} }
}) })
}, },
beforeUpdate () {
// console.log('beforeUpdate')
// this.adjustOpenState()
},
beforeDestroy () { beforeDestroy () {
this.clearFocusTime() this.clearFocusTime()
this.clearBlurTime() this.clearBlurTime()
@ -195,12 +201,12 @@ export default {
// combobox ignore // combobox ignore
onKeyDown (event) { onKeyDown (event) {
const { disabled, sOpen } = this const { disabled, openStatus } = this
if (disabled) { if (disabled) {
return return
} }
const keyCode = event.keyCode const keyCode = event.keyCode
if (sOpen && !this.getInputDOMNode()) { if (openStatus && !this.getInputDOMNode()) {
this.onInputKeydown(event) this.onInputKeydown(event)
} else if (keyCode === KeyCode.ENTER || keyCode === KeyCode.DOWN) { } else if (keyCode === KeyCode.ENTER || keyCode === KeyCode.DOWN) {
this.setOpenState(true) this.setOpenState(true)
@ -209,7 +215,7 @@ export default {
}, },
onInputKeydown (event) { onInputKeydown (event) {
const { disabled, sOpen, sValue, $props } = this const { disabled, openStatus, sValue, $props } = this
if (disabled) { if (disabled) {
return return
} }
@ -226,14 +232,14 @@ export default {
return return
} }
if (keyCode === KeyCode.DOWN) { if (keyCode === KeyCode.DOWN) {
if (!sOpen) { if (!openStatus) {
this.openIfHasChildren() this.openIfHasChildren()
event.preventDefault() event.preventDefault()
event.stopPropagation() event.stopPropagation()
return return
} }
} else if (keyCode === KeyCode.ESC) { } else if (keyCode === KeyCode.ESC) {
if (sOpen) { if (openStatus) {
this.setOpenState(false) this.setOpenState(false)
event.preventDefault() event.preventDefault()
event.stopPropagation() event.stopPropagation()
@ -241,7 +247,7 @@ export default {
return return
} }
if (sOpen) { if (openStatus) {
const menu = this.$refs.selectTriggerRef.getInnerMenu() const menu = this.$refs.selectTriggerRef.getInnerMenu()
if (menu && menu.onKeyDown(event, this.handleBackfill)) { if (menu && menu.onKeyDown(event, this.handleBackfill)) {
event.preventDefault() event.preventDefault()
@ -315,19 +321,23 @@ export default {
}, },
onArrowClick (e) { onArrowClick (e) {
e.stopPropagation() // e.stopPropagation()
if (!this.disabled) { // if (!this.disabled) {
this.setOpenState(!this.sOpen, !this.sOpen) // this.setOpenState(!this.openStatus, !this.openStatus)
} // }
}, },
onPlaceholderClick () { onPlaceholderClick (e) {
if (this._focused) {
e.stopPropagation()
}
if (this.getInputDOMNode()) { if (this.getInputDOMNode()) {
this.getInputDOMNode().focus() this.getInputDOMNode().focus()
} }
}, },
onOuterFocus (e) { onOuterFocus (e) {
console.log('onOuterFocus')
if (this.disabled) { if (this.disabled) {
e.preventDefault() e.preventDefault()
return return
@ -386,7 +396,7 @@ export default {
// why not use setState? // why not use setState?
this.inputValue = this.getInputDOMNode().value = '' this.inputValue = this.getInputDOMNode().value = ''
} }
this._emit('blur', this.getVLForOnChange(sValue)) this.__emit('blur', this.getVLForOnChange(sValue))
this.setOpenState(false) this.setOpenState(false)
}, 10) }, 10)
}, },
@ -528,7 +538,21 @@ export default {
} }
return null return null
}, },
inputClick (e) {
if (this._focused) {
e.stopPropagation()
}
},
inputBlur (e) {
// console.log(e.target)
this.clearBlurTime()
this.blurTimer = setTimeout(() => {
this.onOuterBlur()
if (!this.disabled) {
this.setOpenState(!this.openStatus, !this.openStatus)
}
}, 10)
},
_getInputElement () { _getInputElement () {
const props = this.$props const props = this.$props
const inputElement = props.getInputElement const inputElement = props.getInputElement
@ -537,15 +561,15 @@ export default {
const inputCls = classnames(getClass(inputElement), { const inputCls = classnames(getClass(inputElement), {
[`${props.prefixCls}-search__field`]: true, [`${props.prefixCls}-search__field`]: true,
}) })
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
return ( return (
<div class={`${props.prefixCls}-search__field__wrap`}> <div class={`${props.prefixCls}-search__field__wrap`}>
{cloneElement(inputElement, { {cloneElement(inputElement, {
props: { attrs: {
value: this.inputValue, value: this.inputValue,
disabled: props.disabled, disabled: props.disabled,
}, },
class: inputCls, class: inputCls,
ref: 'inputRef', ref: 'inputRef',
@ -553,9 +577,21 @@ export default {
input: this.onInputChange, input: this.onInputChange,
keydown: chaining( keydown: chaining(
this.onInputKeydown, this.onInputKeydown,
getEvents(inputElement).keydown || noop, inputEvents.keydown || noop,
this.$listeners.inputKeydown this.$listeners.inputKeydown
), ),
// focus: chaining(
// this.onOuterFocus,
// inputEvents.focus || noop,
// ),
blur: chaining(
this.inputBlur,
inputEvents.blur || noop,
),
click: chaining(
this.inputClick,
inputEvents.click || noop,
),
}, },
})} })}
<span <span
@ -587,8 +623,8 @@ export default {
}, },
setOpenState (open, needFocus) { setOpenState (open, needFocus) {
const { $props: props, $data: state } = this const { $props: props, openStatus } = this
if (state.sOpen === open) { if (openStatus === open) {
this.maybeFocus(open, needFocus) this.maybeFocus(open, needFocus)
return return
} }
@ -858,7 +894,9 @@ 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) {
@ -874,7 +912,39 @@ export default {
} }
this.sOpen = sOpen this.sOpen = sOpen
}, },
getOptionsAndOpenStatus () {
let sOpen = this.sOpen
if (this.skipAdjustOpen) {
return {
option: this._options,
open: sOpen,
}
}
const { $props, showSearch } = this
let options = []
// If hidden menu due to no options, then it should be calculated again
if (true || sOpen || this.hiddenForNoOptions) {
options = this.renderFilterOptions()
}
this._options = options
if (isMultipleOrTagsOrCombobox($props) || !showSearch) {
if (sOpen && !options.length) {
sOpen = false
this.hiddenForNoOptions = true
}
// Keep menu open if there are options and hidden for no options before
if (this.hiddenForNoOptions && options.length) {
sOpen = true
this.hiddenForNoOptions = false
}
}
this.openStatus = sOpen
return {
options,
open: sOpen,
}
},
renderFilterOptions () { renderFilterOptions () {
const { inputValue } = this const { inputValue } = this
const { $slots, tags, filterOption, notFoundContent } = this const { $slots, tags, filterOption, notFoundContent } = this
@ -1030,8 +1100,8 @@ export default {
return sel return sel
}, },
renderTopControlNode () { renderTopControlNode (openStatus) {
const { sValue, sOpen, inputValue, $props: props } = this const { sValue, inputValue, $props: props } = this
const { const {
choiceTransitionName, choiceTransitionName,
prefixCls, prefixCls,
@ -1051,7 +1121,7 @@ export default {
if (!showSearch) { if (!showSearch) {
showSelectedValue = true showSelectedValue = true
} else { } else {
if (sOpen) { if (openStatus) {
showSelectedValue = !inputValue showSelectedValue = !inputValue
if (showSelectedValue) { if (showSelectedValue) {
opacity = 0.4 opacity = 0.4
@ -1084,7 +1154,7 @@ export default {
class={`${prefixCls}-search ${prefixCls}-search--inline`} class={`${prefixCls}-search ${prefixCls}-search--inline`}
key='input' key='input'
style={{ style={{
display: sOpen ? 'block' : 'none', display: openStatus ? 'block' : 'none',
}} }}
> >
{this._getInputElement()} {this._getInputElement()}
@ -1165,7 +1235,7 @@ export default {
if (isMultipleOrTags(props) && choiceTransitionName) { if (isMultipleOrTags(props) && choiceTransitionName) {
const transitionProps = getTransitionProps(choiceTransitionName, { const transitionProps = getTransitionProps(choiceTransitionName, {
tag: 'ul', tag: 'ul',
afterLeave: this.onChoiceAnimationLeave, // beforeEnter: this.onChoiceAnimationLeave,
}) })
innerNode = ( innerNode = (
<transition-group <transition-group
@ -1219,16 +1289,26 @@ export default {
} }
return null return null
}, },
rootRefClick (e) {
// e.stopPropagation()
if (this._focused) {
// this.getInputDOMNode().blur()
this.onOuterBlur()
} else {
this.onOuterFocus()
// this.getInputDOMNode().focus()
}
},
}, },
render () { render () {
const props = this.$props const props = this.$props
const multiple = isMultipleOrTags(props) const multiple = isMultipleOrTags(props)
const { disabled, prefixCls, sOpen, inputValue, sValue, $listeners } = this const { options, open: openStatus } = this.getOptionsAndOpenStatus()
const { disabled, prefixCls, inputValue, sValue, $listeners } = this
const { mouseenter = noop, mouseleave = noop, popupScroll = noop } = $listeners const { mouseenter = noop, mouseleave = noop, popupScroll = noop } = $listeners
const ctrlNode = this.renderTopControlNode() const ctrlNode = this.renderTopControlNode(openStatus)
let extraSelectionProps = {} let extraSelectionProps = {}
const options = this._options
if (!isMultipleOrTagsOrCombobox(props)) { if (!isMultipleOrTagsOrCombobox(props)) {
extraSelectionProps = { extraSelectionProps = {
onKeyDown: this.onKeyDown, onKeyDown: this.onKeyDown,
@ -1237,13 +1317,14 @@ export default {
} }
const rootCls = { const rootCls = {
[prefixCls]: 1, [prefixCls]: 1,
[`${prefixCls}-open`]: sOpen, [`${prefixCls}-open`]: openStatus,
[`${prefixCls}-focused`]: sOpen || !!this._focused, [`${prefixCls}-focused`]: openStatus || !!this._focused,
[`${prefixCls}-combobox`]: isCombobox(props), [`${prefixCls}-combobox`]: isCombobox(props),
[`${prefixCls}-disabled`]: disabled, [`${prefixCls}-disabled`]: disabled,
[`${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}
@ -1260,7 +1341,7 @@ export default {
options={options} options={options}
multiple={multiple} multiple={multiple}
disabled={disabled} disabled={disabled}
visible={sOpen} visible={openStatus}
inputValue={inputValue} inputValue={inputValue}
value={sValue} value={sValue}
firstActiveValue={props.firstActiveValue} firstActiveValue={props.firstActiveValue}
@ -1277,8 +1358,9 @@ export default {
> >
<div <div
ref='rootRef' ref='rootRef'
onBlur={this.onOuterBlur} // onBlur={this.onOuterBlur}
onFocus={this.onOuterFocus} // onFocus={this.onOuterFocus}
onClick={this.rootRefClick}
class={classnames(rootCls)} class={classnames(rootCls)}
> >
<div <div
@ -1289,8 +1371,9 @@ export default {
role='combobox' role='combobox'
aria-autocomplete='list' aria-autocomplete='list'
aria-haspopup='true' aria-haspopup='true'
aria-expanded={sOpen} aria-expanded={openStatus}
{...extraSelectionProps} {...extraSelectionProps}
// onClick={this.stopPropagation}
> >
{ctrlNode} {ctrlNode}
{this.renderClear()} {this.renderClear()}

@ -49,6 +49,7 @@ export default {
value: PropTypes.array, value: PropTypes.array,
// children: PropTypes.any, // children: PropTypes.any,
showAction: PropTypes.arrayOf(PropTypes.string), showAction: PropTypes.arrayOf(PropTypes.string),
combobox: PropTypes.bool,
}, },
data () { data () {
return { return {
@ -176,7 +177,6 @@ export default {
builtinPlacements: BUILT_IN_PLACEMENTS, builtinPlacements: BUILT_IN_PLACEMENTS,
prefixCls: dropdownPrefixCls, prefixCls: dropdownPrefixCls,
popupTransitionName: this.getDropdownTransitionName(), popupTransitionName: this.getDropdownTransitionName(),
popup: popupElement,
popupAlign: dropdownAlign, popupAlign: dropdownAlign,
popupVisible: visible, popupVisible: visible,
getPopupContainer, getPopupContainer,
@ -191,6 +191,9 @@ export default {
return ( return (
<Trigger {...triggerProps}> <Trigger {...triggerProps}>
{$slots.default} {$slots.default}
<template slot='popup'>
{popupElement}
</template>
</Trigger> </Trigger>
) )
}, },

Loading…
Cancel
Save