AniUI

Keyboard View

KeyboardAvoidingView wrapper with sensible platform defaults — keeps inputs visible above the keyboard.

Sign in
Email
Password
Sign In
Keyboard
Web preview — components render natively on iOS & Android
import { View } from "react-native";
import { KeyboardView } from "@/components/ui/keyboard-view";
import { SafeArea } from "@/components/ui/safe-area";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";

export function LoginScreen() {
  return (
    <SafeArea>
      <KeyboardView>
        <View className="flex-1 justify-end gap-3 p-6">
          <Input placeholder="Email" keyboardType="email-address" autoCapitalize="none" />
          <Input placeholder="Password" secureTextEntry />
          <Button>Sign In</Button>
        </View>
      </KeyboardView>
    </SafeArea>
  );
}

Installation#

npx @aniui/cli add keyboard-view

Usage#

Wrap the screen content in KeyboardView — the component is flex-1 by default, so inputs at the bottom slide up when the keyboard opens.

app/login.tsx
import { View } from "react-native";
import { KeyboardView } from "@/components/ui/keyboard-view";
import { SafeArea } from "@/components/ui/safe-area";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";

export function LoginScreen() {
  return (
    <SafeArea>
      <KeyboardView>
        <View className="flex-1 justify-end gap-3 p-6">
          <Input placeholder="Email" keyboardType="email-address" autoCapitalize="none" />
          <Input placeholder="Password" secureTextEntry />
          <Button>Sign In</Button>
        </View>
      </KeyboardView>
    </SafeArea>
  );
}

Offset#

If a fixed header or navigation bar sits above the view, pass its height as offset so the keyboard math stays correct.

Offset for fixed headers
// Account for a fixed header above the KeyboardView
// (offset maps to KeyboardAvoidingView's keyboardVerticalOffset)
<KeyboardView offset={64}>
  {/* Screen content */}
</KeyboardView>

Behavior#

On iOS the default is "padding"; on Android it is undefined because windowSoftInputMode="adjustResize" already resizes the window — setting a behavior there would double-shift the layout.

Overriding behavior
// The default behavior is "padding" on iOS and undefined on Android
// (Android's adjustResize already resizes the window). Override if needed:
<KeyboardView behavior="height">
  {/* Screen content */}
</KeyboardView>

Props#

PropTypeDefault
offset
number
behavior
"height" | "position" | "padding"
"padding" on iOS, undefined on Android
className
string

Also accepts all KeyboardAvoidingView props from React Native. offset is forwarded as keyboardVerticalOffset.

Accessibility#

  • Keeps focused inputs visible above the keyboard, which is essential for switch-access and low-vision users.
  • Layout container only — content within inherits standard accessibility behavior.

Source#

components/ui/keyboard-view.tsx
import React from "react";
import { KeyboardAvoidingView, Platform } from "react-native";
import { cn } from "@/lib/utils";

export interface KeyboardViewProps
  extends React.ComponentPropsWithoutRef<typeof KeyboardAvoidingView> {
  className?: string;
  offset?: number;
}

export function KeyboardView({ className, offset, behavior, ...props }: KeyboardViewProps) {
  return (
    <KeyboardAvoidingView
      className={cn("flex-1", className)}
      // iOS needs "padding"; Android's windowSoftInputMode="adjustResize" already
      // resizes the window, so no behavior avoids double-shifting the layout.
      behavior={behavior ?? (Platform.OS === "ios" ? "padding" : undefined)}
      keyboardVerticalOffset={offset}
      {...props}
    />
  );
}