Works natively with Cursor. Add npx -y bare-ui-mcp to your MCP settings.

Typing Animation

A zero-dependency typing effect for text elements with a customizable blinking cursor, delays, and duration.

Installation

1. Copy the component into your project:

tsx
"use client";

import React, { useState, useEffect } from "react";

export interface TypingAnimationProps extends React.HTMLAttributes<HTMLSpanElement> {
  text: string;
  duration?: number;
  delay?: number;
  cursor?: boolean;
}

export const TypingAnimation = ({
  text,
  duration = 50,
  delay = 0,
  cursor = true,
  className = "",
  ...props
}: TypingAnimationProps) => {
  const [displayedText, setDisplayedText] = useState("");
  const [isStarted, setIsStarted] = useState(false);

  useEffect(() => {
    let timeout: NodeJS.Timeout;
    if (delay > 0) {
      timeout = setTimeout(() => setIsStarted(true), delay);
    } else {
      setIsStarted(true);
    }
    return () => clearTimeout(timeout);
  }, [delay]);

  useEffect(() => {
    if (!isStarted) return;

    let currentIndex = 0;
    const intervalId = setInterval(() => {
      setDisplayedText(text.slice(0, currentIndex + 1));
      currentIndex++;
      if (currentIndex === text.length) {
        clearInterval(intervalId);
      }
    }, duration);

    return () => clearInterval(intervalId);
  }, [text, duration, isStarted]);

  return (
    <span className={`bare-typing-animation ${className}`} {...props}>
      {displayedText}
      {cursor && (
        <span className="bare-typing-cursor" aria-hidden="true">
          |
        </span>
      )}
    </span>
  );
};

Usage

tsx
import { TypingAnimation } from "@/components/ui/typing-animation";

export default function MyComponent() {
  return (
    <TypingAnimation
      text="Hello, Bare UI!"
      duration={100}
      delay={500}
      cursor={true}
    />
  );
}