A React Native component that provides an auto-resizing text input with animated expansion, similar to modern messaging apps like iMessage or WhatsApp.
- π Auto-resizing: Container grows upward as you type multiple lines
- π¬ Smooth animations: Built with React Native Reanimated for 60fps performance
- π± Cross-platform: Works on iOS, Android, and Web
- π― Send button: Adaptive button that changes color based on input state
- π§ Action icons: Four customizable action buttons (attach, rocket, magic, science)
- β¨οΈ Keyboard shortcuts: Enter to send, Shift+Enter for new line (Web)
- π¨ Modern UI: Dark theme with Tailwind CSS styling
- π TypeScript: Fully typed with TypeScript support
| Platform | Status | Notes |
|---|---|---|
| iOS | β Full Support | Native animations, keyboard handling |
| Android | β Full Support | Native animations, keyboard handling |
| Web | β Full Support | Keyboard shortcuts, focus management |
| Dependency | Version | Required |
|---|---|---|
| Expo SDK | 53.0.0+ | β |
| React Native | 0.79+ | β |
| React Native Reanimated | 3.17+ | β |
| Expo Vector Icons | 14.0+ | β |
| Tailwind CSS (NativeWind) | Latest | β |
| TypeScript | 5.8+ | β |
| React DOM | 19.0.0 | β (Web only) |
| React Native Web | 0.20+ | β (Web only) |
# Install core dependencies
npm install react-native-reanimated @expo/vector-icons
# For web support (optional)
npm install react-native-web react-dom@19.0.0 --legacy-peer-depsimport AutoResizingInput from './components/AutoResizingInput';
export default function App() {
const handleSend = (text: string) => {
console.log('Message sent:', text);
// Handle your message sending logic here
};
return (
<View style={{ flex: 1, justifyContent: 'flex-end' }}>
<AutoResizingInput
onSend={handleSend}
placeholder="Type your message..."
/>
</View>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
onSend |
(text: string) => void |
undefined |
Callback function called when send button is pressed |
placeholder |
string |
"Type your message..." |
Placeholder text for the input field |
- Calculates height based on number of lines (
\ncharacters) - Each line = 20px height
- Container height = input height + 80px (for padding and action bar)
- Uses
justify-endto ensure expansion goes upward
- Built with React Native Reanimated's
useSharedValueanduseAnimatedStyle - Send button has a subtle scale animation when pressed
- Container height changes are smooth and native
- Touch-optimized interactions
- Native keyboard handling
- Smooth 60fps animations
- Enter to send message
- Shift+Enter for new line
- Click anywhere in input area to focus
- No focus outline for clean design
The component uses Tailwind CSS (NativeWind) classes:
| Element | Classes | Description |
|---|---|---|
| Container | bg-zinc-900 border-zinc-700 rounded-2xl |
Dark theme with rounded corners |
| Input | text-white text-base |
White text, standard size |
| Send Button | bg-white / bg-zinc-700 |
White when active, gray when disabled |
| Icons | text-gray-400 |
Subtle gray icons |
Recommended setup in your main App component:
import {
KeyboardAvoidingView,
TouchableWithoutFeedback,
Keyboard,
Platform
} from 'react-native';
export default function App() {
return (
<SafeAreaView style={{ flex: 1 }}>
<KeyboardAvoidingView
style={{ flex: 1 }}
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
>
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={{ flex: 1, justifyContent: 'flex-end' }}>
<AutoResizingInput onSend={handleSend} />
</View>
</TouchableWithoutFeedback>
</KeyboardAvoidingView>
</SafeAreaView>
);
}For web deployment, ensure you have:
# Install web dependencies
npm install react-native-web react-dom@19.0.0 @expo/metro-runtime --legacy-peer-deps
# Start web development server
npx expo start --webModify the Tailwind classes in the component:
// Container background
className="bg-zinc-900" // Change to your preferred color
// Send button active state
className="bg-white" // Change to your brand colorModify the line height calculation:
const newInputHeight = lineCount * 25; // Change from 20 to 25 for taller lines- Page won't load: Check react-dom version is exactly 19.0.0
- Focus issues: Ensure you're clicking in the input area
- Animations laggy: This is expected, web performance is lower than native
- Keyboard covers input: Use KeyboardAvoidingView wrapper
- Animations choppy: Ensure Reanimated is properly installed
- Height not updating: Check if onContentSizeChange is firing
When contributing:
- Test on iOS, Android, and Web
- Ensure animations are smooth (60fps on mobile)
- Follow TypeScript patterns
- Update this README if adding features
MIT License - feel free to use in your projects!
Built with β€οΈ using React Native, Reanimated, and Tailwind CSS