About this animation
A spring-grown AI composer with staggered suggestions, a rotating conic edge, and a luminous send transition.
How it works
- Focus drives one shared progress value that grows the composer, brightens its rotating edge, and reveals each suggestion with a short stagger.
- Attachment chips occupy a measured row above the input, and a spring expands the glass surface to make room without covering typed text.
- A sweep gradient renders the active edge in Skia on native platforms, with an equivalent conic treatment on web.
- Sending snapshots the current prompt, animates that copy upward, and expands a fading light pulse from the composer.
- The keyboard offset, attachment growth, active border, send flight, and busy indicator all stay on the UI thread.
Why this one
Most prompt fields stop at a growing text area and a loading icon. This one makes focus feel spatial: the surface opens, useful prompts arrive in sequence, and sending becomes a compact moment of transformation without turning the composer into a visual distraction.
Install
npx expo install react-native-reanimated react-native-worklets @shopify/react-native-skiaSkia on web also requires CanvasKit to be loaded before importing the component. Expo's Skia guide covers the required setup.
Usage
import { AiPromptBar } from './AiPromptBar';
<AiPromptBar onSend={(prompt) => submitPrompt(prompt)} />;With personality knobs and suggestions:
<AiPromptBar
accentColor="#8B7CFF"
attachments={[{ id: 'brief', label: 'Launch brief' }]}
fontFamily="Geist"
onRemoveAttachment={removeAttachment}
onSend={submitPrompt}
onSuggestionPress={trackSuggestion}
suggestions={['Distill the insight', 'Write a bold opening']}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | Controlled prompt text. |
defaultValue | string | '' | Initial text when uncontrolled. |
onChangeText | (value: string) => void | — | Called when the prompt changes. |
attachments | PromptAttachment[] | [] | Removable attachment chips. |
onRemoveAttachment | (id: string) => void | — | Called when an attachment is removed. |
onAddAttachment | () => void | — | Called from the add button. |
suggestions | string[] | Three writing prompts | Suggestions revealed on focus. |
onSuggestionPress | (suggestion: string) => void | — | Called after a suggestion fills the input. |
onSend | (text: string) => void | — | Called when a non-empty prompt is sent. |
busy | boolean | false | Replaces send with the stop control. |
onStop | () => void | — | Called from the stop control. |
accentColor | string | '#8B7CFF' | Active edge, glow, and action color. |
fontFamily | string | System | Font for the prompt and controls. |
style | StyleProp<ViewStyle> | — | Style for the outer container. |
accessibilityLabel | string | 'Message composer' | Label for the composer region. |
testID | string | — | Test identifier for the outer container. |
The forwarded ref exposes focus(), clear(), and send().
Compatibility
- Expo SDK 57
- React Native 0.86.3
- Reanimated 4.5.1 and React Native Worklets 0.10.1
- React Native Skia 2.6.2
- iOS: unverified
- Android: unverified
- Web: verified
- Expo Go: supported because Skia and Reanimated are included
Accessibility
Every action exposes a descriptive button label. Suggestions leave the accessibility tree while hidden. Reduced Motion replaces the spring growth, staggered movement, rotating edge, flying text, and expanding pulse with short opacity transitions.




