fix: select input width

pull/2523/head
tangjinzhou 2020-07-03 22:53:50 +08:00
parent ad6f343376
commit 89c9e81433
8 changed files with 57 additions and 66 deletions

@ -1 +1 @@
Subproject commit d680625687a695a9b9a06a131e12f9611a480d5b Subproject commit 44f59845e9fa34578b79066f22fb14526f4ee7a6

View File

@ -1,12 +1,11 @@
import ref from 'vue-ref'; import ref from 'vue-ref';
import { antInput } from './antInputDirective'; // import { antInput } from './antInputDirective';
import { antDecorator } from './FormDecoratorDirective'; import { antDecorator } from './FormDecoratorDirective';
import { antPortal } from './portalDirective'; import { antPortal } from './portalDirective';
export default { export default {
install: Vue => { install: Vue => {
Vue.use(ref, { name: 'ant-ref' }); Vue.use(ref, { name: 'ant-ref' });
antInput(Vue);
antDecorator(Vue); antDecorator(Vue);
antPortal(Vue); antPortal(Vue);
}, },

View File

@ -44,30 +44,29 @@ if (isIE9) {
}); });
} }
export function antInput(Vue) { export const antInput = {
return Vue.directive('ant-input', { mounted(el, binding, vnode) {
inserted(el, binding, vnode) { if (vnode.type === 'textarea' || isTextInputType(el.type)) {
if (vnode.tag === 'textarea' || isTextInputType(el.type)) { if (!binding.modifiers || !binding.modifiers.lazy) {
if (!binding.modifiers || !binding.modifiers.lazy) { el.addEventListener('compositionstart', onCompositionStart);
el.addEventListener('compositionstart', onCompositionStart); el.addEventListener('compositionend', onCompositionEnd);
el.addEventListener('compositionend', onCompositionEnd); // Safari < 10.2 & UIWebView doesn't fire compositionend when
// Safari < 10.2 & UIWebView doesn't fire compositionend when // switching focus before confirming composition choice
// switching focus before confirming composition choice // this also fixes the issue where some browsers e.g. iOS Chrome
// this also fixes the issue where some browsers e.g. iOS Chrome // fires "change" instead of "input" on autocomplete.
// fires "change" instead of "input" on autocomplete. el.addEventListener('change', onCompositionEnd);
el.addEventListener('change', onCompositionEnd); /* istanbul ignore if */
/* istanbul ignore if */ if (isIE9) {
if (isIE9) { el.vmodel = true;
el.vmodel = true;
}
} }
} }
}, }
}); },
} };
export default { export default {
install: Vue => { install: app => {
antInput(Vue); antInput(app);
app.directive('ant-input', antInput);
}, },
}; };

View File

@ -5,4 +5,7 @@ export default {
label: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), label: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
}, },
isSelectOptGroup: true, isSelectOptGroup: true,
render() {
return null;
},
}; };

View File

@ -8,4 +8,7 @@ export default {
title: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), title: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
}, },
isSelectOption: true, isSelectOption: true,
render() {
return null;
},
}; };

View File

