Browse Source

fix: tree-select placeholder error

pull/3053/head
tangjinzhou 4 years ago
parent
commit
e0667855ee
  1. 2
      antdv-demo
  2. 51
      components/_util/BaseInput.tsx
  3. 63
      components/vc-tree-select/src/SearchInput.jsx
  4. 15
      components/vc-tree-select/src/Select.jsx
  5. 35
      components/vc-tree-select/src/Selector/SingleSelector.jsx
  6. 2
      examples/App.vue

2
antdv-demo

@ -1 +1 @@
Subproject commit ab46da93f0bca77a66a25f0ef427fa106d6dff13 Subproject commit 6cb2ff40c46114d4195edcacf82e56b6686ff8a7

51
components/_util/BaseInput.tsx

@ -0,0 +1,51 @@
import { defineComponent, ref, withDirectives } from 'vue';
import antInput from './antInputDirective';
import PropTypes from './vue-types';
const BaseInput = defineComponent({
props: {
value: PropTypes.string.def(''),
},
emits: ['change', 'input'],
setup(_p, { emit }) {
const inputRef = ref(null);
const handleChange = (e: Event) => {
const { composing } = e.target as any;
if ((e as any).isComposing || composing) {
emit('input', e);
} else {
emit('input', e);
emit('change', e);
}
};
return {
inputRef,
focus: () => {
if (inputRef.value) {
inputRef.value.focus();
}
},
blur: () => {
if (inputRef.value) {
inputRef.value.blur();
}
},
handleChange,
};
},
render() {
return withDirectives(
(
<input
{...this.$props}
{...this.$attrs}
onInput={this.handleChange}
onChange={this.handleChange}
ref="inputRef"
/>
) as any,
[[antInput]],
);
},
});
export default BaseInput;

63
components/vc-tree-select/src/SearchInput.jsx

