Skip to main content
The TypingIndicator component displays an animated three-dot indicator to show when a contact is typing a message. It uses CSS animations for smooth, staggered bouncing effects.

Location

components/chat/typing-indicator.tsx

Props

label
string
default:"typing"
Accessible label for screen readers

Features

Animated bouncing dots

The component renders three dots that bounce in sequence with staggered timing:
components/chat/typing-indicator.tsx
{dots.map((dot) => (
  <span
    key={dot}
    className="block h-1.5 w-1.5 animate-bounce rounded-full bg-accent"
    style={{ animationDelay: `${dot * 0.12}s` }}
  />
))}
Each dot has a delay of 0.12s * its index, creating a wave effect:
  • Dot 0: 0s delay
  • Dot 1: 0.12s delay
  • Dot 2: 0.24s delay

Accessibility

The component includes proper ARIA attributes for screen readers:
components/chat/typing-indicator.tsx
<div
  className="inline-flex items-center gap-2 rounded-full bg-black/5 px-3 py-1 text-xs font-medium text-muted-foreground"
  aria-live="polite"
  aria-label={`${label} indicator`}
>
  <span className="sr-only">{label}</span>
  {/* dots */}
</div>
  • aria-live="polite": Announces changes to screen readers without interrupting
  • aria-label: Provides context about what the indicator means
  • .sr-only: Hidden text label for screen readers

Memoization

The component is wrapped in React.memo to prevent unnecessary re-renders:
components/chat/typing-indicator.tsx
export const TypingIndicator = memo(TypingIndicatorComponent)
TypingIndicator.displayName = "TypingIndicator"

Usage

import { TypingIndicator } from "@/components/chat/typing-indicator"

function MessageList({ isTyping, contactName }) {
  return (
    <div>
      {/* messages */}
      {isTyping && (
        <div className="px-4">
          <TypingIndicator label={`${contactName} is typing`} />
        </div>
      )}
    </div>
  )
}

Styling

The indicator uses these Tailwind classes for styling:
  • bg-black/5: Semi-transparent background
  • rounded-full: Fully rounded pill shape
  • px-3 py-1: Comfortable padding
  • text-xs font-medium: Small, medium-weight text
  • text-muted-foreground: Subtle text color
  • bg-accent: Dots use the primary accent color

Animation timing

The animation creates a smooth wave effect:
  1. Each dot uses Tailwind’s animate-bounce utility
  2. Custom animationDelay staggers the start time
  3. Total cycle: ~0.36s for all three dots to complete one bounce sequence
The 0.12s delay creates a natural-looking wave. Adjust this value to speed up or slow down the wave effect.
  • MessageList - Renders the typing indicator as a footer
  • ChatPanel - Manages typing state via the store

Build docs developers (and LLMs) love