Keyboard Aware Screen
Scrollable form-screen shell with bounded width, explicit safe-area ownership, and platform keyboard handling.
Identity
Section titled “Identity”- Category: Layout & surfaces
- Status: stable public Registry/export-map component family
- Targets: iOS · Android · Web, subject to the compatibility contract
- Prerequisites:
@beemvp/beeui-uiinstalled (or this component’s source copied via the Registry CLI below) and, on Web, the BeeUI Tailwind/Uniwind theme CSS loaded — see Start for full platform setup. - Source:
packages/ui/src/components/keyboard-aware-screen.tsx
Import
Section titled “Import”import { KeyboardAwareScreen } from '@beemvp/beeui-ui';There is no documented deep/private source import. For source ownership from a BeeUI checkout:
pnpm beeui add keyboard-aware-screenRegistry (used throughout this page) is BeeUI’s source-ownership manifest — registry/registry.json — that the pnpm beeui/@beemvp/beeui-cli CLI reads to copy a component’s real source into your app and rewrite its internal imports; it is not an npm package index. This component’s own Registry entry: registry/registry.json.
Composition and public API
Section titled “Composition and public API”- Primary export:
KeyboardAwareScreen- Also routed here, outside the Registry family:
keyboard-aware-screen
- Package export subpath:
@beemvp/beeui-ui/keyboard-aware-screen
- Also routed here, outside the Registry family:
Exported types: KeyboardAwareScreenContentWidth, KeyboardAwareScreenKeyboardDismissMode, KeyboardAwareScreenProps, KeyboardAwareScreenSafeAreaEdges
The generated API inventory is mechanically joined to packages/ui/src/index.ts, Registry metadata, and the component reference contract. Each type’s field table below is parsed directly from that source, not a second hand-maintained copy; for the fuller behavior narrative see the canonical component behavior catalog.
State and behavior contract
Section titled “State and behavior contract”Stateless scrollable form-screen shell; it owns explicit safe-area edges and platform keyboard avoidance/dismissal defaults, but no routing, form state, validation, auth, or persistence — those stay entirely with the caller.
KeyboardAwareScreenProps
Section titled “KeyboardAwareScreenProps”| Prop | Type | Default | Description |
|---|---|---|---|
children (required) |
React.ReactNode |
— | Screen content. Composed inside the bounded, scrollable, keyboard-avoiding body. |
className |
string |
— | Extra utility classes, merged after the component’s own via cn(...), so they win on conflict. An escape hatch for source-owned and application work, not a cross-engine portability guarantee. |
contentWidth |
KeyboardAwareScreenContentWidth |
'full' |
Bounded max-width applied to the scrollable content so long-line forms stay readable on wide/tablet/web viewports. Defaults to 'full' (no bound) — opt into a narrower measure for form-style screens. |
keyboardScrollMargin |
number |
24 |
Gap kept between the focused input and the keyboard once scrolled into view on Android. Defaults to 24. |
keyboardDismissMode |
KeyboardAwareScreenKeyboardDismissMode |
— | Maps to the underlying ScrollView’s keyboardDismissMode. Defaults to 'interactive' on iOS and 'on-drag' elsewhere so drag-to-dismiss stays effective on Android, where React Native treats interactive like none. |
keyboardShouldPersistTaps |
ScrollViewProps['keyboardShouldPersistTaps'] |
'handled' |
Maps to the underlying ScrollView’s keyboardShouldPersistTaps. Defaults to 'handled' so taps on interactive children (buttons, links) inside the scroll body do not require a second tap after the keyboard has focus. |
safeAreaEdges |
KeyboardAwareScreenSafeAreaEdges |
— | Safe-area edges this screen owns. Left unset by default: a screen composed under a header/tab-bar shell that already owns safe-area insets should not also apply them here (double-inset). Pass the edges this screen actually touches (e.g. ['top', 'bottom']) when it owns the full window. |
testID |
string |
— | Test identifier. Forwarded to the native testID and, on Web, emitted as data-testid. |
Related exported types:
KeyboardAwareScreenContentWidth— one of'sm','md','lg','full'.KeyboardAwareScreenKeyboardDismissMode— alias ofNonNullable<ScrollViewProps['keyboardDismissMode']>.KeyboardAwareScreenSafeAreaEdges— alias ofNonNullable<React.ComponentProps<typeof SafeArea>['edges']>.
The executable fixtures below are the source-grounded usage examples; consumers should not infer state ownership from DOM structure or another UI library.
Provider and dependencies
Section titled “Provider and dependencies”- No additional provider is required by this family.
BeeUIProviderremains the recommended application root. - Peer/native dependencies visible to this Registry item:
react,react-native - Registry dependency closure:
core-cn,safe-area,theme - Safe-area ownership remains explicit: shell surfaces touching system edges opt into
SafeArea; components do not silently invent app-shell insets. - Web consumers load the BeeUI semantic theme CSS as documented in Web onboarding.
Platform behavior
Section titled “Platform behavior”This family ships no platform-specific file, but its source branches on Platform, so some behavior differs by target.
The same public family is exposed across the supported target matrix; meaningful platform differences remain governed by the compatibility contract.
Evidence classes are not equal and this page does not blur them: Web behavior is exercised in a real browser, while iOS and Android carry package/export and native-compile evidence, which is not device-runtime proof. The compatibility contract records which class each claim rests on.
Accessibility
Section titled “Accessibility”- Roles this family assigns: none set in
keyboard-aware-screen.tsx. - Accessibility states and properties it sets: none set in
keyboard-aware-screen.tsx.
Keyboard/focus behavior, announcements, Dynamic Type/Web zoom, RTL and reduced-motion expectations are not derived here — see Accessibility overview, Keyboard & focus, RTL/localization and Large text & zoom. BeeUI does not claim universal accessibility certification from automated tests.
Styling and theming
Section titled “Styling and theming”- Style axes:
contentWidth(4 values). - Class-name surfaces:
className.
Colors, spacing and typography come from semantic tokens rather than from values written here — see Theming and Density. A className is an escape hatch for source-owned and application work, not a cross-engine portability guarantee.
Executable examples
Section titled “Executable examples”- Primary executable fixture:
apps/showcase/__tests__/keyboard-aware-screen.test.tsx - Additional fixture:
apps/showcase/patterns/account-settings/components/settings-screen-shell.tsx - Additional fixture:
apps/showcase/patterns/auth/components/auth-shared.tsx - Additional fixture:
apps/showcase/runtime-smoke/runtime-acceptance.tsx
Addressable examples
Section titled “Addressable examples”Each link below opens the Showcase at that exact example, not at the top of the gallery:
basic— smallest meaningful complete usage
The Showcase links demonstrate Web behavior; use the native-preview guide for real simulator/emulator/device paths.
Live Web preview
Section titled “Live Web preview”This frame loads the real BeeUI Web Showcase on demand; it is not a second docs-only implementation. It proves browser behavior only. Use native preview for iOS/Android simulator, emulator or device paths.
Composition anatomy
Section titled “Composition anatomy”- Family root / primary export:
KeyboardAwareScreen- Exported type surface:
KeyboardAwareScreenContentWidthKeyboardAwareScreenKeyboardDismissModeKeyboardAwareScreenPropsKeyboardAwareScreenSafeAreaEdges
- Exported type surface:
The tree above is ordinary document structure so it remains readable with keyboard and assistive technology; it is derived from the real public export family rather than a canvas-only diagram.
Verified example source
Section titled “Verified example source”The following is the exact typechecked runtime Showcase fixture selected for this live preview: apps/showcase/patterns/account-settings/components/settings-screen-shell.tsx. Runtime gallery/pattern sources are preferred over test harnesses, and the displayed source and executable source are the same file; there is no separately maintained demo snippet.
import { Box, KeyboardAwareScreen, Screen, Text, VStack } from '@beemvp/beeui-ui';import * as React from 'react';import { ScrollView } from 'react-native';
export type SettingsScreenShellProps = { children: React.ReactNode; description?: string; eyebrow?: string; keyboardAware?: boolean; testID?: string; title: string;};
export function SettingsScreenShell({ children, description, eyebrow, keyboardAware = false, testID, title,}: SettingsScreenShellProps) { const header = ( <VStack gap="sm"> {eyebrow ? ( <Text tone="muted" variant="caption"> {eyebrow} </Text> ) : null} <Text className="text-3xl leading-10" variant="title"> {title} </Text> {description ? ( <Text tone="muted" variant="body"> {description} </Text> ) : null} </VStack> );
if (keyboardAware) { return ( <KeyboardAwareScreen contentWidth="md" testID={testID}> <Box className="flex-1 px-5 py-6 web:py-10"> <VStack gap="xl"> {header} {children} </VStack> </Box> </KeyboardAwareScreen> ); }
return ( <Screen testID={testID}> <ScrollView contentContainerStyle={{ flexGrow: 1 }} keyboardDismissMode="interactive" keyboardShouldPersistTaps="handled" > <Box className="mx-auto w-full max-w-[680px] flex-1 px-5 py-6 web:py-10"> <VStack gap="xl"> {header} {children} </VStack> </Box> </ScrollView> </Screen> );}Use the code block’s copy affordance to copy the exact fixture. For a smaller app-specific example, start from the public imports shown above and keep only the state your screen owns.
Limitations
Section titled “Limitations”Owns no routing, form state, validation, auth, or persistence.