ldc-volena/resources/ts/bo/components/InputTextAutoComponent.vue
Jérémy Munsch bc18f01f3e
bump ts code
2024-06-19 16:28:34 +02:00

104 lines
2.5 KiB
Vue

<template>
<WordCounter
:id="id"
class="ck-word-count"
/>
<textarea
ref="textarea"
:id="id"
:class="`input-text-auto-component ${classPath}`"
:name="name"
:aria-describedby="ariaDescribedby"
:placeholder="placeholder"
:required="required"
@input="styleElement(checkInput())"
@blur="onBlur"
v-model="value"
/>
</template>
<script lang="ts" setup>
import { computed, nextTick, onBeforeMount, onMounted, ref, useAttrs } from "vue";
import WordCounter from "./WordCounterComponent.vue";
defineOptions({
name: "InputTextAutoComponent"
});
// * ATTRIBUTES
const attrs = useAttrs();
// * REFS
const textarea = ref<HTMLTextAreaElement|null>(null);
// * DATA
/** Hack to set the id for wordCounterComponent. */
const id = ref<string>(JSON.parse(String(attrs.json ?? "{}")).id);
const classPath = ref<string>("");
const name = ref<string>("");
const placeholder = ref<string>("");
const ariaDescribedby = ref<string>("");
const value = ref<string>("");
const required = ref<boolean>(true);
// * COMPUTED
const isUsedWithProps = computed<boolean>(() => attrs.json === undefined);
onBeforeMount(() => {
if (isUsedWithProps.value) {
throw new Error("this component requires json");
}
});
// * LIFECYCLE
onMounted(() => {
const json = String(attrs.json ?? "{}"),
data = JSON.parse(json);
if (!isUsedWithProps.value) {
id.value = String(data.id);
classPath.value = String(data.class);
name.value = String(data.name);
placeholder.value = String(data.placeholder);
ariaDescribedby.value = String(data.ariaDescribedby);
value.value = String(data.value);
required.value = data.required;
textarea.value?.setAttribute("style", "height:1rem;overflow-y:hidden;");
}
nextTick(() => {
styleElement(checkInput());
});
});
// * METHODS
/** When the textarea get the focus. */
function onBlur() {
const el = checkInput();
/** Remove every new line char */
el.value = el.value.replace(/[\n\r]/g, "");
nextTick(() => {
styleElement(el);
});
}
/** Check if the element is an HTMLTextAreaElement. */
function checkInput(): HTMLTextAreaElement {
const el = textarea.value;
if (!el) {
throw new Error("undefined textarea element");
}
return el;
}
/** Style the textarea element. */
function styleElement(el: HTMLTextAreaElement): void {
el.style.height = "auto";
el.style.height = `${el.scrollHeight}px`;
}
</script>
<style lang="scss" scopped>
.input-text-auto-component {
resize: none;
}
</style>