ScaleRocket/Mobile

Screen Layout

SafeAreaView wrapper, ScrollView patterns, KeyboardAvoidingView, and screen padding conventions.

Screen Layout

ScaleRocket Mobile uses a ScreenLayout component that handles safe areas, scrolling, and keyboard avoidance so you can focus on screen content.

Basic Screen

import { ScreenLayout } from "@/components/ui/ScreenLayout";

export default function ProfileScreen() {
  return (
    <ScreenLayout>
      <Text>Profile content goes here</Text>
    </ScreenLayout>
  );
}

This wraps your content in SafeAreaView with consistent horizontal padding (16px) and background color.

SafeAreaView

Every screen must respect the device safe area (notch, status bar, home indicator):

import { SafeAreaView } from "react-native-safe-area-context";

export default function Screen() {
  return (
    <SafeAreaView style={{ flex: 1 }}>
      {/* Content avoids notch and home indicator */}
    </SafeAreaView>
  );
}

The ScreenLayout component handles this automatically. If you build a custom screen, always use react-native-safe-area-context instead of the built-in SafeAreaView from React Native.

ScrollView Pattern

For screens with content that may overflow, ScreenLayout uses ScrollView:

<ScreenLayout scroll>
  <Text>Section 1</Text>
  <Text>Section 2</Text>
  <Text>Section 3</Text>
  {/* Content scrolls when it exceeds screen height */}
</ScreenLayout>

Manual implementation:

import { ScrollView } from "react-native";

<SafeAreaView style={{ flex: 1 }}>
  <ScrollView
    contentContainerStyle={{ padding: 16, paddingBottom: 32 }}
    showsVerticalScrollIndicator={false}
    keyboardShouldPersistTaps="handled"
  >
    {children}
  </ScrollView>
</SafeAreaView>

Tip: Always set keyboardShouldPersistTaps="handled" so tapping a button while the keyboard is open works on the first tap.

KeyboardAvoidingView

For screens with forms, the keyboard can cover inputs. Use KeyboardAvoidingView:

import { KeyboardAvoidingView, Platform } from "react-native";

<ScreenLayout>
  <KeyboardAvoidingView
    behavior={Platform.OS === "ios" ? "padding" : "height"}
    style={{ flex: 1 }}
  >
    <Input label="Email" value={email} onChangeText={setEmail} />
    <Input label="Password" secureTextEntry value={pw} onChangeText={setPw} />
    <Button title="Sign In" onPress={handleSignIn} />
  </KeyboardAvoidingView>
</ScreenLayout>
PlatformBehaviorWhy
iOS"padding"Adds padding below content to push it up
Android"height"Resizes the view height

Padding Conventions

ScaleRocket Mobile uses consistent spacing:

const SPACING = {
  screenPadding: 16,    // Horizontal screen padding
  sectionGap: 24,       // Gap between sections
  cardPadding: 16,      // Padding inside cards
  inputGap: 16,         // Gap between form inputs
  bottomSafe: 32,       // Extra padding at bottom of scroll views
};

FlatList Screens

For screens with lists, use FlatList instead of ScrollView:

import { FlatList } from "react-native";

<SafeAreaView style={{ flex: 1 }}>
  <FlatList
    data={items}
    renderItem={({ item }) => <ItemCard item={item} />}
    keyExtractor={(item) => item.id}
    contentContainerStyle={{ padding: 16 }}
    ItemSeparatorComponent={() => <View style={{ height: 12 }} />}
  />
</SafeAreaView>

Important: Never nest a FlatList inside a ScrollView. Use ListHeaderComponent and ListFooterComponent instead.

Component Props

PropTypeDefaultDescription
scrollbooleantrueEnable ScrollView
paddingnumber16Horizontal padding
safeAreabooleantrueWrap in SafeAreaView
backgroundColorstringtheme bgScreen background color
childrenReactNodeScreen content

On this page