Skip to content
Native Animation
Typing to Message animation preview

This preview uses fictional demo content. See the props below for the customization options available in this component.

npx nativeanimation add typing-to-message
Glass

Typing to Message

A support chat where typing indicators morph into replies, with configurable reply copy, instruction steps, gradient colors, and fonts.

$9 for this animation

Add to your project

Copy the component and its assets into your app with the Native Animation CLI, or paste the agent prompt into Claude Code, Codex or Cursor once the MCP server is connected.

About this animation

A support chat where typing indicators morph into replies, with configurable reply copy, instruction steps, gradient colors, and fonts.

How it works

  1. One continuous Reanimated shared value drives the full conversation timeline.
  2. An invisible copy of the first reply measures its natural text size before the visible bubble expands.
  3. Spring segments morph the 56 × 36 typing surface into the measured message while its dots converge and dissolve.
  4. Each word fades upward on a 28 ms stagger, and the conversation follows the newest reply.
  5. Reduced Motion swaps spatial morphs and avatar nods for short opacity transitions.

Why this one

Most typing indicators disappear before a separate message pops in. This version preserves one physical surface from anticipation to answer, repeats that continuity for every reply, and pairs it with a structured support card and contextual action. The result feels connected instead of staged while remaining interruptible through one timeline.

Icons: Lucide (ISC).

Install

npx expo install expo-blur expo-linear-gradient @shopify/react-native-skia react-native-reanimated react-native-worklets

Usage

import { TypingToMessage } from './typing-to-message';

export function SupportChat() {
  return <TypingToMessage style={{ flex: 1 }} />;
}
import { useRef } from 'react';
import {
  TypingToMessage,
  type TypingToMessageRef,
} from './typing-to-message';

export function BrandedSupportChat() {
  const ref = useRef<TypingToMessageRef>(null);

  return (
    <TypingToMessage
      ref={ref}
      supportName="Nimbus Support"
      brandColors={['#7C5CFF', '#3B82F6']}
      firstReply="I can help with that. Let’s refresh the connection first."
      onSettingsPress={() => openSettings()}
    />
  );
}

Props

PropTypeDefaultDescription
supportNamestring'Support'Support team shown in the glass header.
agentNamestring'Jordan'Agent name shown above the response.
agentInitialsstring'JL'Initials rendered in the agent avatar.
userMessagestring'My files stopped syncing on my laptop.'Customer's opening message.
firstReplystring'I can help with that. Let’s refresh the sync connection first.'First agent response measured before the primary morph.
stepsTitlestring'Quick sync reset'Heading above the numbered troubleshooting steps.
stepsreadonly [string, string, string]['Pause syncing', 'Wait ten seconds', 'Resume and refresh']Three concise troubleshooting steps.
finalReplystring'That should reconnect this laptop. You can also review the sync folder.'Closing agent response.
linkLabelstring'Open sync settings'Label for the contextual settings action.
quickReplystring'Thanks, that fixed it!'Quick response inserted by the send button.
quickReplyResponsestring'Perfect — your files should stay in sync now.'Agent acknowledgment after the quick response.
placeholderstring'Message support…'Placeholder in the glass composer.
brandColorsreadonly [string, string]['#7C5CFF', '#3B82F6']Two-color brand gradient.
fontFamilystringundefinedMain interface font family.
mediumFontFamilystringundefinedMedium interface font family.
onQuickReply() => voidundefinedCalled after the quick response is inserted.
onSettingsPress() => voidundefinedCalled when the contextual settings action is pressed.
sendAccessibilityLabelstring'Send quick reply'Screen-reader label for the send action.
styleStyleProp<ViewStyle>undefinedOptional container style.
testIDstringundefinedOptional test identifier.

The forwarded ref exposes play(), reset(), and sendQuickReply().

Compatibility

  • Expo SDK 58, React Native 0.88, Reanimated 4.7, Worklets 0.13, and Skia 2.14.
  • iOS, Android, and web: supported
  • Runs in Expo Go because the native dependencies are bundled with Expo SDK 58.

Accessibility

The send control and settings link expose semantic roles and 44 pt minimum targets. Reduced Motion removes bubble morphs, scrolling translations, dot waves, and avatar nods while preserving short fades and the full conversational state change.

Customization notes

The typing and message phases share a coordinated timeline. There is no separate duration for one reduced-motion branch.