refactor: input by ts
parent
20f54950a9
commit
6cb52efbc8
|
@ -1 +1 @@
|
||||||
Subproject commit 88970d13f8e2e6f5c96a28697fe0b399eccdcb07
|
Subproject commit c9c4f31698398d5bafa5ccd80f0cb7c23b1ab608
|
|
@ -4,8 +4,10 @@ import { getInputClassName } from './Input';
|
||||||
import PropTypes from '../_util/vue-types';
|
import PropTypes from '../_util/vue-types';
|
||||||
import { cloneElement } from '../_util/vnode';
|
import { cloneElement } from '../_util/vnode';
|
||||||
import { getComponent } from '../_util/props-util';
|
import { getComponent } from '../_util/props-util';
|
||||||
|
import { defineComponent, VNode } from 'vue';
|
||||||
|
import { tuple } from '../_util/type';
|
||||||
|
|
||||||
export function hasPrefixSuffix(instance) {
|
export function hasPrefixSuffix(instance: any) {
|
||||||
return !!(
|
return !!(
|
||||||
getComponent(instance, 'prefix') ||
|
getComponent(instance, 'prefix') ||
|
||||||
getComponent(instance, 'suffix') ||
|
getComponent(instance, 'suffix') ||
|
||||||
|
@ -15,27 +17,27 @@ export function hasPrefixSuffix(instance) {
|
||||||
|
|
||||||
const ClearableInputType = ['text', 'input'];
|
const ClearableInputType = ['text', 'input'];
|
||||||
|
|
||||||
const ClearableLabeledInput = {
|
const ClearableLabeledInput = defineComponent({
|
||||||
name: 'ClearableLabeledInput',
|
name: 'ClearableLabeledInput',
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: {
|
props: {
|
||||||
prefixCls: PropTypes.string,
|
prefixCls: PropTypes.string,
|
||||||
inputType: PropTypes.oneOf(ClearableInputType),
|
inputType: PropTypes.oneOf(tuple('text', 'input')),
|
||||||
value: PropTypes.any,
|
value: PropTypes.any,
|
||||||
defaultValue: PropTypes.any,
|
defaultValue: PropTypes.any,
|
||||||
allowClear: PropTypes.looseBool,
|
allowClear: PropTypes.looseBool,
|
||||||
element: PropTypes.any,
|
element: PropTypes.VNodeChild,
|
||||||
handleReset: PropTypes.func,
|
handleReset: PropTypes.func,
|
||||||
disabled: PropTypes.looseBool,
|
disabled: PropTypes.looseBool,
|
||||||
size: PropTypes.oneOf(['small', 'large', 'default']),
|
size: PropTypes.oneOf(tuple('small', 'large', 'default')),
|
||||||
suffix: PropTypes.any,
|
suffix: PropTypes.VNodeChild,
|
||||||
prefix: PropTypes.any,
|
prefix: PropTypes.VNodeChild,
|
||||||
addonBefore: PropTypes.any,
|
addonBefore: PropTypes.VNodeChild,
|
||||||
addonAfter: PropTypes.any,
|
addonAfter: PropTypes.VNodeChild,
|
||||||
readonly: PropTypes.looseBool,
|
readonly: PropTypes.looseBool,
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
renderClearIcon(prefixCls) {
|
renderClearIcon(prefixCls: string) {
|
||||||
const { allowClear, value, disabled, readonly, inputType, handleReset } = this.$props;
|
const { allowClear, value, disabled, readonly, inputType, handleReset } = this.$props;
|
||||||
if (
|
if (
|
||||||
!allowClear ||
|
!allowClear ||
|
||||||
|
@ -54,7 +56,7 @@ const ClearableLabeledInput = {
|
||||||
return <CloseCircleFilled onClick={handleReset} class={className} role="button" />;
|
return <CloseCircleFilled onClick={handleReset} class={className} role="button" />;
|
||||||
},
|
},
|
||||||
|
|
||||||
renderSuffix(prefixCls) {
|
renderSuffix(prefixCls: string) {
|
||||||
const { suffix, allowClear } = this.$props;
|
const { suffix, allowClear } = this.$props;
|
||||||
if (suffix || allowClear) {
|
if (suffix || allowClear) {
|
||||||
return (
|
return (
|
||||||
|
@ -67,7 +69,7 @@ const ClearableLabeledInput = {
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
|
|
||||||
renderLabeledIcon(prefixCls, element) {
|
renderLabeledIcon(prefixCls: string, element: VNode): VNode {
|
||||||
const props = this.$props;
|
const props = this.$props;
|
||||||
const suffix = this.renderSuffix(prefixCls);
|
const suffix = this.renderSuffix(prefixCls);
|
||||||
if (!hasPrefixSuffix(this)) {
|
if (!hasPrefixSuffix(this)) {
|
||||||
|
@ -88,7 +90,7 @@ const ClearableLabeledInput = {
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span class={affixWrapperCls} style={props.style}>
|
<span class={affixWrapperCls} style={this.$attrs?.style}>
|
||||||
{prefix}
|
{prefix}
|
||||||
{cloneElement(element, {
|
{cloneElement(element, {
|
||||||
style: null,
|
style: null,
|
||||||
|
@ -97,10 +99,10 @@ const ClearableLabeledInput = {
|
||||||
})}
|
})}
|
||||||
{suffix}
|
{suffix}
|
||||||
</span>
|
</span>
|
||||||
);
|
) as VNode;
|
||||||
},
|
},
|
||||||
|
|
||||||
renderInputWithLabel(prefixCls, labeledElement) {
|
renderInputWithLabel(prefixCls: string, labeledElement: VNode) {
|
||||||
const { addonBefore, addonAfter, size } = this.$props;
|
const { addonBefore, addonAfter, size } = this.$props;
|
||||||
const { style, class: className } = this.$attrs;
|
const { style, class: className } = this.$attrs;
|
||||||
// Not wrap when there is not addons
|
// Not wrap when there is not addons
|
||||||
|
@ -137,7 +139,7 @@ const ClearableLabeledInput = {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
renderTextAreaWithClearIcon(prefixCls, element) {
|
renderTextAreaWithClearIcon(prefixCls: string, element: VNode) {
|
||||||
const { value, allowClear } = this.$props;
|
const { value, allowClear } = this.$props;
|
||||||
const { style, class: className } = this.$attrs;
|
const { style, class: className } = this.$attrs;
|
||||||
if (!allowClear) {
|
if (!allowClear) {
|
||||||
|
@ -160,7 +162,7 @@ const ClearableLabeledInput = {
|
||||||
},
|
},
|
||||||
|
|
||||||
renderClearableLabeledInput() {
|
renderClearableLabeledInput() {
|
||||||
const { prefixCls, inputType, element } = this.$props;
|
const { prefixCls, inputType, element } = this.$props as any;
|
||||||
if (inputType === ClearableInputType[0]) {
|
if (inputType === ClearableInputType[0]) {
|
||||||
return this.renderTextAreaWithClearIcon(prefixCls, element);
|
return this.renderTextAreaWithClearIcon(prefixCls, element);
|
||||||
}
|
}
|
||||||
|
@ -170,6 +172,6 @@ const ClearableLabeledInput = {
|
||||||
render() {
|
render() {
|
||||||
return this.renderClearableLabeledInput();
|
return this.renderClearableLabeledInput();
|
||||||
},
|
},
|
||||||
};
|
});
|
||||||
|
|
||||||
export default ClearableLabeledInput;
|
export default ClearableLabeledInput;
|
|
@ -1,17 +1,14 @@
|
||||||
import { inject } from 'vue';
|
import { defineComponent, inject } from 'vue';
|
||||||
import PropTypes from '../_util/vue-types';
|
import PropTypes from '../_util/vue-types';
|
||||||
import { getSlot } from '../_util/props-util';
|
import { getSlot } from '../_util/props-util';
|
||||||
import { defaultConfigProvider } from '../config-provider';
|
import { defaultConfigProvider } from '../config-provider';
|
||||||
|
import { tuple } from '../_util/type';
|
||||||
|
|
||||||
export default {
|
export default defineComponent({
|
||||||
name: 'AInputGroup',
|
name: 'AInputGroup',
|
||||||
props: {
|
props: {
|
||||||
prefixCls: PropTypes.string,
|
prefixCls: PropTypes.string,
|
||||||
size: {
|
size: PropTypes.oneOf(tuple('small', 'large', 'default')),
|
||||||
validator(value) {
|
|
||||||
return ['small', 'large', 'default'].includes(value);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
compact: PropTypes.looseBool,
|
compact: PropTypes.looseBool,
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
|
@ -21,8 +18,8 @@ export default {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
classes() {
|
classes() {
|
||||||
const { prefixCls: customizePrefixCls, size, compact = false } = this;
|
const { prefixCls: customizePrefixCls, size, compact = false, configProvider } = this as any;
|
||||||
const getPrefixCls = this.configProvider.getPrefixCls;
|
const getPrefixCls = configProvider.getPrefixCls;
|
||||||
const prefixCls = getPrefixCls('input-group', customizePrefixCls);
|
const prefixCls = getPrefixCls('input-group', customizePrefixCls);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -36,4 +33,4 @@ export default {
|
||||||
render() {
|
render() {
|
||||||
return <span class={this.classes}>{getSlot(this)}</span>;
|
return <span class={this.classes}>{getSlot(this)}</span>;
|
||||||
},
|
},
|
||||||
};
|
});
|
|
@ -1,4 +1,4 @@
|
||||||
import { defineComponent, inject, withDirectives } from 'vue';
|
import { defineComponent, inject, VNode, withDirectives } from 'vue';
|
||||||
import antInputDirective from '../_util/antInputDirective';
|
import antInputDirective from '../_util/antInputDirective';
|
||||||
import classNames from '../_util/classNames';
|
import classNames from '../_util/classNames';
|
||||||
import omit from 'omit.js';
|
import omit from 'omit.js';
|
||||||
|
@ -57,6 +57,9 @@ export default defineComponent({
|
||||||
setup() {
|
setup() {
|
||||||
return {
|
return {
|
||||||
configProvider: inject('configProvider', defaultConfigProvider),
|
configProvider: inject('configProvider', defaultConfigProvider),
|
||||||
|
removePasswordTimeout: undefined,
|
||||||
|
input: null,
|
||||||
|
clearableInput: null
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
@ -98,15 +101,15 @@ export default defineComponent({
|
||||||
this.input.select();
|
this.input.select();
|
||||||
},
|
},
|
||||||
|
|
||||||
saveClearableInput(input) {
|
saveClearableInput(input: any) {
|
||||||
this.clearableInput = input;
|
this.clearableInput = input;
|
||||||
},
|
},
|
||||||
|
|
||||||
saveInput(input) {
|
saveInput(input: any) {
|
||||||
this.input = input;
|
this.input = input;
|
||||||
},
|
},
|
||||||
|
|
||||||
setValue(value, callback) {
|
setValue(value: any, callback?: Function) {
|
||||||
if (this.stateValue === value) {
|
if (this.stateValue === value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -119,18 +122,18 @@ export default defineComponent({
|
||||||
callback && callback();
|
callback && callback();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
triggerChange(e) {
|
triggerChange(e: Event) {
|
||||||
this.$emit('update:value', e.target.value);
|
this.$emit('update:value', (e.target as any).value);
|
||||||
this.$emit('change', e);
|
this.$emit('change', e);
|
||||||
this.$emit('input', e);
|
this.$emit('input', e);
|
||||||
},
|
},
|
||||||
handleReset(e) {
|
handleReset(e: Event) {
|
||||||
this.setValue('', () => {
|
this.setValue('', () => {
|
||||||
this.focus();
|
this.focus();
|
||||||
});
|
});
|
||||||
resolveOnChange(this.input, e, this.triggerChange);
|
resolveOnChange(this.input, e, this.triggerChange);
|
||||||
},
|
},
|
||||||
renderInput(prefixCls, { addonBefore, addonAfter }) {
|
renderInput(prefixCls: string, { addonBefore, addonAfter }) {
|
||||||
const otherProps = omit(this.$props, [
|
const otherProps = omit(this.$props, [
|
||||||
'prefixCls',
|
'prefixCls',
|
||||||
'onPressEnter',
|
'onPressEnter',
|
||||||
|
@ -142,19 +145,17 @@ export default defineComponent({
|
||||||
'defaultValue',
|
'defaultValue',
|
||||||
'lazy',
|
'lazy',
|
||||||
'size',
|
'size',
|
||||||
'inputType',
|
|
||||||
'className',
|
|
||||||
'inputPrefixCls',
|
'inputPrefixCls',
|
||||||
'loading',
|
'loading',
|
||||||
]);
|
]);
|
||||||
const { handleKeyDown, handleChange, size, disabled, $attrs } = this;
|
const { handleKeyDown, handleChange, size, disabled, $attrs } = this;
|
||||||
|
|
||||||
const inputProps = {
|
const inputProps: any = {
|
||||||
...otherProps,
|
...otherProps,
|
||||||
...$attrs,
|
...$attrs,
|
||||||
onKeydown: handleKeyDown,
|
onKeydown: handleKeyDown,
|
||||||
class: classNames(getInputClassName(prefixCls, size, disabled), {
|
class: classNames(getInputClassName(prefixCls, size, disabled), {
|
||||||
[$attrs.class]: $attrs.class && !addonBefore && !addonAfter,
|
[$attrs.class as string]: $attrs.class && !addonBefore && !addonAfter,
|
||||||
}),
|
}),
|
||||||
ref: this.saveInput,
|
ref: this.saveInput,
|
||||||
key: 'ant-input',
|
key: 'ant-input',
|
||||||
|
@ -164,7 +165,8 @@ export default defineComponent({
|
||||||
if (!inputProps.autofocus) {
|
if (!inputProps.autofocus) {
|
||||||
delete inputProps.autofocus;
|
delete inputProps.autofocus;
|
||||||
}
|
}
|
||||||
return withDirectives(<input {...inputProps} />, [[antInputDirective]]);
|
const inputNode = <input {...inputProps} />
|
||||||
|
return withDirectives(inputNode as VNode, [[antInputDirective]]);
|
||||||
},
|
},
|
||||||
clearPasswordValueAttribute() {
|
clearPasswordValueAttribute() {
|
||||||
// https://github.com/ant-design/ant-design/issues/20541
|
// https://github.com/ant-design/ant-design/issues/20541
|
||||||
|
@ -179,14 +181,14 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleChange(e) {
|
handleChange(e: Event) {
|
||||||
const { value, composing } = e.target;
|
const { value, composing, isComposing } = e.target as any;
|
||||||
// https://github.com/vueComponent/ant-design-vue/issues/2203
|
// https://github.com/vueComponent/ant-design-vue/issues/2203
|
||||||
if (((e.isComposing || composing) && this.lazy) || this.stateValue === value) return;
|
if (((isComposing || composing) && this.lazy) || this.stateValue === value) return;
|
||||||
this.setValue(value, this.clearPasswordValueAttribute);
|
this.setValue(value, this.clearPasswordValueAttribute);
|
||||||
resolveOnChange(this.input, e, this.triggerChange);
|
resolveOnChange(this.input, e, this.triggerChange);
|
||||||
},
|
},
|
||||||
handleKeyDown(e) {
|
handleKeyDown(e: KeyboardEvent) {
|
||||||
if (e.keyCode === 13) {
|
if (e.keyCode === 13) {
|
||||||
this.$emit('pressEnter', e);
|
this.$emit('pressEnter', e);
|
||||||
}
|
}
|
||||||
|
@ -194,16 +196,6 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
render() {
|
render() {
|
||||||
// if (this.$props.type === 'textarea') {
|
|
||||||
// const textareaProps = {
|
|
||||||
// ...this.$props,
|
|
||||||
// ...this.$attrs,
|
|
||||||
// onInput: this.handleChange,
|
|
||||||
// onKeydown: this.handleKeyDown,
|
|
||||||
// onChange: noop,
|
|
||||||
// };
|
|
||||||
// return <TextArea {...textareaProps} ref="input" />;
|
|
||||||
// }
|
|
||||||
const { prefixCls: customizePrefixCls } = this.$props;
|
const { prefixCls: customizePrefixCls } = this.$props;
|
||||||
const { stateValue } = this.$data;
|
const { stateValue } = this.$data;
|
||||||
const getPrefixCls = this.configProvider.getPrefixCls;
|
const getPrefixCls = this.configProvider.getPrefixCls;
|
||||||
|
@ -212,7 +204,7 @@ export default defineComponent({
|
||||||
const addonBefore = getComponent(this, 'addonBefore');
|
const addonBefore = getComponent(this, 'addonBefore');
|
||||||
const suffix = getComponent(this, 'suffix');
|
const suffix = getComponent(this, 'suffix');
|
||||||
const prefix = getComponent(this, 'prefix');
|
const prefix = getComponent(this, 'prefix');
|
||||||
const props = {
|
const props: any = {
|
||||||
...this.$attrs,
|
...this.$attrs,
|
||||||
...getOptionProps(this),
|
...getOptionProps(this),
|
||||||
prefixCls,
|
prefixCls,
|
|
@ -6,13 +6,14 @@ import EyeInvisibleOutlined from '@ant-design/icons-vue/EyeInvisibleOutlined';
|
||||||
import inputProps from './inputProps';
|
import inputProps from './inputProps';
|
||||||
import PropTypes from '../_util/vue-types';
|
import PropTypes from '../_util/vue-types';
|
||||||
import BaseMixin from '../_util/BaseMixin';
|
import BaseMixin from '../_util/BaseMixin';
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
const ActionMap = {
|
const ActionMap = {
|
||||||
click: 'onClick',
|
click: 'onClick',
|
||||||
hover: 'onMouseover',
|
hover: 'onMouseover',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default defineComponent({
|
||||||
name: 'AInputPassword',
|
name: 'AInputPassword',
|
||||||
mixins: [BaseMixin],
|
mixins: [BaseMixin],
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
|
@ -23,13 +24,18 @@ export default {
|
||||||
action: PropTypes.string.def('click'),
|
action: PropTypes.string.def('click'),
|
||||||
visibilityToggle: PropTypes.looseBool.def(true),
|
visibilityToggle: PropTypes.looseBool.def(true),
|
||||||
},
|
},
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
input: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
visible: false,
|
visible: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
saveInput(node) {
|
saveInput(node: any) {
|
||||||
this.input = node;
|
this.input = node;
|
||||||
},
|
},
|
||||||
focus() {
|
focus() {
|
||||||
|
@ -101,4 +107,4 @@ export default {
|
||||||
};
|
};
|
||||||
return <Input {...inputProps} ref={this.saveInput} />;
|
return <Input {...inputProps} ref={this.saveInput} />;
|
||||||
},
|
},
|
||||||
};
|
});
|
|
@ -1,3 +1,4 @@
|
||||||
|
import {PropType, VNode} from 'vue';
|
||||||
import ResizeObserver from '../vc-resize-observer';
|
import ResizeObserver from '../vc-resize-observer';
|
||||||
import omit from 'omit.js';
|
import omit from 'omit.js';
|
||||||
import classNames from '../_util/classNames';
|
import classNames from '../_util/classNames';
|
||||||
|
@ -6,22 +7,28 @@ import raf from '../_util/raf';
|
||||||
import warning from '../_util/warning';
|
import warning from '../_util/warning';
|
||||||
import BaseMixin from '../_util/BaseMixin';
|
import BaseMixin from '../_util/BaseMixin';
|
||||||
import inputProps from './inputProps';
|
import inputProps from './inputProps';
|
||||||
import PropTypes, { withUndefined } from '../_util/vue-types';
|
import PropTypes from '../_util/vue-types';
|
||||||
import { getOptionProps } from '../_util/props-util';
|
import { getOptionProps } from '../_util/props-util';
|
||||||
import { withDirectives } from 'vue';
|
import { defineComponent, withDirectives } from 'vue';
|
||||||
import antInput from '../_util/antInputDirective';
|
import antInput from '../_util/antInputDirective';
|
||||||
|
|
||||||
const RESIZE_STATUS_NONE = 0;
|
const RESIZE_STATUS_NONE = 0;
|
||||||
const RESIZE_STATUS_RESIZING = 1;
|
const RESIZE_STATUS_RESIZING = 1;
|
||||||
const RESIZE_STATUS_RESIZED = 2;
|
const RESIZE_STATUS_RESIZED = 2;
|
||||||
|
|
||||||
|
export interface AutoSizeType {
|
||||||
|
minRows?: number;
|
||||||
|
maxRows?: number;
|
||||||
|
}
|
||||||
|
|
||||||
const TextAreaProps = {
|
const TextAreaProps = {
|
||||||
...inputProps,
|
...inputProps,
|
||||||
autosize: withUndefined(PropTypes.oneOfType([Object, Boolean])),
|
autosize: { type: [Boolean, Object] as PropType<AutoSizeType>, default: undefined},
|
||||||
autoSize: withUndefined(PropTypes.oneOfType([Object, Boolean])),
|
autoSize: {type: [Boolean, Object] as PropType<AutoSizeType>, default: undefined},
|
||||||
onResize: PropTypes.func,
|
onResize: PropTypes.func,
|
||||||
};
|
};
|
||||||
const ResizableTextArea = {
|
|
||||||
|
const ResizableTextArea = defineComponent({
|
||||||
name: 'ResizableTextArea',
|
name: 'ResizableTextArea',
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: TextAreaProps,
|
props: TextAreaProps,
|
||||||
|
@ -39,6 +46,13 @@ const ResizableTextArea = {
|
||||||
raf.cancel(this.nextFrameActionId);
|
raf.cancel(this.nextFrameActionId);
|
||||||
raf.cancel(this.resizeFrameId);
|
raf.cancel(this.resizeFrameId);
|
||||||
},
|
},
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
nextFrameActionId: undefined,
|
||||||
|
textArea: null,
|
||||||
|
resizeFrameId: undefined,
|
||||||
|
}
|
||||||
|
},
|
||||||
watch: {
|
watch: {
|
||||||
value() {
|
value() {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
|
@ -47,10 +61,10 @@ const ResizableTextArea = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
saveTextArea(textArea) {
|
saveTextArea(textArea: any) {
|
||||||
this.textArea = textArea;
|
this.textArea = textArea;
|
||||||
},
|
},
|
||||||
handleResize(size) {
|
handleResize(size: any) {
|
||||||
const { resizeStatus } = this.$data;
|
const { resizeStatus } = this.$data;
|
||||||
|
|
||||||
if (resizeStatus !== RESIZE_STATUS_NONE) {
|
if (resizeStatus !== RESIZE_STATUS_NONE) {
|
||||||
|
@ -98,7 +112,7 @@ const ResizableTextArea = {
|
||||||
},
|
},
|
||||||
|
|
||||||
renderTextArea() {
|
renderTextArea() {
|
||||||
const props = { ...getOptionProps(this), ...this.$attrs };
|
const props: any = { ...getOptionProps(this), ...this.$attrs };
|
||||||
const { prefixCls, autoSize, autosize, disabled, class: className } = props;
|
const { prefixCls, autoSize, autosize, disabled, class: className } = props;
|
||||||
const { textareaStyles, resizeStatus } = this.$data;
|
const { textareaStyles, resizeStatus } = this.$data;
|
||||||
warning(
|
warning(
|
||||||
|
@ -131,7 +145,7 @@ const ResizableTextArea = {
|
||||||
? { overflowX: 'hidden', overflowY: 'hidden' }
|
? { overflowX: 'hidden', overflowY: 'hidden' }
|
||||||
: null),
|
: null),
|
||||||
};
|
};
|
||||||
const textareaProps = {
|
const textareaProps: any = {
|
||||||
...otherProps,
|
...otherProps,
|
||||||
style,
|
style,
|
||||||
class: cls,
|
class: cls,
|
||||||
|
@ -141,7 +155,7 @@ const ResizableTextArea = {
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<ResizeObserver onResize={this.handleResize} disabled={!(autoSize || autosize)}>
|
<ResizeObserver onResize={this.handleResize} disabled={!(autoSize || autosize)}>
|
||||||
{withDirectives(<textarea {...textareaProps} ref={this.saveTextArea} />, [[antInput]])}
|
{withDirectives(<textarea {...textareaProps} ref={this.saveTextArea} /> as VNode, [[antInput]])}
|
||||||
</ResizeObserver>
|
</ResizeObserver>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -150,6 +164,6 @@ const ResizableTextArea = {
|
||||||
render() {
|
render() {
|
||||||
return this.renderTextArea();
|
return this.renderTextArea();
|
||||||
},
|
},
|
||||||
};
|
});
|
||||||
|
|
||||||
export default ResizableTextArea;
|
export default ResizableTextArea;
|
|
@ -1,4 +1,4 @@
|
||||||
import { inject } from 'vue';
|
import { defineComponent, inject } from 'vue';
|
||||||
import classNames from '../_util/classNames';
|
import classNames from '../_util/classNames';
|
||||||
import { isMobile } from 'is-mobile';
|
import { isMobile } from 'is-mobile';
|
||||||
import Input from './Input';
|
import Input from './Input';
|
||||||
|
@ -12,22 +12,23 @@ import { getOptionProps, getComponent } from '../_util/props-util';
|
||||||
import { defaultConfigProvider } from '../config-provider';
|
import { defaultConfigProvider } from '../config-provider';
|
||||||
import isPlainObject from 'lodash-es/isPlainObject';
|
import isPlainObject from 'lodash-es/isPlainObject';
|
||||||
|
|
||||||
export default {
|
export default defineComponent({
|
||||||
name: 'AInputSearch',
|
name: 'AInputSearch',
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: {
|
props: {
|
||||||
...inputProps,
|
...inputProps,
|
||||||
// 不能设置默认值 https://github.com/vueComponent/ant-design-vue/issues/1916
|
// 不能设置默认值 https://github.com/vueComponent/ant-design-vue/issues/1916
|
||||||
enterButton: PropTypes.any,
|
enterButton: PropTypes.VNodeChild,
|
||||||
onSearch: PropTypes.func,
|
onSearch: PropTypes.func,
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
return {
|
return {
|
||||||
configProvider: inject('configProvider', defaultConfigProvider),
|
configProvider: inject('configProvider', defaultConfigProvider),
|
||||||
|
input: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
saveInput(node) {
|
saveInput(node: any) {
|
||||||
this.input = node;
|
this.input = node;
|
||||||
},
|
},
|
||||||
handleChange(e) {
|
handleChange(e) {
|
||||||
|
@ -53,7 +54,7 @@ export default {
|
||||||
blur() {
|
blur() {
|
||||||
this.input.blur();
|
this.input.blur();
|
||||||
},
|
},
|
||||||
renderLoading(prefixCls) {
|
renderLoading(prefixCls: string) {
|
||||||
const { size } = this.$props;
|
const { size } = this.$props;
|
||||||
let enterButton = getComponent(this, 'enterButton');
|
let enterButton = getComponent(this, 'enterButton');
|
||||||
// 兼容 <a-input-search enterButton />, 因enterButton类型为 any,此类写法 enterButton 为空字符串
|
// 兼容 <a-input-search enterButton />, 因enterButton类型为 any,此类写法 enterButton 为空字符串
|
||||||
|
@ -67,7 +68,7 @@ export default {
|
||||||
}
|
}
|
||||||
return <LoadingOutlined class={`${prefixCls}-icon`} key="loadingIcon" />;
|
return <LoadingOutlined class={`${prefixCls}-icon`} key="loadingIcon" />;
|
||||||
},
|
},
|
||||||
renderSuffix(prefixCls) {
|
renderSuffix(prefixCls: string) {
|
||||||
const { loading } = this;
|
const { loading } = this;
|
||||||
const suffix = getComponent(this, 'suffix');
|
const suffix = getComponent(this, 'suffix');
|
||||||
let enterButton = getComponent(this, 'enterButton');
|
let enterButton = getComponent(this, 'enterButton');
|
||||||
|
@ -95,7 +96,7 @@ export default {
|
||||||
|
|
||||||
return icon;
|
return icon;
|
||||||
},
|
},
|
||||||
renderAddonAfter(prefixCls) {
|
renderAddonAfter(prefixCls: string) {
|
||||||
const { size, disabled, loading } = this;
|
const { size, disabled, loading } = this;
|
||||||
const btnClassName = `${prefixCls}-button`;
|
const btnClassName = `${prefixCls}-button`;
|
||||||
let enterButton = getComponent(this, 'enterButton');
|
let enterButton = getComponent(this, 'enterButton');
|
||||||
|
@ -106,7 +107,7 @@ export default {
|
||||||
}
|
}
|
||||||
if (!enterButton) return addonAfter;
|
if (!enterButton) return addonAfter;
|
||||||
const enterButtonAsElement = Array.isArray(enterButton) ? enterButton[0] : enterButton;
|
const enterButtonAsElement = Array.isArray(enterButton) ? enterButton[0] : enterButton;
|
||||||
let button;
|
let button: any;
|
||||||
const isAntdButton =
|
const isAntdButton =
|
||||||
enterButtonAsElement.type &&
|
enterButtonAsElement.type &&
|
||||||
isPlainObject(enterButtonAsElement.type) &&
|
isPlainObject(enterButtonAsElement.type) &&
|
||||||
|
@ -146,7 +147,7 @@ export default {
|
||||||
size,
|
size,
|
||||||
class: className,
|
class: className,
|
||||||
...restProps
|
...restProps
|
||||||
} = { ...getOptionProps(this), ...this.$attrs };
|
} = { ...getOptionProps(this), ...this.$attrs } as any;
|
||||||
delete restProps.onSearch;
|
delete restProps.onSearch;
|
||||||
delete restProps.loading;
|
delete restProps.loading;
|
||||||
delete restProps.enterButton;
|
delete restProps.enterButton;
|
||||||
|
@ -159,7 +160,7 @@ export default {
|
||||||
let enterButton = getComponent(this, 'enterButton');
|
let enterButton = getComponent(this, 'enterButton');
|
||||||
const addonBefore = getComponent(this, 'addonBefore');
|
const addonBefore = getComponent(this, 'addonBefore');
|
||||||
enterButton = enterButton || enterButton === '';
|
enterButton = enterButton || enterButton === '';
|
||||||
let inputClassName;
|
let inputClassName: string;
|
||||||
if (enterButton) {
|
if (enterButton) {
|
||||||
inputClassName = classNames(prefixCls, className, {
|
inputClassName = classNames(prefixCls, className, {
|
||||||
[`${prefixCls}-enter-button`]: !!enterButton,
|
[`${prefixCls}-enter-button`]: !!enterButton,
|
||||||
|
@ -183,4 +184,4 @@ export default {
|
||||||
};
|
};
|
||||||
return <Input {...inputProps} ref={this.saveInput} />;
|
return <Input {...inputProps} ref={this.saveInput} />;
|
||||||
},
|
},
|
||||||
};
|
});
|
|
@ -1,4 +1,4 @@
|
||||||
import { inject } from 'vue';
|
import { defineComponent, inject } from 'vue';
|
||||||
import ClearableLabeledInput from './ClearableLabeledInput';
|
import ClearableLabeledInput from './ClearableLabeledInput';
|
||||||
import ResizableTextArea from './ResizableTextArea';
|
import ResizableTextArea from './ResizableTextArea';
|
||||||
import inputProps from './inputProps';
|
import inputProps from './inputProps';
|
||||||
|
@ -13,7 +13,7 @@ const TextAreaProps = {
|
||||||
autoSize: withUndefined(PropTypes.oneOfType([Object, Boolean])),
|
autoSize: withUndefined(PropTypes.oneOfType([Object, Boolean])),
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default defineComponent({
|
||||||
name: 'ATextarea',
|
name: 'ATextarea',
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: {
|
props: {
|
||||||
|
@ -22,6 +22,8 @@ export default {
|
||||||
setup() {
|
setup() {
|
||||||
return {
|
return {
|
||||||
configProvider: inject('configProvider', defaultConfigProvider),
|
configProvider: inject('configProvider', defaultConfigProvider),
|
||||||
|
resizableTextArea: null,
|
||||||
|
clearableInput: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
@ -45,7 +47,7 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
setValue(value, callback) {
|
setValue(value: any, callback?: Function) {
|
||||||
if (!hasProp(this, 'value')) {
|
if (!hasProp(this, 'value')) {
|
||||||
this.stateValue = value;
|
this.stateValue = value;
|
||||||
} else {
|
} else {
|
||||||
|
@ -55,22 +57,22 @@ export default {
|
||||||
callback && callback();
|
callback && callback();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleKeyDown(e) {
|
handleKeyDown(e: KeyboardEvent) {
|
||||||
if (e.keyCode === 13) {
|
if (e.keyCode === 13) {
|
||||||
this.$emit('pressEnter', e);
|
this.$emit('pressEnter', e);
|
||||||
}
|
}
|
||||||
this.$emit('keydown', e);
|
this.$emit('keydown', e);
|
||||||
},
|
},
|
||||||
triggerChange(e) {
|
triggerChange(e: Event) {
|
||||||
this.$emit('update:value', e.target.value);
|
this.$emit('update:value', (e.target as any).value);
|
||||||
this.$emit('change', e);
|
this.$emit('change', e);
|
||||||
this.$emit('input', e);
|
this.$emit('input', e);
|
||||||
},
|
},
|
||||||
handleChange(e) {
|
handleChange(e: Event) {
|
||||||
const { value, composing } = e.target;
|
const { value, composing, isComposing } = e.target as any;
|
||||||
if (((e.isComposing || composing) && this.lazy) || this.stateValue === value) return;
|
if (((isComposing || composing) && this.lazy) || this.stateValue === value) return;
|
||||||
|
|
||||||
this.setValue(e.target.value, () => {
|
this.setValue((e.target as any).value, () => {
|
||||||
this.resizableTextArea.resizeTextarea();
|
this.resizableTextArea.resizeTextarea();
|
||||||
});
|
});
|
||||||
resolveOnChange(this.resizableTextArea.textArea, e, this.triggerChange);
|
resolveOnChange(this.resizableTextArea.textArea, e, this.triggerChange);
|
||||||
|
@ -83,14 +85,14 @@ export default {
|
||||||
blur() {
|
blur() {
|
||||||
this.resizableTextArea.textArea.blur();
|
this.resizableTextArea.textArea.blur();
|
||||||
},
|
},
|
||||||
saveTextArea(resizableTextArea) {
|
saveTextArea(resizableTextArea: any) {
|
||||||
this.resizableTextArea = resizableTextArea;
|
this.resizableTextArea = resizableTextArea;
|
||||||
},
|
},
|
||||||
|
|
||||||
saveClearableInput(clearableInput) {
|
saveClearableInput(clearableInput: any) {
|
||||||
this.clearableInput = clearableInput;
|
this.clearableInput = clearableInput;
|
||||||
},
|
},
|
||||||
handleReset(e) {
|
handleReset(e: Event) {
|
||||||
this.setValue('', () => {
|
this.setValue('', () => {
|
||||||
this.resizableTextArea.renderTextArea();
|
this.resizableTextArea.renderTextArea();
|
||||||
this.focus();
|
this.focus();
|
||||||
|
@ -98,7 +100,7 @@ export default {
|
||||||
resolveOnChange(this.resizableTextArea.textArea, e, this.triggerChange);
|
resolveOnChange(this.resizableTextArea.textArea, e, this.triggerChange);
|
||||||
},
|
},
|
||||||
|
|
||||||
renderTextArea(prefixCls) {
|
renderTextArea(prefixCls: string) {
|
||||||
const props = getOptionProps(this);
|
const props = getOptionProps(this);
|
||||||
const resizeProps = {
|
const resizeProps = {
|
||||||
...props,
|
...props,
|
||||||
|
@ -116,7 +118,7 @@ export default {
|
||||||
const getPrefixCls = this.configProvider.getPrefixCls;
|
const getPrefixCls = this.configProvider.getPrefixCls;
|
||||||
const prefixCls = getPrefixCls('input', customizePrefixCls);
|
const prefixCls = getPrefixCls('input', customizePrefixCls);
|
||||||
|
|
||||||
const props = {
|
const props: any = {
|
||||||
...getOptionProps(this),
|
...getOptionProps(this),
|
||||||
...this.$attrs,
|
...this.$attrs,
|
||||||
prefixCls,
|
prefixCls,
|
||||||
|
@ -127,4 +129,4 @@ export default {
|
||||||
};
|
};
|
||||||
return <ClearableLabeledInput {...props} ref={this.saveClearableInput} />;
|
return <ClearableLabeledInput {...props} ref={this.saveClearableInput} />;
|
||||||
},
|
},
|
||||||
};
|
});
|
|
@ -35,12 +35,20 @@ const SIZING_STYLE = [
|
||||||
'box-sizing',
|
'box-sizing',
|
||||||
];
|
];
|
||||||
|
|
||||||
const computedStyleCache = {};
|
export interface NodeType {
|
||||||
let hiddenTextarea;
|
sizingStyle: string;
|
||||||
|
paddingSize: number;
|
||||||
|
borderSize: number;
|
||||||
|
boxSizing: string;
|
||||||
|
}
|
||||||
|
|
||||||
export function calculateNodeStyling(node, useCache = false) {
|
const computedStyleCache: { [key: string]: NodeType } = {};
|
||||||
const nodeRef =
|
let hiddenTextarea: HTMLTextAreaElement;
|
||||||
node.getAttribute('id') || node.getAttribute('data-reactid') || node.getAttribute('name');
|
|
||||||
|
export function calculateNodeStyling(node: HTMLElement, useCache = false) {
|
||||||
|
const nodeRef = (node.getAttribute('id') ||
|
||||||
|
node.getAttribute('data-reactid') ||
|
||||||
|
node.getAttribute('name')) as string;
|
||||||
|
|
||||||
if (useCache && computedStyleCache[nodeRef]) {
|
if (useCache && computedStyleCache[nodeRef]) {
|
||||||
return computedStyleCache[nodeRef];
|
return computedStyleCache[nodeRef];
|
||||||
|
@ -63,7 +71,7 @@ export function calculateNodeStyling(node, useCache = false) {
|
||||||
|
|
||||||
const sizingStyle = SIZING_STYLE.map(name => `${name}:${style.getPropertyValue(name)}`).join(';');
|
const sizingStyle = SIZING_STYLE.map(name => `${name}:${style.getPropertyValue(name)}`).join(';');
|
||||||
|
|
||||||
const nodeInfo = {
|
const nodeInfo: NodeType = {
|
||||||
sizingStyle,
|
sizingStyle,
|
||||||
paddingSize,
|
paddingSize,
|
||||||
borderSize,
|
borderSize,
|
||||||
|
@ -78,10 +86,10 @@ export function calculateNodeStyling(node, useCache = false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function calculateNodeHeight(
|
export default function calculateNodeHeight(
|
||||||
uiTextNode,
|
uiTextNode: HTMLTextAreaElement,
|
||||||
useCache = false,
|
useCache = false,
|
||||||
minRows = null,
|
minRows: number | null = null,
|
||||||
maxRows = null,
|
maxRows: number | null = null,
|
||||||
) {
|
) {
|
||||||
if (!hiddenTextarea) {
|
if (!hiddenTextarea) {
|
||||||
hiddenTextarea = document.createElement('textarea');
|
hiddenTextarea = document.createElement('textarea');
|
||||||
|
@ -91,7 +99,7 @@ export default function calculateNodeHeight(
|
||||||
// Fix wrap="off" issue
|
// Fix wrap="off" issue
|
||||||
// https://github.com/ant-design/ant-design/issues/6577
|
// https://github.com/ant-design/ant-design/issues/6577
|
||||||
if (uiTextNode.getAttribute('wrap')) {
|
if (uiTextNode.getAttribute('wrap')) {
|
||||||
hiddenTextarea.setAttribute('wrap', uiTextNode.getAttribute('wrap'));
|
hiddenTextarea.setAttribute('wrap', uiTextNode.getAttribute('wrap') as string);
|
||||||
} else {
|
} else {
|
||||||
hiddenTextarea.removeAttribute('wrap');
|
hiddenTextarea.removeAttribute('wrap');
|
||||||
}
|
}
|
||||||
|
@ -112,7 +120,7 @@ export default function calculateNodeHeight(
|
||||||
let minHeight = Number.MIN_SAFE_INTEGER;
|
let minHeight = Number.MIN_SAFE_INTEGER;
|
||||||
let maxHeight = Number.MAX_SAFE_INTEGER;
|
let maxHeight = Number.MAX_SAFE_INTEGER;
|
||||||
let height = hiddenTextarea.scrollHeight;
|
let height = hiddenTextarea.scrollHeight;
|
||||||
let overflowY;
|
let overflowY: any;
|
||||||
|
|
||||||
if (boxSizing === 'border-box') {
|
if (boxSizing === 'border-box') {
|
||||||
// border-box: add border, since height = content + padding + border
|
// border-box: add border, since height = content + padding + border
|
|
@ -3,6 +3,7 @@ import Group from './Group';
|
||||||
import Search from './Search';
|
import Search from './Search';
|
||||||
import TextArea from './TextArea';
|
import TextArea from './TextArea';
|
||||||
import Password from './Password';
|
import Password from './Password';
|
||||||
|
import { App } from 'vue';
|
||||||
|
|
||||||
Input.Group = Group;
|
Input.Group = Group;
|
||||||
Input.Search = Search;
|
Input.Search = Search;
|
||||||
|
@ -10,7 +11,7 @@ Input.TextArea = TextArea;
|
||||||
Input.Password = Password;
|
Input.Password = Password;
|
||||||
|
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
Input.install = function(app) {
|
Input.install = function(app: App) {
|
||||||
app.component(Input.name, Input);
|
app.component(Input.name, Input);
|
||||||
app.component(Input.Group.name, Input.Group);
|
app.component(Input.Group.name, Input.Group);
|
||||||
app.component(Input.Search.name, Input.Search);
|
app.component(Input.Search.name, Input.Search);
|
||||||
|
@ -19,4 +20,9 @@ Input.install = function(app) {
|
||||||
return app;
|
return app;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Input;
|
export default Input as typeof Input & {
|
||||||
|
readonly Group: typeof Group;
|
||||||
|
readonly Search: typeof Search;
|
||||||
|
readonly TextArea: typeof TextArea;
|
||||||
|
readonly Password: typeof Password;
|
||||||
|
};
|
|
@ -1,35 +1,26 @@
|
||||||
|
import { tuple } from '../_util/type';
|
||||||
|
import { PropType } from 'vue';
|
||||||
import PropTypes from '../_util/vue-types';
|
import PropTypes from '../_util/vue-types';
|
||||||
export default {
|
export default {
|
||||||
prefixCls: PropTypes.string,
|
prefixCls: PropTypes.string,
|
||||||
inputPrefixCls: PropTypes.string,
|
inputPrefixCls: PropTypes.string,
|
||||||
defaultValue: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
defaultValue: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||||
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||||
placeholder: [String, Number],
|
placeholder: {
|
||||||
type: {
|
type: [String, Number] as PropType<string | number>,
|
||||||
default: 'text',
|
|
||||||
type: String,
|
|
||||||
},
|
},
|
||||||
name: String,
|
type: PropTypes.string.def('text'),
|
||||||
size: PropTypes.oneOf(['small', 'large', 'default']),
|
name: PropTypes.string,
|
||||||
|
size: PropTypes.oneOf(tuple('small', 'large', 'default')),
|
||||||
disabled: PropTypes.looseBool,
|
disabled: PropTypes.looseBool,
|
||||||
readonly: PropTypes.looseBool,
|
readonly: PropTypes.looseBool,
|
||||||
addonBefore: PropTypes.any,
|
addonBefore: PropTypes.VNodeChild,
|
||||||
addonAfter: PropTypes.any,
|
addonAfter: PropTypes.VNodeChild,
|
||||||
// onPressEnter?: React.FormEventHandler<any>;
|
prefix: PropTypes.VNodeChild,
|
||||||
// onKeyDown?: React.FormEventHandler<any>;
|
suffix: PropTypes.VNodeChild,
|
||||||
// onChange?: React.ChangeEventHandler<HTMLInputElement>;
|
|
||||||
// onClick?: React.FormEventHandler<any>;
|
|
||||||
// onFocus?: React.FormEventHandler<any>;
|
|
||||||
// onBlur?: React.FormEventHandler<any>;
|
|
||||||
prefix: PropTypes.any,
|
|
||||||
suffix: PropTypes.any,
|
|
||||||
// spellCheck: Boolean,
|
|
||||||
autofocus: PropTypes.looseBool,
|
autofocus: PropTypes.looseBool,
|
||||||
allowClear: PropTypes.looseBool,
|
allowClear: PropTypes.looseBool,
|
||||||
lazy: {
|
lazy: PropTypes.looseBool.def(true),
|
||||||
default: true,
|
|
||||||
type: Boolean,
|
|
||||||
},
|
|
||||||
maxlength: PropTypes.number,
|
maxlength: PropTypes.number,
|
||||||
loading: PropTypes.looseBool,
|
loading: PropTypes.looseBool,
|
||||||
onPressEnter: PropTypes.func,
|
onPressEnter: PropTypes.func,
|
Loading…
Reference in New Issue