ldc-loue/resources/ts/components/bo/InputTextAutoComponent.vue
2022-07-04 10:17:34 +00:00

97 lines
2.2 KiB
Vue

<template>
<WordCounter :id="_id" />
<textarea
ref="textarea"
:id="_id"
:class="`inputTextAutoComponent ${_class}`"
:name="_name"
:aria-describedby="_ariaDescribedby"
:placeholder="_placeholder"
:required="_required"
v-on:input="onInput"
:json="'{}'"
>{{ _value }}</textarea
>
</template>
<script lang="ts">
import { defineComponent, onMounted, ref } from "vue";
import trans from "../../modules/trans";
import WordCounter from "./WordCounterComponent.vue";
const textarea = ref<HTMLTextAreaElement | null>(null);
export default defineComponent({
inheritAttrs: false,
mixins: [trans],
components: {
WordCounter,
},
setup() {
return { textarea };
},
beforeMount() {
if (!this.$attrs.json) {
throw new Error("this component requires json");
}
},
mounted() {
const json = String(this.$attrs.json ?? "{}"),
data = JSON.parse(json);
this._id = String(data.id);
this._class = String(data.class);
this._name = String(data.name);
this._placeholder = String(data.placeholder);
this._ariaDescribedby = String(data.ariaDescribedby);
this._value = String(data.value);
if (data.required) {
this._required = true;
}
if (this.textarea) {
// Default input init
this.textarea.setAttribute("style", `height: 1rem;overflow-y: hidden;`);
}
// * Init input
this.$nextTick(this.onInput);
},
data(): {
_id: string;
_class: string;
_name: string;
_placeholder: string;
_ariaDescribedby: string;
_required: boolean;
_value: string;
_textarea: HTMLTextAreaElement | null;
} {
return {
_id: "",
_class: "",
_name: "",
_placeholder: "",
_ariaDescribedby: "",
_required: false,
_value: "",
_textarea: null,
};
},
methods: {
onInput() {
const el = textarea.value;
if (!el) {
throw new Error("undefined textarea element");
}
// * Remove every new line char
el.value = el.value.replace(/[\n\r]/, "");
el.style.height = "auto";
el.style.height = `${el.scrollHeight}px`;
},
},
});
</script>
<style lang="scss">
.inputTextAutoComponent {
resize: none;
}
</style>