fix: tree-select search value logic

pull/3053/head
tanjinzhou 2020-10-21 18:33:15 +08:00
parent f82fcad094
commit 02c3af5c7c
5 changed files with 68 additions and 51 deletions

View File

@ -32,6 +32,7 @@ export const selectorPropTypes = () => ({
focused: PropTypes.looseBool, focused: PropTypes.looseBool,
isMultiple: PropTypes.looseBool, isMultiple: PropTypes.looseBool,
showSearch: PropTypes.looseBool, showSearch: PropTypes.looseBool,
searchValue: PropTypes.string,
}); });
function noop() {} function noop() {}

View File

@ -20,19 +20,23 @@ const SearchInput = {
renderPlaceholder: PropTypes.func, renderPlaceholder: PropTypes.func,
needAlign: PropTypes.looseBool, needAlign: PropTypes.looseBool,
ariaId: PropTypes.string, ariaId: PropTypes.string,
isMultiple: PropTypes.looseBool.def(true),
}, },
setup(props) { setup(props) {
const measureRef = ref(); const measureRef = ref();
const inputWidth = ref(0); const inputWidth = ref(0);
// We measure width and set to the input immediately // We measure width and set to the input immediately
onMounted(() => { onMounted(() => {
watch( if(props.isMultiple) {
computed(()=>props.searchValue), watch(
() => { computed(()=>props.searchValue),
inputWidth.value = measureRef.value.scrollWidth; () => {
}, inputWidth.value = measureRef.value.scrollWidth;
{ flush: 'post' }, },
); { flush: 'post', immediate: true },
);
}
}); });
return { return {
measureRef, measureRef,
@ -52,15 +56,11 @@ const SearchInput = {
}, },
created() { created() {
this.inputRef = createRef(); this.inputRef = createRef();
// this.mirrorInputRef = createRef();
this.prevProps = { ...this.$props }; this.prevProps = { ...this.$props };
}, },
mounted() { mounted() {
this.$nextTick(() => { this.$nextTick(() => {
const { open, needAlign } = this.$props; const { open } = this.$props;
if (needAlign) {
this.alignInputWidth();
}
if (open) { if (open) {
this.focus(true); this.focus(true);
@ -75,22 +75,11 @@ const SearchInput = {
if (open && prevProps.open !== open) { if (open && prevProps.open !== open) {
this.focus(); this.focus();
} }
// if (needAlign && searchValue !== prevProps.searchValue) {
// this.alignInputWidth();
// }
this.prevProps = { ...this.$props }; this.prevProps = { ...this.$props };
}); });
}, },
methods: { methods: {
/**
* `scrollWidth` is not correct in IE, do the workaround.
* ref: https://github.com/react-component/tree-select/issues/65
* clientWidth 0 when mounted in vue. why?
*/
// alignInputWidth() {
// this.inputRef.current.style.width = `${this.mirrorInputRef.current.clientWidth ||
// this.mirrorInputRef.current.offsetWidth}px`;
// },
/** /**
* Need additional timeout for focus cause parent dom is not ready when didMount trigger * Need additional timeout for focus cause parent dom is not ready when didMount trigger
@ -125,7 +114,7 @@ const SearchInput = {
}, },
render() { render() {
const { searchValue, prefixCls, disabled, renderPlaceholder, open, ariaId } = this.$props; const { searchValue, prefixCls, disabled, renderPlaceholder, open, ariaId, isMultiple } = this.$props;
const { const {
vcTreeSelect: { onSearchInputKeyDown }, vcTreeSelect: { onSearchInputKeyDown },
handleInputChange, handleInputChange,
@ -134,7 +123,7 @@ const SearchInput = {
} = this; } = this;
return ( return (
<> <>
<span class={`${prefixCls}-selection-search`} style={{ width: inputWidth + 'px' }}> <span class={`${prefixCls}-selection-search`} style={isMultiple ? { width: inputWidth + 'px' }:{}}>
{withDirectives( {withDirectives(
<input <input
type="text" type="text"
@ -152,9 +141,9 @@ const SearchInput = {
/>, />,
[[antInput]], [[antInput]],
)} )}
<span ref="measureRef" class={`${prefixCls}-selection-search-mirror`} aria-hidden> {isMultiple ? <span ref="measureRef" class={`${prefixCls}-selection-search-mirror`} aria-hidden>
{mirrorSearchValue}&nbsp; {mirrorSearchValue}&nbsp;
</span> </span> : null}
</span> </span>
{renderPlaceholder && !mirrorSearchValue ? renderPlaceholder() : null} {renderPlaceholder && !mirrorSearchValue ? renderPlaceholder() : null}
</> </>

View File

@ -29,8 +29,6 @@ import KeyCode from '../../_util/KeyCode';
import SelectTrigger from './SelectTrigger'; import SelectTrigger from './SelectTrigger';
import SingleSelector from './Selector/SingleSelector'; import SingleSelector from './Selector/SingleSelector';
import MultipleSelector from './Selector/MultipleSelector'; import MultipleSelector from './Selector/MultipleSelector';
import SinglePopup from './Popup/SinglePopup';
import MultiplePopup from './Popup/MultiplePopup';
import { SHOW_ALL, SHOW_PARENT, SHOW_CHILD } from './strategies'; import { SHOW_ALL, SHOW_PARENT, SHOW_CHILD } from './strategies';
import BaseMixin from '../../_util/BaseMixin'; import BaseMixin from '../../_util/BaseMixin';
@ -58,6 +56,7 @@ import {
getPropsData, getPropsData,
findDOMNode, findDOMNode,
} from '../../_util/props-util'; } from '../../_util/props-util';
import BasePopup from './Popup/MultiplePopup';
function getWatch(keys = []) { function getWatch(keys = []) {
const watch = {}; const watch = {};
keys.forEach(k => { keys.forEach(k => {
@ -1092,8 +1091,7 @@ const Select = defineComponent({
ref: this.setPopupRef, ref: this.setPopupRef,
}; };
const Popup = isMultiple ? MultiplePopup : SinglePopup; const $popup = <BasePopup {...popupProps} __propsSymbol__={[]} />;
const $popup = <Popup {...popupProps} __propsSymbol__={[]} />;
const Selector = isMultiple ? MultipleSelector : SingleSelector; const Selector = isMultiple ? MultipleSelector : SingleSelector;
const $selector = <Selector {...passProps} isMultiple={isMultiple} ref={this.selectorRef} />; const $selector = <Selector {...passProps} isMultiple={isMultiple} ref={this.selectorRef} />;

View File

@ -23,7 +23,6 @@ const MultipleSelector = {
...SearchInput.props, ...SearchInput.props,
selectorValueList: PropTypes.array, selectorValueList: PropTypes.array,
disabled: PropTypes.looseBool, disabled: PropTypes.looseBool,
searchValue: PropTypes.string,
labelInValue: PropTypes.looseBool, labelInValue: PropTypes.looseBool,
maxTagCount: PropTypes.number, maxTagCount: PropTypes.number,
maxTagPlaceholder: PropTypes.any, maxTagPlaceholder: PropTypes.any,
@ -142,11 +141,9 @@ const MultipleSelector = {
selectedValueNodes.push( selectedValueNodes.push(
<SearchInput <SearchInput
{...{ key="SearchInput"
...this.$props, {...this.$props}
...this.$attrs, {...this.$attrs}
needAlign: true,
}}
ref={this.inputRef} ref={this.inputRef}
> >
{children} {children}

View File

@ -2,6 +2,7 @@ import generateSelector, { selectorPropTypes } from '../Base/BaseSelector';
import { toTitle } from '../util'; import { toTitle } from '../util';
import { getOptionProps } from '../../../_util/props-util'; import { getOptionProps } from '../../../_util/props-util';
import { createRef } from '../util'; import { createRef } from '../util';
import SearchInput from '../SearchInput';
const Selector = generateSelector('single'); const Selector = generateSelector('single');
const SingleSelector = { const SingleSelector = {
@ -10,31 +11,61 @@ const SingleSelector = {
props: selectorPropTypes(), props: selectorPropTypes(),
created() { created() {
this.selectorRef = createRef(); this.selectorRef = createRef();
this.inputRef = createRef();
}, },
methods: { methods: {
onPlaceholderClick() {
this.inputRef.current.focus();
},
focus() { focus() {
this.selectorRef.current.focus(); this.selectorRef.current.focus();
}, },
blur() { blur() {
this.selectorRef.current.blur(); this.selectorRef.current.blur();
}, },
renderSelection() { _renderPlaceholder() {
const { selectorValueList, placeholder, prefixCls } = this.$props; const {
prefixCls,
placeholder,
searchPlaceholder,
searchValue,
selectorValueList,
} = this.$props;
const currentPlaceholder = placeholder || searchPlaceholder;
if (!currentPlaceholder) return null;
const hidden = searchValue || selectorValueList.length;
// [Legacy] Not remove the placeholder
return (
<span
style={{
display: hidden ? 'none' : 'block',
}}
onClick={this.onPlaceholderClick}
class={`${prefixCls}-selection-placeholder`}
>
{currentPlaceholder}
</span>
);
},
renderSelection() {
const { selectorValueList, prefixCls } = this.$props;
const selectedValueNodes = [];
if (selectorValueList.length) { if (selectorValueList.length) {
const { label, value } = selectorValueList[0]; const { label, value } = selectorValueList[0];
return ( selectedValueNodes.push(<span key="value" title={toTitle(label)} class={`${prefixCls}-selection-item`}>{label || value}</span>);
<span key="value" title={toTitle(label)} class={`${prefixCls}-selection-item`}>
{label || value}
</span>
);
} else {
return (
<span key="placeholder" class={`${prefixCls}-selection-placeholder`}>
{placeholder}
</span>
);
} }
selectedValueNodes.push(
<SearchInput
{...this.$props}
{...this.$attrs}
ref={this.inputRef}
isMultiple={false}
/>);
return selectedValueNodes;
}, },
}, },
@ -43,6 +74,7 @@ const SingleSelector = {
...getOptionProps(this), ...getOptionProps(this),
...this.$attrs, ...this.$attrs,
renderSelection: this.renderSelection, renderSelection: this.renderSelection,
renderPlaceholder: this._renderPlaceholder,
ref: this.selectorRef, ref: this.selectorRef,
}; };
return <Selector {...props} />; return <Selector {...props} />;