AvoidKeyboard

A component that automatically adjusts its height to avoid keyboard overlap with smooth animations and cross-platform support.

Installation

pnpm dlx bna-ui add avoid-keyboard

Usage

import { AvoidKeyboard } from '@/components/ui/avoid-keyboard';
<View style={{ flex: 1 }}>
  {/* Your content */}
  <TextInput placeholder='Type here...' />
 
  {/* This will push content up when keyboard appears */}
  <AvoidKeyboard />
</View>

Examples

Basic Usage

With Offset

Custom Duration

Chat Interface

Form Example

Playground

API Reference

AvoidKeyboard

Automatically adjusts height to avoid keyboard overlap with smooth animations.

PropTypeDefaultDescription
offsetnumber0Additional spacing above the keyboard (in px)
durationnumber0Extra animation duration (in ms)

Features

  • Cross-platform support: Works on both iOS and Android
  • Smooth animations: Uses Reanimated for 60fps animations
  • Smart timing: Matches native keyboard animation duration
  • Flexible offset: Add extra spacing as needed
  • Automatic cleanup: Handles component unmounting gracefully
  • Screen rotation: Adapts to orientation changes

How It Works

The component uses the useKeyboardHeight hook to:

  1. Listen to keyboard events: Tracks show/hide events on both platforms
  2. Measure keyboard height: Gets accurate height measurements
  3. Animate smoothly: Uses platform-appropriate easing curves
  4. Handle edge cases: Manages screen rotation and invalid values

Platform Differences

iOS

  • Uses keyboardWillShow/Hide for smoother animations
  • Provides animation duration in keyboard events
  • Better landscape keyboard height detection

Android

  • Uses keyboardDidShow/Hide events
  • Falls back to default animation duration
  • Handles software keyboard variations

Best Practices

Placement

// ✅ Good - Place at bottom of your layout
<View style={{ flex: 1 }}>
  <ScrollView>
    {/* Your content */}
  </ScrollView>
  <TextInput />
  <AvoidKeyboard offset={20} />
</View>
 
// ❌ Avoid - Don't place in middle of content
<View>
  <TextInput />
  <AvoidKeyboard />
  <View>{/* More content */}</View>
</View>

With ScrollView

// ✅ Recommended pattern
<View style={{ flex: 1 }}>
  <ScrollView
    contentContainerStyle={{ flexGrow: 1 }}
    keyboardShouldPersistTaps='handled'
  >
    {/* Your content */}
  </ScrollView>
  <View style={{ padding: 16 }}>
    <TextInput />
  </View>
  <AvoidKeyboard offset={16} />
</View>

Multiple Inputs

// ✅ Single AvoidKeyboard for multiple inputs
<View style={{ flex: 1 }}>
  <TextInput placeholder='Name' />
  <TextInput placeholder='Email' />
  <TextInput placeholder='Message' />
  <AvoidKeyboard offset={20} />
</View>

Performance

  • Use a single AvoidKeyboard per screen
  • Avoid nesting multiple instances
  • Consider using offset instead of margin for spacing

Troubleshooting

Common Issues

Keyboard not detected:

  • Ensure React Native Reanimated is properly installed
  • Check if useKeyboardHeight hook is working correctly

Animation feels choppy:

  • Verify Reanimated 2+ is installed
  • Check if Hermes is enabled (recommended)

Wrong height on Android:

  • Some Android keyboards report incorrect heights
  • Consider using a small offset as buffer

Landscape mode issues:

  • Component handles basic landscape detection
  • For complex cases, listen to orientation changes

Debug Mode

// Add this for debugging
const { keyboardHeight, isKeyboardVisible } = useKeyboardHeight();
 
console.log('Keyboard:', { keyboardHeight, isKeyboardVisible });

Accessibility

The AvoidKeyboard component enhances accessibility by:

  • Preventing content hiding: Ensures form inputs remain visible
  • Maintaining focus: Keeps focused elements in view
  • Supporting assistive tech: Works with screen readers and voice control
  • Respecting user settings: Honors system animation preferences

Integration with Other Libraries

React Navigation

// Works seamlessly with React Navigation
function ChatScreen() {
  return (
    <View style={{ flex: 1 }}>
      <FlatList data={messages} />
      <TextInput />
      <AvoidKeyboard />
    </View>
  );
}

KeyboardAvoidingView Alternative

// Replace KeyboardAvoidingView with AvoidKeyboard
// ❌ Old way
<KeyboardAvoidingView behavior="padding">
  <TextInput />
</KeyboardAvoidingView>
 
// ✅ New way
<View style={{ flex: 1 }}>
  <TextInput />
  <AvoidKeyboard />
</View>

This component provides a more reliable and smoother alternative to React Native's built-in KeyboardAvoidingView with better cross-platform consistency.