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,
isMultiple: PropTypes.looseBool,
showSearch: PropTypes.looseBool,
searchValue: PropTypes.string,
});
function noop() {}

View File

@ -20,19 +20,23 @@ const SearchInput = {
renderPlaceholder: PropTypes.func,
needAlign: PropTypes.looseBool,
ariaId: PropTypes.string,
isMultiple: PropTypes.looseBool.def(true),
},
setup(props) {
const measureRef = ref();
const inputWidth = ref(0);
// We measure width and set to the input immediately
onMounted(() => {
watch(
computed(()=>props.searchValue),
() => {
inputWidth.value = measureRef.value.scrollWidth;
},
{ flush: 'post' },
);
if(props.isMultiple) {
watch(
computed(()=>props.searchValue),
() => {
inputWidth.value = measureRef.value.scrollWidth;
},
{ flush: 'post', immediate: true },
);
}
});
return {
measureRef,
@ -52,15 +56,11 @@ const SearchInput = {
},
created() {
this.inputRef = createRef();
// this.mirrorInputRef = createRef();
this.prevProps = { ...this.$props };
},
mounted() {
this.$nextTick(() => {
const { open, needAlign } = this.$props;
if (needAlign) {
this.alignInputWidth();
}
const { open } = this.$props;
if (open) {
this.focus(true);
@ -75,22 +75,11 @@ const SearchInput = {
if (open && prevProps.open !== open) {
this.focus();
}
// if (needAlign && searchValue !== prevProps.searchValue) {
// this.alignInputWidth();
// }
this.prevProps = { ...this.$props };
});
},
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
@ -125,7 +114,7 @@ const SearchInput = {
},
render() {
const { searchValue, prefixCls, disabled, renderPlaceholder, open, ariaId } = this.$props;
const { searchValue, prefixCls, disabled, renderPlaceholder, open, ariaId, isMultiple } = this.$props;
const {
vcTreeSelect: { onSearchInputKeyDown },
handleInputChange,
@ -134,7 +123,7 @@ const SearchInput = {
} = this;
return (
<>
<span class={`${prefixCls}-selection-search`} style={{ width: inputWidth + 'px' }}>
<span class={`${prefixCls}-selection-search`} style={isMultiple ? { width: inputWidth + 'px' }:{}}>
{withDirectives(
<input
type="text"
@ -152,9 +141,9 @@ const SearchInput = {
/>,
[[antInput]],
)}
<span ref="measureRef" class={`${prefixCls}-selection-search-mirror`} aria-hidden>
{isMultiple ? <span ref="measureRef" class={`${prefixCls}-selection-search-mirror`} aria-hidden>
{mirrorSearchValue}&nbsp;
</span>
</span> : null}
</span>
{renderPlaceholder && !mirrorSearchValue ? renderPlaceholder() : null}
</>

View File

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

View File

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

View File

@ -2,6 +2,7 @@ import generateSelector, { selectorPropTypes } from '../Base/BaseSelector';
import { toTitle } from '../util';
import { getOptionProps } from '../../../_util/props-util';
import { createRef } from '../util';
import SearchInput from '../SearchInput';
const Selector = generateSelector('single');
const SingleSelector = {
@ -10,31 +11,61 @@ const SingleSelector = {
props: selectorPropTypes(),
created() {
this.selectorRef = createRef();
this.inputRef = createRef();
},
methods: {
onPlaceholderClick() {
this.inputRef.current.focus();
},
focus() {
this.selectorRef.current.focus();
},
blur() {
this.selectorRef.current.blur();
},
renderSelection() {
const { selectorValueList, placeholder, prefixCls } = this.$props;
_renderPlaceholder() {
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) {
const { label, value } = selectorValueList[0];
return (
<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(<span key="value" title={toTitle(label)} class={`${prefixCls}-selection-item`}>{label || value}</span>);
}
selectedValueNodes.push(
<SearchInput
{...this.$props}
{...this.$attrs}
ref={this.inputRef}
isMultiple={false}
/>);
return selectedValueNodes;
},
},
@ -43,6 +74,7 @@ const SingleSelector = {
...getOptionProps(this),
...this.$attrs,
renderSelection: this.renderSelection,
renderPlaceholder: this._renderPlaceholder,
ref: this.selectorRef,
};
return <Selector {...props} />;