Merge remote-tracking branch 'origin/master' into feat-vue3

# Conflicts:
#	antdv-demo
#	components/_util/store/connect.jsx
#	components/locale-provider/__tests__/__snapshots__/index.test.js.snap
#	package.json
pull/2502/head
tangjinzhou 2020-06-28 23:11:31 +08:00
parent 19e4e27814
commit 0c851369e0
7 changed files with 142 additions and 220 deletions

View File

@ -127,7 +127,7 @@ const getOptionProps = instance => {
} }
return res; return res;
}; };
const getComponent = (instance, prop, options = instance, execute = true) => { const getComponent = (instance, prop = 'default', options = instance, execute = true) => {
if (instance.$) { if (instance.$) {
const temp = instance[prop]; const temp = instance[prop];
if (temp !== undefined) { if (temp !== undefined) {
@ -231,9 +231,6 @@ const getAttrs = ele => {
const getKey = ele => { const getKey = ele => {
let key = ele.key; let key = ele.key;
if (ele.$vnode) {
key = ele.$vnode.key;
}
return key; return key;
}; };

View File

@ -1,6 +1,6 @@
import { reactive, provide } from 'vue'; import { reactive, provide } from 'vue';
import PropTypes from '../_util/vue-types'; import PropTypes from '../_util/vue-types';
import { getComponentFromProp } from '../_util/props-util'; import { getComponent } from '../_util/props-util';
import defaultRenderEmpty from './renderEmpty'; import defaultRenderEmpty from './renderEmpty';
import LocaleProvider, { ANT_MARK } from '../locale-provider'; import LocaleProvider, { ANT_MARK } from '../locale-provider';
import LocaleReceiver from '../locale-provider/LocaleReceiver'; import LocaleReceiver from '../locale-provider/LocaleReceiver';
@ -51,10 +51,9 @@ const ConfigProvider = {
]), ]),
}, },
methods: { methods: {
renderEmptyComponent(h, name) { renderEmptyComponent(name) {
const renderEmpty = const renderEmpty = getComponent(this, 'renderEmpty', {}, false) || defaultRenderEmpty;
getComponentFromProp(this, 'renderEmpty', {}, false) || defaultRenderEmpty; return renderEmpty(name);
return renderEmpty(h, name);
}, },
getPrefixCls(suffixCls, customizePrefixCls) { getPrefixCls(suffixCls, customizePrefixCls) {
const { prefixCls = 'ant' } = this.$props; const { prefixCls = 'ant' } = this.$props;

View File

@ -1,14 +1,15 @@
import { provide, inject } from 'vue';
import warning from '../_util/warning'; import warning from '../_util/warning';
import omit from 'omit.js'; import omit from 'omit.js';
import PropTypes from '../_util/vue-types'; import PropTypes from '../_util/vue-types';
import { Select as VcSelect, Option, OptGroup } from '../vc-select'; import { Select as VcSelect, Option, OptGroup } from '../vc-select';
import { ConfigConsumerProps } from '../config-provider'; import { ConfigConsumerProps } from '../config-provider';
import { import {
getComponentFromProp, getComponent,
getOptionProps, getOptionProps,
filterEmpty, filterEmpty,
isValidElement, isValidElement,
getListeners, getSlot,
} from '../_util/props-util'; } from '../_util/props-util';
import CloseOutlined from '@ant-design/icons-vue/CloseOutlined'; import CloseOutlined from '@ant-design/icons-vue/CloseOutlined';
import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled'; import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled';
@ -16,7 +17,6 @@ import CheckOutlined from '@ant-design/icons-vue/CheckOutlined';
import DownOutlined from '@ant-design/icons-vue/DownOutlined'; import DownOutlined from '@ant-design/icons-vue/DownOutlined';
import LoadingOutlined from '@ant-design/icons-vue/LoadingOutlined'; import LoadingOutlined from '@ant-design/icons-vue/LoadingOutlined';
import { cloneElement } from '../_util/vnode'; import { cloneElement } from '../_util/vnode';
import Base from '../base';
const AbstractSelectProps = () => ({ const AbstractSelectProps = () => ({
prefixCls: PropTypes.string, prefixCls: PropTypes.string,
@ -107,19 +107,17 @@ const Select = {
choiceTransitionName: PropTypes.string.def('zoom'), choiceTransitionName: PropTypes.string.def('zoom'),
}, },
propTypes: SelectPropTypes, propTypes: SelectPropTypes,
model: { // model: {
prop: 'value', // prop: 'value',
event: 'change', // event: 'change',
}, // },
provide() { setup() {
return { return {
savePopupRef: this.savePopupRef, configProvider: inject('configProvider', ConfigConsumerProps),
}; };
}, },
inject: {
configProvider: { default: () => ConfigConsumerProps },
},
created() { created() {
provide('savePopupRef', this.savePopupRef);
warning( warning(
this.$props.mode !== 'combobox', this.$props.mode !== 'combobox',
'Select', 'Select',
@ -130,15 +128,14 @@ const Select = {
}, },
methods: { methods: {
getNotFoundContent(renderEmpty) { getNotFoundContent(renderEmpty) {
const h = this.$createElement; const notFoundContent = getComponent(this, 'notFoundContent');
const notFoundContent = getComponentFromProp(this, 'notFoundContent');
if (notFoundContent !== undefined) { if (notFoundContent !== undefined) {
return notFoundContent; return notFoundContent;
} }
if (this.isCombobox()) { if (this.isCombobox()) {
return null; return null;
} }
return renderEmpty(h, 'Select'); return renderEmpty('Select');
}, },
savePopupRef(ref) { savePopupRef(ref) {
this.popupRef = ref; this.popupRef = ref;
@ -157,7 +154,7 @@ const Select = {
renderSuffixIcon(prefixCls) { renderSuffixIcon(prefixCls) {
const { loading } = this.$props; const { loading } = this.$props;
let suffixIcon = getComponentFromProp(this, 'suffixIcon'); let suffixIcon = getComponent(this, 'suffixIcon');
suffixIcon = Array.isArray(suffixIcon) ? suffixIcon[0] : suffixIcon; suffixIcon = Array.isArray(suffixIcon) ? suffixIcon[0] : suffixIcon;
if (suffixIcon) { if (suffixIcon) {
return isValidElement(suffixIcon) return isValidElement(suffixIcon)
@ -180,17 +177,18 @@ const Select = {
showArrow, showArrow,
...restProps ...restProps
} = getOptionProps(this); } = getOptionProps(this);
const { class: className } = this.$attrs;
const getPrefixCls = this.configProvider.getPrefixCls; const getPrefixCls = this.configProvider.getPrefixCls;
const renderEmpty = this.configProvider.renderEmpty; const renderEmpty = this.configProvider.renderEmpty;
const prefixCls = getPrefixCls('select', customizePrefixCls); const prefixCls = getPrefixCls('select', customizePrefixCls);
const { getPopupContainer: getContextPopupContainer } = this.configProvider; const { getPopupContainer: getContextPopupContainer } = this.configProvider;
let removeIcon = getComponentFromProp(this, 'removeIcon'); let removeIcon = getComponent(this, 'removeIcon');
removeIcon = Array.isArray(removeIcon) ? removeIcon[0] : removeIcon; removeIcon = Array.isArray(removeIcon) ? removeIcon[0] : removeIcon;
let clearIcon = getComponentFromProp(this, 'clearIcon'); let clearIcon = getComponent(this, 'clearIcon');
clearIcon = Array.isArray(clearIcon) ? clearIcon[0] : clearIcon; clearIcon = Array.isArray(clearIcon) ? clearIcon[0] : clearIcon;
let menuItemSelectedIcon = getComponentFromProp(this, 'menuItemSelectedIcon'); let menuItemSelectedIcon = getComponent(this, 'menuItemSelectedIcon');
menuItemSelectedIcon = Array.isArray(menuItemSelectedIcon) menuItemSelectedIcon = Array.isArray(menuItemSelectedIcon)
? menuItemSelectedIcon[0] ? menuItemSelectedIcon[0]
: menuItemSelectedIcon; : menuItemSelectedIcon;
@ -203,6 +201,7 @@ const Select = {
]); ]);
const cls = { const cls = {
[className]: className,
[`${prefixCls}-lg`]: size === 'large', [`${prefixCls}-lg`]: size === 'large',
[`${prefixCls}-sm`]: size === 'small', [`${prefixCls}-sm`]: size === 'small',
[`${prefixCls}-show-arrow`]: showArrow, [`${prefixCls}-show-arrow`]: showArrow,
@ -235,34 +234,32 @@ const Select = {
: menuItemSelectedIcon)) || <CheckOutlined class={`${prefixCls}-selected-icon`} />; : menuItemSelectedIcon)) || <CheckOutlined class={`${prefixCls}-selected-icon`} />;
const selectProps = { const selectProps = {
props: { inputIcon: this.renderSuffixIcon(prefixCls),
inputIcon: this.renderSuffixIcon(prefixCls), removeIcon: finalRemoveIcon,
removeIcon: finalRemoveIcon, clearIcon: finalClearIcon,
clearIcon: finalClearIcon, menuItemSelectedIcon: finalMenuItemSelectedIcon,
menuItemSelectedIcon: finalMenuItemSelectedIcon, showArrow,
showArrow, ...rest,
...rest, ...modeConfig,
...modeConfig, prefixCls,
prefixCls, optionLabelProp: optionLabelProp || 'children',
optionLabelProp: optionLabelProp || 'children', notFoundContent: this.getNotFoundContent(renderEmpty),
notFoundContent: this.getNotFoundContent(renderEmpty), maxTagPlaceholder: getComponent(this, 'maxTagPlaceholder'),
maxTagPlaceholder: getComponentFromProp(this, 'maxTagPlaceholder'), placeholder: getComponent(this, 'placeholder'),
placeholder: getComponentFromProp(this, 'placeholder'), children: options
children: options ? options.map(option => {
? options.map(option => { const { key, label = option.title, on, class: cls, style, ...restOption } = option;
const { key, label = option.title, on, class: cls, style, ...restOption } = option; return (
return ( <Option key={key} {...{ on, class: cls, style, ...restOption }}>
<Option key={key} {...{ props: restOption, on, class: cls, style }}> {label}
{label} </Option>
</Option> );
); })
}) : filterEmpty(getSlot(this)),
: filterEmpty(this.$slots.default), __propsSymbol__: Symbol(),
__propsSymbol__: Symbol(), dropdownRender: getComponent(this, 'dropdownRender', {}, false),
dropdownRender: getComponentFromProp(this, 'dropdownRender', {}, false), getPopupContainer: getPopupContainer || getContextPopupContainer,
getPopupContainer: getPopupContainer || getContextPopupContainer, ...this.$attrs,
},
on: getListeners(this),
class: cls, class: cls,
ref: 'vcSelect', ref: 'vcSelect',
}; };
@ -271,11 +268,9 @@ const Select = {
}; };
/* istanbul ignore next */ /* istanbul ignore next */
Select.install = function(Vue) { Select.install = function(app) {
Vue.use(Base); app.component(Select.name, Select);
Vue.component(Select.name, Select); app.component(Select.Option.name, Select.Option);
Vue.component(Select.Option.name, Select.Option); app.component(Select.OptGroup.name, Select.OptGroup);
Vue.component(Select.OptGroup.name, Select.OptGroup);
}; };
export default Select; export default Select;

View File

@ -56,4 +56,6 @@ export const SelectPropTypes = {
dropdownMenuStyle: PropTypes.object, dropdownMenuStyle: PropTypes.object,
notFoundContent: PropTypes.oneOfType([String, Number]), notFoundContent: PropTypes.oneOfType([String, Number]),
tabIndex: PropTypes.oneOfType([String, Number]), tabIndex: PropTypes.oneOfType([String, Number]),
__propsSymbol__: PropTypes.any,
children: PropTypes.array,
}; };

View File

@ -4,7 +4,6 @@ import classnames from 'classnames';
import classes from 'component-classes'; import classes from 'component-classes';
import { Item as MenuItem, ItemGroup as MenuItemGroup } from '../vc-menu'; import { Item as MenuItem, ItemGroup as MenuItemGroup } from '../vc-menu';
import warning from 'warning'; import warning from 'warning';
import Vue from 'vue';
import Option from './Option'; import Option from './Option';
import OptGroup from './OptGroup'; import OptGroup from './OptGroup';
import { import {
@ -12,20 +11,15 @@ import {
getSlotOptions, getSlotOptions,
getPropsData, getPropsData,
getValueByProp as getValue, getValueByProp as getValue,
getComponentFromProp, getComponent,
getEvents, getEvents,
getClass, getClass,
getStyle,
getAttrs, getAttrs,
getOptionProps, getOptionProps,
getSlots,
getListeners,
} from '../_util/props-util'; } 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 ref from 'vue-ref';
import SelectTrigger from './SelectTrigger'; import SelectTrigger from './SelectTrigger';
import { import {
defaultFilterFn, defaultFilterFn,
@ -54,7 +48,6 @@ import { SelectPropTypes } from './PropTypes';
import contains from '../vc-util/Dom/contains'; import contains from '../vc-util/Dom/contains';
import { isIE, isEdge } from '../_util/env'; import { isIE, isEdge } from '../_util/env';
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';
const noop = () => null; const noop = () => null;
@ -670,11 +663,9 @@ const Select = {
const placeholder = props.placeholder; const placeholder = props.placeholder;
if (placeholder) { if (placeholder) {
const p = { const p = {
on: { onMousedown: preventDefaultEvent,
mousedown: preventDefaultEvent, onClick: this.onPlaceholderClick,
click: this.onPlaceholderClick, ...UNSELECTABLE_ATTRIBUTE,
},
attrs: UNSELECTABLE_ATTRIBUTE,
style: { style: {
display: hidden ? 'none' : 'block', display: hidden ? 'none' : 'block',
...UNSELECTABLE_STYLE, ...UNSELECTABLE_STYLE,
@ -810,51 +801,28 @@ const Select = {
return ( return (
<div class={`${props.prefixCls}-search__field__wrap`} onClick={this.inputClick}> <div class={`${props.prefixCls}-search__field__wrap`} onClick={this.inputClick}>
{cloneElement(inputElement, { {cloneElement(inputElement, {
props: { disabled: props.disabled,
disabled: props.disabled, value: inputValue,
value: inputValue, ...(inputElement.data.attrs || {}),
}, disabled: props.disabled,
attrs: { value: inputValue,
...(inputElement.data.attrs || {}),
disabled: props.disabled,
value: inputValue,
},
domProps: {
value: inputValue,
},
class: inputCls, class: inputCls,
ref: this.saveInputRef,
directives: [ directives: [
{
name: 'ant-ref',
value: this.saveInputRef,
},
{ {
name: 'ant-input', name: 'ant-input',
}, },
], ],
on: { onInput: this.onInputChange,
input: this.onInputChange, onKeydown: chaining(
keydown: chaining( this.onInputKeydown,
this.onInputKeydown, inputEvents.onKeydown,
inputEvents.keydown, this.$attrs.onInputKeydown,
getListeners(this).inputKeydown, ),
), onFocus: chaining(this.inputFocus, inputEvents.onFocus),
focus: chaining(this.inputFocus, inputEvents.focus), onBlur: chaining(this.inputBlur, inputEvents.onBlur),
blur: chaining(this.inputBlur, inputEvents.blur),
},
})} })}
<span <span ref={this.saveInputMirrorRef} class={`${props.prefixCls}-search__field__mirror`}>
{...{
directives: [
{
name: 'ant-ref',
value: this.saveInputMirrorRef,
},
],
}}
// ref='inputMirrorRef'
class={`${props.prefixCls}-search__field__mirror`}
>
{_mirrorInputValue}&nbsp; {_mirrorInputValue}&nbsp;
</span> </span>
</div> </div>
@ -1177,7 +1145,7 @@ const Select = {
role: 'option', role: 'option',
}; };
const menuItem = ( const menuItem = (
<MenuItem style={UNSELECTABLE_STYLE} {...{ attrs }} value={key} key={key}> <MenuItem style={UNSELECTABLE_STYLE} {...attrs} value={key} key={key}>
{key} {key}
</MenuItem> </MenuItem>
); );
@ -1187,12 +1155,10 @@ const Select = {
// ref: https://github.com/ant-design/ant-design/issues/14090 // ref: https://github.com/ant-design/ant-design/issues/14090
if (inputValue && menuItems.every(option => getValuePropValue(option) !== inputValue)) { if (inputValue && menuItems.every(option => getValuePropValue(option) !== inputValue)) {
const p = { const p = {
attrs: UNSELECTABLE_ATTRIBUTE, ...UNSELECTABLE_ATTRIBUTE,
key: inputValue, key: inputValue,
props: { value: inputValue,
value: inputValue, role: 'option',
role: 'option',
},
style: UNSELECTABLE_STYLE, style: UNSELECTABLE_STYLE,
}; };
options.unshift(<MenuItem {...p}>{inputValue}</MenuItem>); options.unshift(<MenuItem {...p}>{inputValue}</MenuItem>);
@ -1202,13 +1168,11 @@ const Select = {
if (!options.length && notFoundContent) { if (!options.length && notFoundContent) {
empty = true; empty = true;
const p = { const p = {
attrs: UNSELECTABLE_ATTRIBUTE, ...UNSELECTABLE_ATTRIBUTE,
key: 'NOT_FOUND', key: 'NOT_FOUND',
props: { value: 'NOT_FOUND',
value: 'NOT_FOUND', disabled: true,
disabled: true, role: 'option',
role: 'option',
},
style: UNSELECTABLE_STYLE, style: UNSELECTABLE_STYLE,
}; };
options = [<MenuItem {...p}>{notFoundContent}</MenuItem>]; options = [<MenuItem {...p}>{notFoundContent}</MenuItem>];
@ -1222,32 +1186,38 @@ const Select = {
const { _inputValue: inputValue } = this.$data; const { _inputValue: inputValue } = this.$data;
const tags = props.tags; const tags = props.tags;
children.forEach(child => { children.forEach(child => {
if (!child.data || child.data.slot !== undefined) { const type = child.type;
warning(
typeof type === 'object' && type.isSelectOption,
'the children of `Select` should be `Select.Option` or `Select.OptGroup`, ' +
`instead of \`${getSlotOptions(child).name || getSlotOptions(child)}\`.`,
);
if (typeof type !== 'object' || !type.isSelectOption) {
return; return;
} }
if (getSlotOptions(child).isSelectOptGroup) { if (type.isSelectOptGroup) {
let label = getComponentFromProp(child, 'label'); let label = getComponent(child, 'label');
let key = child.key; let key = child.key;
if (!key && typeof label === 'string') { if (!key && typeof label === 'string') {
key = label; key = label;
} else if (!label && key) { } else if (!label && key) {
label = key; label = key;
} }
let childChildren = getSlots(child).default; let childChildren = getComponent(child);
childChildren = typeof childChildren === 'function' ? childChildren() : childChildren; childChildren = Array.isArray(childChildren) ? childChildren : [childChildren];
// Match option group label // Match option group label
if (inputValue && this._filterOption(inputValue, child)) { if (inputValue && this._filterOption(inputValue, child)) {
const innerItems = childChildren.map(subChild => { const innerItems = childChildren.map(subChild => {
const childValueSub = getValuePropValue(subChild) || subChild.key; const childValueSub = getValuePropValue(subChild) || subChild.key;
return ( return (
<MenuItem key={childValueSub} value={childValueSub} {...subChild.data}> <MenuItem key={childValueSub} value={childValueSub} {...subChild.props}>
{subChild.componentOptions.children} {subChild.children?.default()}
</MenuItem> </MenuItem>
); );
}); });
sel.push( sel.push(
<MenuItemGroup key={key} title={label} class={getClass(child)}> <MenuItemGroup key={key} title={label} class={child.props?.class}>
{innerItems} {innerItems}
</MenuItemGroup>, </MenuItemGroup>,
); );
@ -1261,7 +1231,7 @@ const Select = {
); );
if (innerItems.length) { if (innerItems.length) {
sel.push( sel.push(
<MenuItemGroup key={key} title={label} {...child.data}> <MenuItemGroup key={key} title={label} {...child.props}>
{innerItems} {innerItems}
</MenuItemGroup>, </MenuItemGroup>,
); );
@ -1270,32 +1240,21 @@ const Select = {
return; return;
} }
warning(
getSlotOptions(child).isSelectOption,
'the children of `Select` should be `Select.Option` or `Select.OptGroup`, ' +
`instead of \`${getSlotOptions(child).name || getSlotOptions(child)}\`.`,
);
const childValue = getValuePropValue(child); const childValue = getValuePropValue(child);
validateOptionValue(childValue, this.$props); validateOptionValue(childValue, this.$props);
if (this._filterOption(inputValue, child)) { if (this._filterOption(inputValue, child)) {
const p = { const p = {
attrs: { ...UNSELECTABLE_ATTRIBUTE,
...UNSELECTABLE_ATTRIBUTE,
...getAttrs(child),
},
key: childValue, key: childValue,
props: { value: childValue,
value: childValue, ...getPropsData(child),
...getPropsData(child), role: 'option',
role: 'option',
},
style: UNSELECTABLE_STYLE, style: UNSELECTABLE_STYLE,
on: getEvents(child), class: child?.class,
class: getClass(child),
}; };
const menuItem = <MenuItem {...p}>{child.componentOptions.children}</MenuItem>; const menuItem = <MenuItem {...p}>{child.children?.default()}</MenuItem>;
sel.push(menuItem); sel.push(menuItem);
menuItems.push(menuItem); menuItems.push(menuItem);
} }
@ -1318,7 +1277,7 @@ const Select = {
maxTagPlaceholder, maxTagPlaceholder,
showSearch, showSearch,
} = props; } = props;
const removeIcon = getComponentFromProp(this, 'removeIcon'); const removeIcon = getComponent(this, 'removeIcon');
const className = `${prefixCls}-selection__rendered`; const className = `${prefixCls}-selection__rendered`;
// search input is inside topControlNode in single, multiple & combobox. 2016/04/13 // search input is inside topControlNode in single, multiple & combobox. 2016/04/13
let innerNode = null; let innerNode = null;
@ -1391,7 +1350,7 @@ const Select = {
maxTagPlaceholderEl = ( maxTagPlaceholderEl = (
<li <li
style={UNSELECTABLE_STYLE} style={UNSELECTABLE_STYLE}
{...{ attrs }} {...attrs}
onMousedown={preventDefaultEvent} onMousedown={preventDefaultEvent}
class={`${prefixCls}-selection__choice ${prefixCls}-selection__choice__disabled`} class={`${prefixCls}-selection__choice ${prefixCls}-selection__choice__disabled`}
key="maxTagPlaceholder" key="maxTagPlaceholder"
@ -1425,7 +1384,7 @@ const Select = {
return ( return (
<li <li
style={UNSELECTABLE_STYLE} style={UNSELECTABLE_STYLE}
{...{ attrs }} {...attrs}
onMousedown={preventDefaultEvent} onMousedown={preventDefaultEvent}
class={choiceClassName} class={choiceClassName}
key={singleValue || SELECT_EMPTY_VALUE_KEY} key={singleValue || SELECT_EMPTY_VALUE_KEY}
@ -1467,18 +1426,7 @@ const Select = {
} }
} }
return ( return (
<div <div class={className} ref={this.saveTopCtrlRef} onClick={this.topCtrlContainerClick}>
class={className}
{...{
directives: [
{
name: 'ant-ref',
value: this.saveTopCtrlRef,
},
],
}}
onClick={this.topCtrlContainerClick}
>
{this.getPlaceholderElement()} {this.getPlaceholderElement()}
{innerNode} {innerNode}
</div> </div>
@ -1487,7 +1435,7 @@ const Select = {
renderArrow(multiple) { renderArrow(multiple) {
// showArrow : Set to true if not multiple by default but keep set value. // showArrow : Set to true if not multiple by default but keep set value.
const { showArrow = !multiple, loading, prefixCls } = this.$props; const { showArrow = !multiple, loading, prefixCls } = this.$props;
const inputIcon = getComponentFromProp(this, 'inputIcon'); const inputIcon = getComponent(this, 'inputIcon');
if (!showArrow && !loading) { if (!showArrow && !loading) {
return null; return null;
} }
@ -1502,7 +1450,7 @@ const Select = {
key="arrow" key="arrow"
class={`${prefixCls}-arrow`} class={`${prefixCls}-arrow`}
style={UNSELECTABLE_STYLE} style={UNSELECTABLE_STYLE}
{...{ attrs: UNSELECTABLE_ATTRIBUTE }} {...UNSELECTABLE_ATTRIBUTE}
onClick={this.onArrowClick} onClick={this.onArrowClick}
ref="arrow" ref="arrow"
> >
@ -1518,14 +1466,14 @@ const Select = {
renderClear() { renderClear() {
const { prefixCls, allowClear } = this.$props; const { prefixCls, allowClear } = this.$props;
const { _value: value, _inputValue: inputValue } = this.$data; const { _value: value, _inputValue: inputValue } = this.$data;
const clearIcon = getComponentFromProp(this, 'clearIcon'); const clearIcon = getComponent(this, 'clearIcon');
const clear = ( const clear = (
<span <span
key="clear" key="clear"
class={`${prefixCls}-selection__clear`} class={`${prefixCls}-selection__clear`}
onMousedown={preventDefaultEvent} onMousedown={preventDefaultEvent}
style={UNSELECTABLE_STYLE} style={UNSELECTABLE_STYLE}
{...{ attrs: UNSELECTABLE_ATTRIBUTE }} {...UNSELECTABLE_ATTRIBUTE}
onClick={this.onClearSelection} onClick={this.onClearSelection}
> >
{clearIcon || <i class={`${prefixCls}-selection__clear-icon`}>×</i>} {clearIcon || <i class={`${prefixCls}-selection__clear-icon`}>×</i>}
@ -1582,12 +1530,12 @@ const Select = {
render() { render() {
const props = this.$props; const props = this.$props;
const { class: className, style } = this.$attrs;
const multiple = isMultipleOrTags(props); const multiple = isMultipleOrTags(props);
// Default set showArrow to true if not set (not set directly in defaultProps to handle multiple case) // Default set showArrow to true if not set (not set directly in defaultProps to handle multiple case)
const { showArrow = true } = props; const { showArrow = true } = props;
const state = this.$data; const state = this.$data;
const { disabled, prefixCls, loading } = props; const { disabled, prefixCls, loading } = props;
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) {
const filterOptions = this.renderFilterOptions(); const filterOptions = this.renderFilterOptions();
@ -1597,26 +1545,13 @@ const Select = {
const realOpen = this.getRealOpenState(); const realOpen = this.getRealOpenState();
const empty = this._empty; const empty = this._empty;
const options = this._options || []; const options = this._options || [];
const { mouseenter = noop, mouseleave = noop, popupScroll = noop } = getListeners(this);
const selectionProps = { const selectionProps = {
props: {}, role: 'combobox',
attrs: { 'aria-autocomplete': 'list',
role: 'combobox', 'aria-haspopup': 'true',
'aria-autocomplete': 'list', 'aria-expanded': realOpen,
'aria-haspopup': 'true', 'aria-controls': this.$data._ariaId,
'aria-expanded': realOpen,
'aria-controls': this.$data._ariaId,
},
on: {
// click: this.selectionRefClick,
},
class: `${prefixCls}-selection ${prefixCls}-selection--${multiple ? 'multiple' : 'single'}`, class: `${prefixCls}-selection ${prefixCls}-selection--${multiple ? 'multiple' : 'single'}`,
// directives: [
// {
// name: 'ant-ref',
// value: this.saveSelectionRef,
// },
// ],
key: 'selection', key: 'selection',
}; };
//if (!isMultipleOrTagsOrCombobox(props)) { //if (!isMultipleOrTagsOrCombobox(props)) {
@ -1626,6 +1561,7 @@ const Select = {
// selectionProps.attrs.tabIndex = props.disabled ? -1 : props.tabIndex; // selectionProps.attrs.tabIndex = props.disabled ? -1 : props.tabIndex;
//} //}
const rootCls = { const rootCls = {
[className]: className,
[prefixCls]: true, [prefixCls]: true,
[`${prefixCls}-open`]: open, [`${prefixCls}-open`]: open,
[`${prefixCls}-focused`]: open || !!this._focused, [`${prefixCls}-focused`]: open || !!this._focused,
@ -1662,26 +1598,19 @@ const Select = {
getPopupContainer={props.getPopupContainer} getPopupContainer={props.getPopupContainer}
onMenuSelect={this.onMenuSelect} onMenuSelect={this.onMenuSelect}
onMenuDeselect={this.onMenuDeselect} onMenuDeselect={this.onMenuDeselect}
onPopupScroll={popupScroll} onPopupScroll={this.$attrs.onPopupScroll}
onPopupFocus={this.onPopupFocus} onPopupFocus={this.onPopupFocus}
onMouseenter={mouseenter} onMouseenter={this.$attrs.onMouseenter}
onMouseleave={mouseleave} onMouseleave={this.$attrs.onMouseleave}
showAction={props.showAction} showAction={props.showAction}
menuItemSelectedIcon={getComponentFromProp(this, 'menuItemSelectedIcon')} menuItemSelectedIcon={getComponent(this, 'menuItemSelectedIcon')}
ref={this.saveSelectTriggerRef} ref={this.saveSelectTriggerRef}
dropdownRender={props.dropdownRender} dropdownRender={props.dropdownRender}
ariaId={this.$data._ariaId} ariaId={this.$data._ariaId}
> >
<div <div
{...{ ref={chaining(this.saveRootRef, this.saveSelectionRef)}
directives: [ style={style}
{
name: 'ant-ref',
value: chaining(this.saveRootRef, this.saveSelectionRef),
},
],
}}
style={getStyle(this)}
class={classnames(rootCls)} class={classnames(rootCls)}
onMousedown={this.markMouseDown} onMousedown={this.markMouseDown}
onMouseup={this.markMouseLeave} onMouseup={this.markMouseLeave}
@ -1693,7 +1622,7 @@ const Select = {
onKeydown={isMultipleOrTagsOrCombobox(props) ? noop : this.onKeyDown} onKeydown={isMultipleOrTagsOrCombobox(props) ? noop : this.onKeyDown}
> >
<div {...selectionProps}> <div {...selectionProps}>
{ctrlNode} {this.renderTopControlNode()}
{this.renderClear()} {this.renderClear()}
{this.renderArrow(!!multiple)} {this.renderArrow(!!multiple)}
</div> </div>
@ -1703,4 +1632,4 @@ const Select = {
}, },
}; };
export { Select }; export { Select };
export default proxyComponent(Select); export default Select;

View File

@ -1,11 +1,5 @@
import { import { getPropsData, getSlotOptions, getKey, getComponent } from '../_util/props-util';
getPropsData, import { cloneElement } from '../_util/vnode';
getSlotOptions,
getKey,
getAttrs,
getComponentFromProp,
} from '../_util/props-util';
import { cloneVNodes } from '../_util/vnode';
export function toTitle(title) { export function toTitle(title) {
if (typeof title === 'string') { if (typeof title === 'string') {
@ -24,8 +18,8 @@ export function getValuePropValue(child) {
if (getKey(child) !== undefined) { if (getKey(child) !== undefined) {
return getKey(child); return getKey(child);
} }
if (getSlotOptions(child).isSelectOptGroup) { if (typeof child.type === 'object' && child.type.isSelectOptGroup) {
const label = getComponentFromProp(child, 'label'); const label = getComponent(child, 'label');
if (label) { if (label) {
return label; return label;
} }
@ -39,8 +33,8 @@ export function getPropValue(child, prop) {
} }
if (prop === 'children') { if (prop === 'children') {
const newChild = child.$slots const newChild = child.$slots
? cloneVNodes(child.$slots.default, true) ? cloneElement(child.$slots.default)
: cloneVNodes(child.componentOptions.children, true); : cloneElement(child.componentOptions.children);
if (newChild.length === 1 && !newChild[0].tag) { if (newChild.length === 1 && !newChild[0].tag) {
return newChild[0].text; return newChild[0].text;
} }
@ -50,7 +44,7 @@ export function getPropValue(child, prop) {
if (prop in data) { if (prop in data) {
return data[prop]; return data[prop];
} else { } else {
return getAttrs(child)[prop]; return child.props && child.props[prop];
} }
} }

View File

@ -2,7 +2,14 @@ import { inject, provide } from 'vue';
import antRef from '../_util/ant-ref'; import antRef from '../_util/ant-ref';
import PropTypes from '../_util/vue-types'; import PropTypes from '../_util/vue-types';
import contains from '../vc-util/Dom/contains'; import contains from '../vc-util/Dom/contains';
import { hasProp, getComponent, getEvents, filterEmpty, getSlot } from '../_util/props-util'; import {
hasProp,
getComponent,
getEvents,
filterEmpty,
getSlot,
findDOMNode,
} from '../_util/props-util';
import { requestAnimationTimeout, cancelAnimationTimeout } from '../_util/requestAnimationTimeout'; import { requestAnimationTimeout, cancelAnimationTimeout } from '../_util/requestAnimationTimeout';
import addEventListener from '../vc-util/Dom/addEventListener'; import addEventListener from '../vc-util/Dom/addEventListener';
import warning from '../_util/warning'; import warning from '../_util/warning';
@ -324,7 +331,7 @@ export default {
}, },
getRootDomNode() { getRootDomNode() {
return this.$refs.trigger.$el || this.$refs.trigger; return findDOMNode(this);
}, },
handleGetPopupClassFromAlign(align) { handleGetPopupClassFromAlign(align) {
@ -583,7 +590,6 @@ export default {
this.childOriginEvents = getEvents(child); this.childOriginEvents = getEvents(child);
const newChildProps = { const newChildProps = {
key: 'trigger', key: 'trigger',
ref: 'trigger',
}; };
if (this.isContextmenuToShow()) { if (this.isContextmenuToShow()) {