evcc-io/assets/js/components/Helper/AnimatedNumber.vue
Maschga 8f114dca96
chore: Typescript: Rewrite Savings (#21019)
Co-authored-by: Michael Geers <michael@geers.tv>
2025-05-15 23:55:27 +02:00

66 lines
1.4 KiB
Vue

<template>
<span />
</template>
<script lang="ts">
import { CountUp } from "countup.js";
import { defineComponent, type PropType } from "vue";
import type { Timeout } from "@/types/evcc";
const DURATION = 0.5;
export default defineComponent({
name: "AnimatedNumber",
props: {
to: { type: [String, Number], default: 0 },
format: { type: Function as PropType<(n: number) => string>, required: true },
duration: { type: Number, default: DURATION },
},
data() {
return {
instance: null as CountUp | null,
timeout: null as Timeout | null,
};
},
watch: {
to(value) {
this.update(value);
},
},
mounted() {
if (this.instance) {
return;
}
this.instance = new CountUp(this.$el, Number(this.to), {
startVal: Number(this.to),
formattingFn: this.format,
duration: this.duration,
decimalPlaces: 3,
});
if (this.instance.error) {
console.error(this.instance.error);
}
},
unmounted() {
this.instance = null;
if (this.timeout !== null) {
clearTimeout(this.timeout);
}
},
methods: {
forceUpdate() {
this.instance?.reset();
this.update(Number(this.to));
},
update(value: number) {
// debounced to avoid rendering issues
// @see https://github.com/inorganik/countUp.js/issues/330#issuecomment-2697595198
if (this.timeout !== null) {
clearTimeout(this.timeout);
}
this.timeout = setTimeout(() => {
this.instance?.update(value);
}, 100);
},
},
});
</script>