ant-design-vue/components/vc-tree-select/src/SearchInput.jsx

141 lines
3.5 KiB
Vue
Raw Normal View History

/**
* Since search box is in different position with different mode.
* - Single: in the popup box
* - multiple: in the selector
* Move the code as a SearchInput for easy management.
*/
2019-01-12 03:33:27 +00:00
import PropTypes from '../../_util/vue-types';
import { createRef } from './util';
const SearchInput = {
name: 'SearchInput',
props: {
open: PropTypes.bool,
searchValue: PropTypes.string,
prefixCls: PropTypes.string,
disabled: PropTypes.bool,
renderPlaceholder: PropTypes.func,
needAlign: PropTypes.bool,
ariaId: PropTypes.string,
},
inject: {
2019-01-28 13:09:13 +00:00
vcTreeSelect: { default: () => ({}) },
},
2019-01-12 03:33:27 +00:00
created() {
this.inputRef = createRef();
this.mirrorInputRef = createRef();
this.prevProps = { ...this.$props };
},
2019-01-12 03:33:27 +00:00
mounted() {
this.$nextTick(() => {
2019-01-12 03:33:27 +00:00
const { open, needAlign } = this.$props;
if (needAlign) {
2019-01-12 03:33:27 +00:00
this.alignInputWidth();
}
if (open) {
2019-01-12 03:33:27 +00:00
this.focus(true);
}
2019-01-12 03:33:27 +00:00
});
},
2019-01-12 03:33:27 +00:00
updated() {
const { open, searchValue, needAlign } = this.$props;
const { prevProps } = this;
this.$nextTick(() => {
if (open && prevProps.open !== open) {
2019-01-12 03:33:27 +00:00
this.focus();
}
if (needAlign && searchValue !== prevProps.searchValue) {
2019-01-12 03:33:27 +00:00
this.alignInputWidth();
}
2019-01-12 03:33:27 +00:00
this.prevProps = { ...this.$props };
});
},
methods: {
/**
2019-01-12 03:33:27 +00:00
* `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`;
},
/**
2019-01-12 03:33:27 +00:00
* Need additional timeout for focus cause parent dom is not ready when didMount trigger
*/
focus(isDidMount) {
if (this.inputRef.current) {
if (isDidMount) {
setTimeout(() => {
2019-01-12 03:33:27 +00:00
this.inputRef.current.focus();
}, 0);
} else {
// set it into else, Avoid scrolling when focus
this.inputRef.current.focus();
}
}
},
2019-01-12 03:33:27 +00:00
blur() {
if (this.inputRef.current) {
2019-01-12 03:33:27 +00:00
this.inputRef.current.blur();
}
},
},
2019-01-12 03:33:27 +00:00
render() {
const { searchValue, prefixCls, disabled, renderPlaceholder, open, ariaId } = this.$props;
const {
vcTreeSelect: { onSearchInputChange, onSearchInputKeyDown },
} = this;
return (
<span class={`${prefixCls}-search__field__wrap`}>
<input
2019-01-12 03:33:27 +00:00
type="text"
{...{
directives: [
{
name: 'ant-ref',
value: this.inputRef,
},
2019-11-14 11:19:24 +00:00
{
name: 'ant-input',
},
2019-01-12 03:33:27 +00:00
],
}}
onInput={onSearchInputChange}
onKeydown={onSearchInputKeyDown}
value={searchValue}
disabled={disabled}
class={`${prefixCls}-search__field`}
2019-01-12 03:33:27 +00:00
aria-label="filter select"
aria-autocomplete="list"
aria-controls={open ? ariaId : undefined}
2019-01-12 03:33:27 +00:00
aria-multiline="false"
/>
<span
2019-01-12 03:33:27 +00:00
{...{
directives: [
{
name: 'ant-ref',
value: this.mirrorInputRef,
},
],
}}
class={`${prefixCls}-search__field__mirror`}
>
{searchValue}&nbsp;
</span>
{renderPlaceholder ? renderPlaceholder() : null}
</span>
2019-01-12 03:33:27 +00:00
);
},
2019-01-12 03:33:27 +00:00
};
2019-01-12 03:33:27 +00:00
export default SearchInput;