@ -4,8 +4,8 @@
* - multiple: in the selector * - multiple: in the selector
* Move the code as a SearchInput for easy management. * Move the code as a SearchInput for easy management.
*/ */
import { inject, withDirectives, ref, onMounted, computed, watch } from 'vue'; import BaseInput from '../../_util/BaseInput';
import antInput from '../../_util/antInputDirective'; import { inject, ref, onMounted, computed, watch } from 'vue';
import PropTypes from '../../_util/vue-types'; import PropTypes from '../../_util/vue-types';
import { createRef } from './util'; import { createRef } from './util';
@ -22,38 +22,42 @@ const SearchInput = {
ariaId: PropTypes.string, ariaId: PropTypes.string,
isMultiple: PropTypes.looseBool.def(true), isMultiple: PropTypes.looseBool.def(true),
}, },
setup(props) { setup(props, { emit }) {
const measureRef = ref(); const measureRef = ref();
const inputWidth = ref(0); const inputWidth = ref(0);
const mirrorSearchValue = ref(props.searchValue);
watch(
computed(() => props.searchValue),
() => {
mirrorSearchValue.value = props.searchValue;
},
);
watch(
mirrorSearchValue,
() => {
emit('mirrorSearchValueChange', mirrorSearchValue.value);
},
{ immediate: true },
);
// We measure width and set to the input immediately // We measure width and set to the input immediately
onMounted(() => { onMounted(() => {
if (props.isMultiple) { if (props.isMultiple) {
watch( watch(
computed(()=>props.searchValue), mirrorSearchValue,
() => { () => {
inputWidth.value = measureRef.value.scrollWidth; inputWidth.value = measureRef.value.scrollWidth;
}, },
{ flush: 'post', immediate: true }, { flush: 'post', immediate: true },
); );
} }
}); });
return { return {
measureRef, measureRef,
inputWidth, inputWidth,
vcTreeSelect: inject('vcTreeSelect', {}), vcTreeSelect: inject('vcTreeSelect', {}),
mirrorSearchValue,
}; };
}, },
data() {
return {
mirrorSearchValue: this.searchValue,
};
},
watch: {
searchValue(val) {
this.mirrorSearchValue = val;
},
},
created() { created() {
this.inputRef = createRef(); this.inputRef = createRef();
this.prevProps = { ...this.$props }; this.prevProps = { ...this.$props };
@ -80,7 +84,6 @@ const SearchInput = {
}); });
}, },
methods: { methods: {
/** /**
* 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
*/ */
@ -114,7 +117,15 @@ const SearchInput = {
}, },
render() { render() {
const { searchValue, prefixCls, disabled, renderPlaceholder, open, ariaId, isMultiple } = this.$props; const {
searchValue,
prefixCls,
disabled,
renderPlaceholder,
open,
ariaId,
isMultiple,
} = this.$props;
const { const {
vcTreeSelect: { onSearchInputKeyDown }, vcTreeSelect: { onSearchInputKeyDown },
handleInputChange, handleInputChange,
@ -123,9 +134,11 @@ const SearchInput = {
} = this; } = this;
return ( return (
<> <>
<span class={`${prefixCls}-selection-search`} style={isMultiple ? { width: inputWidth + 'px' }:{}}> <span
{withDirectives( class={`${prefixCls}-selection-search`}
<input style={isMultiple ? { width: inputWidth + 'px' } : {}}
>
<BaseInput
type="text" type="text"
ref={this.inputRef} ref={this.inputRef}
onInput={handleInputChange} onInput={handleInputChange}
@ -138,12 +151,12 @@ const SearchInput = {
aria-autocomplete="list" aria-autocomplete="list"
aria-controls={open ? ariaId : undefined} aria-controls={open ? ariaId : undefined}
aria-multiline="false" aria-multiline="false"
/>, />
[[antInput]], {isMultiple ? (
)} <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> : null} </span>
) : null}
</span> </span>
{renderPlaceholder && !mirrorSearchValue ? renderPlaceholder() : null} {renderPlaceholder && !mirrorSearchValue ? renderPlaceholder() : null}
</> </>

15
components/vc-tree-select/src/Select.jsx

@ -216,13 +216,19 @@ const Select = defineComponent({
this.setState(state); this.setState(state);
this.needSyncKeys = {}; this.needSyncKeys = {};
}, },
'$data._valueList'() { _valueList() {
this.$nextTick(() => { this.$nextTick(() => {
this.forcePopupAlign(); this.forcePopupAlign();
}); });
}, },
'$data._open'(open) { _open(open) {
this.$nextTick(() => { this.$nextTick(() => {
if (!open && !this.isSearchValueControlled()) {
this.setState({ _searchValue: '' });
}
if (open && !this.$data._searchValue) {
this.setState({ _filteredTreeNodes: null });
}
const { prefixCls } = this.$props; const { prefixCls } = this.$props;
const { _selectorValueList: selectorValueList, _valueEntities: valueEntities } = this.$data; const { _selectorValueList: selectorValueList, _valueEntities: valueEntities } = this.$data;
const isMultiple = this.isMultiple(); const isMultiple = this.isMultiple();
@ -489,7 +495,6 @@ const Select = defineComponent({
newState._valueEntities || prevState._valueEntities, newState._valueEntities || prevState._valueEntities,
); );
}); });
return newState; return newState;
}, },
// ==================== Selector ==================== // ==================== Selector ====================
@ -637,7 +642,6 @@ const Select = defineComponent({
disabled, disabled,
inputValue, inputValue,
treeNodeLabelProp, treeNodeLabelProp,
multiple,
treeCheckable, treeCheckable,
treeCheckStrictly, treeCheckStrictly,
autoClearSearchValue, autoClearSearchValue,
@ -697,7 +701,7 @@ const Select = defineComponent({
// Clean up `searchValue` when this prop is set // Clean up `searchValue` when this prop is set
if (autoClearSearchValue || inputValue === null) { if (autoClearSearchValue || inputValue === null) {
// Clean state `searchValue` if uncontrolled // Clean state `searchValue` if uncontrolled
if (!this.isSearchValueControlled() && (multiple || treeCheckable)) { if (!this.isSearchValueControlled()) {
this.setUncontrolledState({ this.setUncontrolledState({
_searchValue: '', _searchValue: '',
_filteredTreeNodes: null, _filteredTreeNodes: null,
@ -848,7 +852,6 @@ const Select = defineComponent({
if (isSet) { if (isSet) {
// Do the search logic // Do the search logic
const upperSearchValue = String(value).toUpperCase(); const upperSearchValue = String(value).toUpperCase();
let filterTreeNodeFn = filterTreeNode; let filterTreeNodeFn = filterTreeNode;
if (filterTreeNode === false) { if (filterTreeNode === false) {
filterTreeNodeFn = () => true; filterTreeNodeFn = () => true;

35
components/vc-tree-select/src/Selector/SingleSelector.jsx

@ -13,6 +13,16 @@ const SingleSelector = {
this.selectorRef = createRef(); this.selectorRef = createRef();
this.inputRef = createRef(); this.inputRef = createRef();
}, },
data() {
return {
mirrorSearchValue: this.searchValue,
};
},
watch: {
searchValue(val) {
this.mirrorSearchValue = val;
},
},
methods: { methods: {
onPlaceholderClick() { onPlaceholderClick() {
this.inputRef.current.focus(); this.inputRef.current.focus();
@ -24,19 +34,13 @@ const SingleSelector = {
this.selectorRef.current.blur(); this.selectorRef.current.blur();
}, },
_renderPlaceholder() { _renderPlaceholder() {
const { const { prefixCls, placeholder, searchPlaceholder, selectorValueList } = this.$props;
prefixCls,
placeholder,
searchPlaceholder,
searchValue,
selectorValueList,
} = this.$props;
const currentPlaceholder = placeholder || searchPlaceholder; const currentPlaceholder = placeholder || searchPlaceholder;
if (!currentPlaceholder) return null; if (!currentPlaceholder) return null;
const hidden = searchValue || selectorValueList.length; const hidden = this.mirrorSearchValue || selectorValueList.length;
// [Legacy] Not remove the placeholder // [Legacy] Not remove the placeholder
return ( return (
@ -51,12 +55,19 @@ const SingleSelector = {
</span> </span>
); );
}, },
onMirrorSearchValueChange(value) {
this.mirrorSearchValue = value;
},
renderSelection() { renderSelection() {
const { selectorValueList, prefixCls } = this.$props; const { selectorValueList, prefixCls } = this.$props;
const selectedValueNodes = []; const selectedValueNodes = [];
if (selectorValueList.length) { if (selectorValueList.length && !this.mirrorSearchValue) {
const { label, value } = selectorValueList[0]; const { label, value } = selectorValueList[0];
selectedValueNodes.push(<span key="value" title={toTitle(label)} class={`${prefixCls}-selection-item`}>{label || value}</span>); selectedValueNodes.push(
<span key="value" title={toTitle(label)} class={`${prefixCls}-selection-item`}>
{label || value}
</span>,
);
} }
selectedValueNodes.push( selectedValueNodes.push(
<SearchInput <SearchInput
@ -64,7 +75,9 @@ const SingleSelector = {
{...this.$attrs} {...this.$attrs}
ref={this.inputRef} ref={this.inputRef}
isMultiple={false} isMultiple={false}
/>); onMirrorSearchValueChange={this.onMirrorSearchValueChange}
/>,
);
return selectedValueNodes; return selectedValueNodes;
}, },
}, },

2
examples/App.vue

@ -5,7 +5,7 @@
</template> </template>
<script> <script>
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import demo from '../antdv-demo/docs/select/demo'; import demo from '../antdv-demo/docs/tree-select/demo';
// import Affix from '../components/affix'; // import Affix from '../components/affix';
export default defineComponent({ export default defineComponent({
components: { components: {

Loading…
Cancel
Save