# Typing Indicator
URL: https://remocn.dev/docs/ui/components/typing-indicator

A motion atom that renders N bouncing dots driven directly by useCurrentFrame

- Install: `npx shadcn@latest add @remocn/typing-indicator`
- Vibe: clean
- Natural length: 90f @ 30fps

A motion atom that reads `useCurrentFrame` directly and produces N dots bouncing with staggered sine offsets. No state prop — the animation runs continuously as long as the component is mounted on the timeline. Drop it into any bubble or container to signal that a message is being composed.

## Installation

```bash
npx shadcn@latest add @remocn/typing-indicator
```

> **Note**
>
> `typing-indicator` is a motion atom — it reads the Remotion frame internally. Installing it pulls the shared `remocn-ui` core (`lib/remocn-ui/`) via `registryDependencies` (`["remocn-ui"]`). You do not need to install the core separately.

## Usage

Place `TypingIndicator` inside a `MessageBubble` (or any container) to show the typing state before a reply bubble enters:

```tsx
import { MessageBubble } from "@/components/remocn/message-bubble";
import { TypingIndicator } from "@/components/remocn/typing-indicator";

export const Scene = () => (
  <div style={{ position: "relative", width: "100%", height: "100%" }}>
    <MessageBubble variant="incoming" state="visible">
      <TypingIndicator />
    </MessageBubble>
  </div>
);
```

The helper `typingDotOffset(frame, index, opts)` is exported for cases where you want to drive individual dot positions from your own layout.

## Props

| Prop | Type | Default | Description |
|---|---|---|---|
| `dotCount` | `number` | `3` | Number of bouncing dots to render. |
| `color` | `string` | `"currentColor"` | Fill color of the dots. Inherits the parent text color by default. |
| `size` | `number` | `8` | Diameter of each dot in pixels. |
| `gap` | `number` | `5` | Horizontal gap between dots in pixels. |
| `amplitude` | `number` | `5` | Vertical bounce amplitude in pixels. |
| `speed` | `number` | `1` | Multiplier on the overall animation speed. Values above 1 speed up; below 1 slow down. |
| `cyclesPerSecond` | `number` | `1.1` | Number of full bounce cycles per second. |
| `className` | `string` | — | Optional className applied to the dots container element. |

## Use when
- Signalling that a reply or an answer is being composed — drop it inside a `message-bubble` or any container.
- You need a small continuous "working on it" motion that never resolves, tinted through `color`.
- You are timing the typing beat yourself in a `<Sequence>` instead of letting a flow block schedule it.

## Don't use when
- The wait is an async operation rather than a conversation — use `spinner`, or `skeleton` when the placeholder resolves to content.
- The dots should appear and disappear on a scripted conversation timeline — `chat-flow` and `imessage-chat-flow` already sequence them.
- You want a caret blinking at the end of typed text in a composer — use `caret`.