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-viewUsage#
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
offsetnumber—behavior"height" | "position" | "padding""padding" on iOS, undefined on AndroidclassNamestring—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}
/>
);
}