react-native-universal-keyboard-aware-scrollview
v1.0.6
Published
A universal keyboard-aware ScrollView for React Native that works correctly in normal screens, modals, and bottom sheets on both Android and iOS
Maintainers
Readme
react-native-universal-keyboard-aware-scrollview
A universal keyboard-aware ScrollView for React Native that automatically scrolls to keep the focused input visible when the keyboard appears.
✨ Features
- ✅ Single-line TextInput - Auto scroll when focused
- ✅ Multiline TextInput (Textarea) - Scroll adjusts as you type
- ✅ Modal Support - Works perfectly inside React Native Modal
- ✅ Bottom Sheet Compatible - Works with any overlay
- ✅ iOS & Android - Native performance on both platforms
- ✅ Expo Compatible - Works with Expo development builds
- ✅ TypeScript - Full TypeScript support
- ✅ useKeyboard Hook - Custom hook for keyboard state
📦 Installation
npm install react-native-universal-keyboard-aware-scrollview
# or
yarn add react-native-universal-keyboard-aware-scrollviewiOS Setup
cd ios && pod install && cd ..Android Setup
No additional setup needed - auto-linking handles everything!
Expo (Development Build)
npx expo prebuild
npx expo run:ios # or npx expo run:android⚠️ Note: This package uses native code and won't work in Expo Go. Use a development build instead.
🚀 Quick Start
Basic Example
import React from 'react';
import { TextInput, StyleSheet, SafeAreaView } from 'react-native';
import { KeyboardAwareScrollView } from 'react-native-universal-keyboard-aware-scrollview';
export default function App() {
return (
<SafeAreaView style={{ flex: 1 }}>
<KeyboardAwareScrollView style={styles.scroll}>
<TextInput placeholder="Name" style={styles.input} />
<TextInput placeholder="Email" style={styles.input} />
<TextInput placeholder="Phone" style={styles.input} />
{/* Multiline TextInput - works automatically! */}
<TextInput
placeholder="Your message..."
style={[styles.input, { height: 150, textAlignVertical: 'top' }]}
multiline
numberOfLines={6}
/>
</KeyboardAwareScrollView>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
scroll: { flex: 1, padding: 20 },
input: {
backgroundColor: 'white',
borderWidth: 1,
borderColor: '#ddd',
borderRadius: 8,
padding: 15,
marginBottom: 15,
fontSize: 16,
},
});📱 Usage in Modal
The component works perfectly inside React Native Modal:
import React, { useState } from 'react';
import { Modal, TextInput, Button, SafeAreaView, View, StyleSheet } from 'react-native';
import { KeyboardAwareScrollView } from 'react-native-universal-keyboard-aware-scrollview';
export default function ModalExample() {
const [visible, setVisible] = useState(false);
return (
<View style={styles.container}>
<Button title="Open Modal" onPress={() => setVisible(true)} />
<Modal visible={visible} animationType="slide">
<SafeAreaView style={{ flex: 1 }}>
<KeyboardAwareScrollView
style={styles.scroll}
insideModal={true}
>
<TextInput placeholder="Username" style={styles.input} />
<TextInput placeholder="Email" style={styles.input} />
<TextInput
placeholder="Bio (multiline)"
style={[styles.input, { height: 120, textAlignVertical: 'top' }]}
multiline
/>
</KeyboardAwareScrollView>
<Button title="Close" onPress={() => setVisible(false)} />
</SafeAreaView>
</Modal>
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1, justifyContent: 'center', padding: 20 },
scroll: { flex: 1, padding: 20 },
input: {
backgroundColor: 'white',
borderWidth: 1,
borderColor: '#ccc',
borderRadius: 8,
padding: 12,
marginBottom: 12,
fontSize: 16,
},
});📝 Multiline TextInput (Textarea)
Multiline inputs are automatically handled. The scroll adjusts as you type:
<KeyboardAwareScrollView>
<TextInput
placeholder="Write your message..."
multiline // Required for multiline
numberOfLines={6} // Optional
textAlignVertical="top" // For Android - aligns text to top
style={{
height: 150, // Fixed height recommended
padding: 12,
borderWidth: 1,
borderColor: '#ccc',
}}
/>
</KeyboardAwareScrollView>How it works:
- When you focus on a multiline input, it scrolls into view
- As you type and content grows, the scroll adjusts automatically
- Uses
onContentSizeChangeto detect content growth
🪝 useKeyboard Hook
For custom keyboard handling:
import { useKeyboard } from 'react-native-universal-keyboard-aware-scrollview';
function MyComponent() {
const { keyboardHeight, isKeyboardVisible, dismissKeyboard } = useKeyboard();
return (
<View style={{ paddingBottom: keyboardHeight }}>
<Text>Keyboard Height: {keyboardHeight}px</Text>
<TextInput placeholder="Type here..." />
{isKeyboardVisible && (
<Button title="Dismiss" onPress={dismissKeyboard} />
)}
</View>
);
}📖 Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| enableOnAndroid | boolean | true | Enable keyboard handling on Android |
| enableOnIOS | boolean | true | Enable keyboard handling on iOS |
| extraScrollHeight | number | 150 | Extra space above keyboard (pixels) |
| enableAutoScrollToFocused | boolean | true | Auto-scroll to focused input |
| insideModal | boolean | false | Set true when inside a Modal |
| keyboardShouldPersistTaps | string | 'handled' | Keyboard tap behavior |
| onKeyboardDidShow | function | - | Callback when keyboard appears |
| onKeyboardDidHide | function | - | Callback when keyboard disappears |
🔧 Ref Methods
const scrollRef = useRef<KeyboardAwareScrollViewRef>(null);
// Scroll to specific position
scrollRef.current?.scrollTo({ x: 0, y: 100, animated: true });
// Scroll to end
scrollRef.current?.scrollToEnd({ animated: true });
// Scroll to focused input manually
scrollRef.current?.scrollToFocusedInput();
// Get underlying ScrollView
scrollRef.current?.getScrollView();✅ Platform Support
| Platform | Supported | |----------|-----------| | iOS | ✅ | | Android | ✅ | | React Native CLI | ✅ | | Expo (Dev Build) | ✅ | | Expo Go | ❌ |
🛠 How It Works
- Keyboard Detection - Listens to keyboard events (
keyboardWillShow/keyboardDidShow) - Padding Adjustment - Adds bottom padding when keyboard appears
- Focus Detection - Uses
TextInput.State.currentlyFocusedInput()to find focused input - Position Measurement - Measures input position relative to ScrollView
- Smart Scrolling - Calculates optimal scroll position to show input above keyboard
- Multiline Support - Tracks content size changes and re-scrolls as content grows
🐛 Troubleshooting
Native module not found
# iOS
cd ios && pod install --repo-update && cd ..
# Android
cd android && ./gradlew clean && cd ..Expo Go not working
This package requires native code. Use a development build:
npx expo prebuild
npx expo run:iosInput still hidden behind keyboard
Increase extraScrollHeight:
<KeyboardAwareScrollView extraScrollHeight={200}>Multiline not scrolling
Make sure you have multiline={true}:
<TextInput
multiline={true}
numberOfLines={4}
style={{ height: 100 }}
/>📄 License
MIT © Vijay Kishan
🙏 Support
If this package helped you, please ⭐ star the repo!