@ -1,4 +1,4 @@
import {TransitionGroup} from 'vue'; import { TransitionGroup } from 'vue';
import KeyCode from '../_util/KeyCode'; import KeyCode from '../_util/KeyCode';
import PropTypes from '../_util/vue-types'; import PropTypes from '../_util/vue-types';
import classnames from 'classnames'; import classnames from 'classnames';
@ -149,7 +149,7 @@ const Select = {
}; };
return { return {
...state, ...state,
_mirrorInputValue: state._inputValue, // https://github.com/vueComponent/ant-design-vue/issues/1458 // _mirrorInputValue: state._inputValue, // https://github.com/vueComponent/ant-design-vue/issues/1458
...this.getDerivedState(props, state), ...this.getDerivedState(props, state),
}; };
}, },
@ -170,22 +170,10 @@ const Select = {
__propsSymbol__() { __propsSymbol__() {
Object.assign(this.$data, this.getDerivedState(getOptionProps(this), this.$data)); Object.assign(this.$data, this.getDerivedState(getOptionProps(this), this.$data));
}, },
_inputValue(val) {
this.$data._mirrorInputValue = val;
},
}, },
updated() { updated() {
this.$nextTick(() => { this.$nextTick(() => {
if (isMultipleOrTags(this.$props)) { this.updateInputWidth();
const inputNode = this.getInputDOMNode();
const mirrorNode = this.getInputMirrorDOMNode();
if (inputNode && inputNode.value && mirrorNode) {
inputNode.style.width = '';
inputNode.style.width = `${mirrorNode.clientWidth + 10}px`;
} else if (inputNode) {
inputNode.style.width = '';
}
}
this.forcePopupAlign(); this.forcePopupAlign();
}); });
}, },
@ -199,6 +187,18 @@ const Select = {
} }
}, },
methods: { methods: {
updateInputWidth() {
if (isMultipleOrTags(this.$props)) {
const inputNode = this.getInputDOMNode();
const mirrorNode = this.getInputMirrorDOMNode();
if (inputNode && inputNode.value && mirrorNode) {
inputNode.style.width = '';
inputNode.style.width = `${mirrorNode.clientWidth + 10}px`;
} else if (inputNode) {
inputNode.style.width = '';
}
}
},
getDerivedState(nextProps, prevState) { getDerivedState(nextProps, prevState) {
const optionsInfo = prevState._skipBuildOptionsInfo const optionsInfo = prevState._skipBuildOptionsInfo
? prevState._optionsInfo ? prevState._optionsInfo
@ -310,14 +310,7 @@ const Select = {
}, },
onInputChange(e) { onInputChange(e) {
const { value: val, composing } = e.target; const { value: val } = e.target;
const { _inputValue = '' } = this.$data;
if (e.isComposing || composing || _inputValue === val) {
this.setState({
_mirrorInputValue: val,
});
return;
}
const { tokenSeparators } = this.$props; const { tokenSeparators } = this.$props;
if ( if (
isMultipleOrTags(this.$props) && isMultipleOrTags(this.$props) &&
@ -639,20 +632,14 @@ const Select = {
getPlaceholderElement() { getPlaceholderElement() {
const { $props: props, $data: state } = this; const { $props: props, $data: state } = this;
let hidden = false; let hidden = false;
if (state._mirrorInputValue) { if (state._inputValue) {
hidden = true; hidden = true;
} }
const value = state._value; const value = state._value;
if (value.length) { if (value.length) {
hidden = true; hidden = true;
} }
if ( if (isCombobox(props) && value.length === 1 && state._value && !state._value[0]) {
!state._mirrorInputValue &&
isCombobox(props) &&
value.length === 1 &&
state._value &&
!state._value[0]
) {
hidden = false; hidden = false;
} }
const placeholder = props.placeholder; const placeholder = props.placeholder;
@ -781,9 +768,11 @@ const Select = {
}, },
_getInputElement() { _getInputElement() {
const props = this.$props; const props = this.$props;
const { _inputValue: inputValue, _mirrorInputValue } = this.$data; const { _inputValue: inputValue } = this.$data;
const attrs = this.$attrs; const attrs = this.$attrs;
const defaultInput = <input {...(attrs.id !== undefined ? {id: attrs.id}: {})} autoComplete="off"/>; const defaultInput = (
<input {...(attrs.id !== undefined ? { id: attrs.id } : {})} autoComplete="off" />
);
const inputElement = props.getInputElement ? props.getInputElement() : defaultInput; const inputElement = props.getInputElement ? props.getInputElement() : defaultInput;
const inputCls = classnames(inputElement.class, { const inputCls = classnames(inputElement.class, {
@ -816,7 +805,7 @@ const Select = {
onBlur: chaining(this.inputBlur, inputEvents.onBlur), onBlur: chaining(this.inputBlur, inputEvents.onBlur),
})} })}
<span ref={this.saveInputMirrorRef} class={`${props.prefixCls}-search__field__mirror`}> <span ref={this.saveInputMirrorRef} class={`${props.prefixCls}-search__field__mirror`}>
{_mirrorInputValue}&nbsp; {inputValue}&nbsp;
</span> </span>
</div> </div>
); );
@ -1206,7 +1195,7 @@ const Select = {
}); });
sel.push( sel.push(
<MenuItemGroup key={key} title={label} class={child.props?.class}> <MenuItemGroup key={key} title={label} class={child.props && child.props.class}>
{...innerItems} {...innerItems}
</MenuItemGroup>, </MenuItemGroup>,
); );
@ -1411,9 +1400,7 @@ const Select = {
tag: 'ul', tag: 'ul',
onAfterLeave: this.onChoiceAnimationLeave, onAfterLeave: this.onChoiceAnimationLeave,
}); });
innerNode = ( innerNode = <TransitionGroup {...transitionProps}>{selectedValueNodes}</TransitionGroup>;
<TransitionGroup {...transitionProps}>{selectedValueNodes}</TransitionGroup>
);
} else { } else {
innerNode = <ul>{selectedValueNodes}</ul>; innerNode = <ul>{selectedValueNodes}</ul>;
} }

View File

@ -4,7 +4,7 @@
</div> </div>
</template> </template>
<script> <script>
import demo from '../antdv-demo/docs/select/demo/tags'; import demo from '../antdv-demo/docs/auto-complete/demo/index';
export default { export default {
components: { components: {

View File

@ -152,7 +152,7 @@
"terser-webpack-plugin": "^3.0.3", "terser-webpack-plugin": "^3.0.3",
"through2": "^3.0.0", "through2": "^3.0.0",
"url-loader": "^3.0.0", "url-loader": "^3.0.0",
"vue": "^3.0.0-beta.17", "vue": "^3.0.0-beta.18",
"vue-antd-md-loader": "^1.1.0", "vue-antd-md-loader": "^1.1.0",
"vue-clipboard2": "0.3.1", "vue-clipboard2": "0.3.1",
"vue-draggable-resizable": "^2.1.0", "vue-draggable-resizable": "^2.1.0",