97 lines
2.2 KiB
Vue
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>
|