ldc-loue/resources/ts/components/bo/WordCounterComponent.vue
2022-06-12 16:38:22 +02:00

105 lines
2.2 KiB
Vue

<template>
<div class="wordCounter">
<span class="words"
><u>{{ __("Mots") }}</u
>&nbsp;:&nbsp;<b>{{ words }}</b></span
>
<span class="chars"
><u>{{ __("Caractères") }}</u
>&nbsp;:&nbsp;<b>{{ chars }}</b></span
>
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import trans from "../../modules/trans";
export default defineComponent({
mixins: [trans],
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 = data.id;
},
data(): {
id: string;
words: number;
chars: number;
input: HTMLInputElement | null;
} {
return {
id: "",
words: 0,
chars: 0,
input: null,
};
},
watch: {
id() {
if (!this.id) {
throw new Error("Missing ID");
}
const input = document.getElementById(this.id);
if (!input) {
throw new Error(`Input ${this.id} could not be found`);
}
},
input() {
if (!this.input) {
throw new Error("input has to be set");
}
if (this.input && !(this.input instanceof HTMLInputElement)) {
throw new Error("input as to be HTMLInputElement");
}
this.input.addEventListener("input", (e) => {
const el = e.target;
if (!el || !(el instanceof HTMLInputElement)) {
throw new Error();
}
this.updateValues(el.value);
});
this.updateValues(this.input.value);
},
},
methods: {
updateValues(string: string) {
let chars, words;
[words, chars] = this.calculateValues(string);
this.words = words;
this.chars = chars;
},
calculateValues(string: string) {
const arr = string.split(" ");
return [arr.filter((word) => word !== "").length, string.length];
},
},
});
</script>
<style lang="scss">
.wordCounter {
display: inline-block;
color: initial;
border: 1px solid rgb(196, 196, 196);
border-bottom: 0;
background-color: #fafafa;
position: relative;
width: 100%;
.words {
position: relative;
left: 2rem;
}
.chars {
position: absolute;
left: 9rem;
}
}
</style>