Vue 3 Typewriter Component
Feb 05, 2023 (1748 views)
Create the Typewriter component
Typewriter Com
Typewriter.vue
<script setup lang="ts">
// Vue 3.5+ - Reactive Prop Destructure
const {
data = [],
start = 1000,
enter = 60,
end = 1500,
leave = 30
} = defineProps<{
data: Array<string>;
start?: number;
enter?: number;
end?: number;
leave?: number;
}>();
const state = reactive({ text: '', complete: false, index: 0 });
addText();
function addText() {
if (state.text.length < data[state.index].length && !state.complete) {
state.text += data[state.index].charAt(state.text.length);
useTimeoutFn(addText, enter);
}
if (state.text.length === data[state.index].length) {
state.complete = true;
useTimeoutFn(removeText, end);
}
}
function removeText() {
if (state.text.length > 0) {
const t = state.text.split('');
t.pop();
state.text = t.join('');
useTimeoutFn(removeText, leave);
}
if (state.text.length === 0 && state.complete) {
state.complete = false;
if (state.index === data.length - 1) {
state.index = 0;
} else {
state.index++;
}
useTimeoutFn(addText, start);
}
}
</script>
<template>
<p
class="flex items-center text-lg h-5 animate-blink
border-r-2 border-transparent w-fit font-semibold dark:text-gray-200"
>
{{ state.text }}
</p>
</template>
Add blink animation to tailwind stylesheet
tailwind.css
/* tailwind 4+ */
@theme {
--animate-blink: blink 1s infinite;
@keyframes blink {
0% {
border-color: transparent;
}
45% {
border-color: transparent;
}
50% {
border-color: var(--color-gray-400);
}
100% {
border-color: var(--color-gray-400);
}
}
}
Usage
component.vue
<script>
const data = [
'Typewriter Component',
'Built with Vue 3, TypeScript, & Tailwind'
];
</script>
<template>
<Typewriter :data="data" />
</template>
Result
Typewriter Co