Chatwoot/app/javascript/shared/components/ResizableTextArea.vue
2022-12-22 14:14:30 -08:00

91 lines
1.6 KiB
Vue

<template>
<textarea
ref="textarea"
:placeholder="placeholder"
:value="value"
@input="onInput"
@focus="onFocus"
@keyup="onKeyup"
@blur="onBlur"
/>
</template>
<script>
const TYPING_INDICATOR_IDLE_TIME = 4000;
export default {
props: {
placeholder: {
type: String,
default: '',
},
value: {
type: String,
default: '',
},
minHeight: {
type: Number,
default: 2,
},
},
data() {
return {
idleTimer: null,
};
},
watch: {
value() {
this.resizeTextarea();
},
},
mounted() {
this.$nextTick(() => {
if (this.value) {
this.resizeTextarea();
}
});
},
methods: {
resizeTextarea() {
if (!this.value) {
this.$el.style.height = `${this.minHeight}rem`;
} else {
this.$el.style.height = `${this.$el.scrollHeight}px`;
}
},
onInput(event) {
this.$emit('input', event.target.value);
this.resizeTextarea();
},
resetTyping() {
this.$emit('typing-off');
this.idleTimer = null;
},
turnOffIdleTimer() {
if (this.idleTimer) {
clearTimeout(this.idleTimer);
}
},
onKeyup() {
if (!this.idleTimer) {
this.$emit('typing-on');
}
this.turnOffIdleTimer();
this.idleTimer = setTimeout(
() => this.resetTyping(),
TYPING_INDICATOR_IDLE_TIME
);
},
onBlur() {
this.turnOffIdleTimer();
this.resetTyping();
this.$emit('blur');
},
onFocus() {
this.$emit('focus');
},
focus() {
this.$refs.textarea.focus();
},
},
};
</script>