import { defineComponent, inject, nextTick } from 'vue'; import ClearableLabeledInput from './ClearableLabeledInput'; import ResizableTextArea from './ResizableTextArea'; import inputProps from './inputProps'; import { hasProp, getOptionProps } from '../_util/props-util'; import { defaultConfigProvider } from '../config-provider'; import { fixControlledValue, resolveOnChange } from './Input'; import classNames from '../_util/classNames'; import PropTypes, { withUndefined } from '../_util/vue-types'; const TextAreaProps = { ...inputProps, autosize: withUndefined(PropTypes.oneOfType([Object, Boolean])), autoSize: withUndefined(PropTypes.oneOfType([Object, Boolean])), showCount: PropTypes.looseBool, onCompositionstart: PropTypes.func, onCompositionend: PropTypes.func, }; export default defineComponent({ name: 'ATextarea', inheritAttrs: false, props: { ...TextAreaProps, }, setup() { return { configProvider: inject('configProvider', defaultConfigProvider), resizableTextArea: null, clearableInput: null, }; }, data() { const value = typeof this.value === 'undefined' ? this.defaultValue : this.value; return { stateValue: typeof value === 'undefined' ? '' : value, }; }, watch: { value(val: string) { this.stateValue = val; }, }, mounted() { nextTick(() => { if (process.env.NODE_ENV === 'test') { if (this.autofocus) { this.focus(); } } }); }, methods: { setValue(value: string, callback?: Function) { if (!hasProp(this, 'value')) { this.stateValue = value; } else { this.$forceUpdate(); } nextTick(() => { callback && callback(); }); }, handleKeyDown(e: KeyboardEvent) { if (e.keyCode === 13) { this.$emit('pressEnter', e); } this.$emit('keydown', e); }, triggerChange(e: Event) { this.$emit('update:value', (e.target as any).value); this.$emit('change', e); this.$emit('input', e); }, handleChange(e: Event) { const { value, composing, isComposing } = e.target as any; if (((isComposing || composing) && this.lazy) || this.stateValue === value) return; this.setValue((e.target as HTMLTextAreaElement).value, () => { this.resizableTextArea?.resizeTextarea(); }); resolveOnChange(this.resizableTextArea.textArea, e, this.triggerChange); }, focus() { this.resizableTextArea.textArea.focus(); }, blur() { this.resizableTextArea.textArea.blur(); }, saveTextArea(resizableTextArea: any) { this.resizableTextArea = resizableTextArea; }, saveClearableInput(clearableInput: HTMLTextAreaElement) { this.clearableInput = clearableInput; }, handleReset(e: Event) { this.setValue('', () => { this.resizableTextArea.renderTextArea(); this.focus(); }); resolveOnChange(this.resizableTextArea.textArea, e, this.triggerChange); }, renderTextArea(prefixCls: string) { const props = getOptionProps(this); const { style, class: customClass } = this.$attrs; const resizeProps = { ...props, ...this.$attrs, style: !props.showCount && style, class: !props.showCount && customClass, showCount: null, prefixCls, onInput: this.handleChange, onChange: this.handleChange, onKeydown: this.handleKeyDown, }; return ; }, }, render() { const { stateValue, prefixCls: customizePrefixCls, maxlength, showCount } = this; const { style, class: customClass } = this.$attrs; const getPrefixCls = this.configProvider.getPrefixCls; const prefixCls = getPrefixCls('input', customizePrefixCls); let value = fixControlledValue(stateValue) as string; // Max length value const hasMaxlength = Number(maxlength) > 0; value = hasMaxlength ? value.slice(0, maxlength) : value; const props: any = { ...getOptionProps(this), ...this.$attrs, prefixCls, inputType: 'text', element: this.renderTextArea(prefixCls), handleReset: this.handleReset, }; let textareaNode = ( ); if (showCount) { const valueLength = [...value].length; const dataCount = `${valueLength}${hasMaxlength ? ` / ${maxlength}` : ''}`; textareaNode = (
{textareaNode}
); } return textareaNode; }, });