A framework for building native apps using React
Overall
score
100%
Evaluation — 100%
↑ 1.06xAgent success when using this tile
React Native provides a comprehensive set of built-in components for building mobile applications. These components compile to native UI elements on each platform.
npm install react-nativeThe fundamental building block for UI construction, providing layout with flexbox, styling, and touch handling.
// ESM
import {View} from 'react-native';
// CommonJS
const {View} = require('react-native');
// Basic usage
<View style={{flex: 1, backgroundColor: 'blue'}}>
<Text>Content inside view</Text>
</View>
// With touch handling
<View
style={styles.container}
onTouchStart={(event) => console.log('Touch started')}
onLayout={(event) => console.log('Layout:', event.nativeEvent.layout)}
>
<Text>Touchable view</Text>
</View>interface ViewProps {
// Layout
style?: ViewStyle;
// Accessibility
accessible?: boolean;
accessibilityLabel?: string;
accessibilityRole?: AccessibilityRole;
accessibilityState?: AccessibilityState;
accessibilityValue?: AccessibilityValue;
accessibilityActions?: AccessibilityActionInfo[];
onAccessibilityAction?: (event: AccessibilityActionEvent) => void;
// Touch handling
onTouchStart?: (event: GestureResponderEvent) => void;
onTouchMove?: (event: GestureResponderEvent) => void;
onTouchEnd?: (event: GestureResponderEvent) => void;
onTouchCancel?: (event: GestureResponderEvent) => void;
// Layout events
onLayout?: (event: LayoutEvent) => void;
// Pointer events
pointerEvents?: 'none' | 'box-none' | 'box-only' | 'auto';
// Other
children?: React.ReactNode;
testID?: string;
nativeID?: string;
}
interface ViewStyle {
// Flexbox
flex?: number;
flexDirection?: 'row' | 'column' | 'row-reverse' | 'column-reverse';
justifyContent?: 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around' | 'space-evenly';
alignItems?: 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline';
alignSelf?: 'auto' | 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline';
// Positioning
position?: 'absolute' | 'relative';
top?: number | string;
left?: number | string;
right?: number | string;
bottom?: number | string;
// Dimensions
width?: number | string;
height?: number | string;
minWidth?: number | string;
maxWidth?: number | string;
minHeight?: number | string;
maxHeight?: number | string;
// Margin and padding
margin?: number | string;
marginTop?: number | string;
marginRight?: number | string;
marginBottom?: number | string;
marginLeft?: number | string;
marginHorizontal?: number | string;
marginVertical?: number | string;
padding?: number | string;
paddingTop?: number | string;
paddingRight?: number | string;
paddingBottom?: number | string;
paddingLeft?: number | string;
paddingHorizontal?: number | string;
paddingVertical?: number | string;
// Appearance
backgroundColor?: string;
opacity?: number;
// Border
borderWidth?: number;
borderTopWidth?: number;
borderRightWidth?: number;
borderBottomWidth?: number;
borderLeftWidth?: number;
borderColor?: string;
borderTopColor?: string;
borderRightColor?: string;
borderBottomColor?: string;
borderLeftColor?: string;
borderRadius?: number;
borderTopLeftRadius?: number;
borderTopRightRadius?: number;
borderBottomLeftRadius?: number;
borderBottomRightRadius?: number;
borderStyle?: 'solid' | 'dotted' | 'dashed';
// Shadow (iOS)
shadowColor?: string;
shadowOffset?: {width: number; height: number};
shadowOpacity?: number;
shadowRadius?: number;
// Elevation (Android)
elevation?: number;
// Transform
transform?: TransformStyle[];
}A component that renders content within the safe area boundaries of a device, accounting for physical limitations like notches or home indicators.
import {SafeAreaView} from 'react-native';
// Basic usage
<SafeAreaView style={{flex: 1}}>
<View style={{flex: 1, backgroundColor: 'red'}}>
<Text>Content respects safe areas</Text>
</View>
</SafeAreaView>
// iOS-specific behavior
<SafeAreaView style={{flex: 1, backgroundColor: 'white'}}>
<StatusBar barStyle="dark-content" />
<NavigationHeader />
<ScrollView>
<Text>Main content</Text>
</ScrollView>
</SafeAreaView>interface SafeAreaViewProps extends ViewProps {
emulateUnlessSupported?: boolean; // iOS only
}A generic scrolling container that can host multiple components and views.
import {ScrollView} from 'react-native';
// Basic vertical scrolling
<ScrollView style={{flex: 1}}>
<View style={{height: 1000}}>
<Text>Scrollable content</Text>
</View>
</ScrollView>
// Horizontal scrolling
<ScrollView
horizontal={true}
showsHorizontalScrollIndicator={false}
pagingEnabled={true}
>
<View style={{width: 300, height: 200}} />
<View style={{width: 300, height: 200}} />
<View style={{width: 300, height: 200}} />
</ScrollView>
// With pull-to-refresh
<ScrollView
refreshControl={
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
}
>
<Text>Pull to refresh</Text>
</ScrollView>
// Scroll methods
const scrollViewRef = useRef(null);
// Scroll to position
scrollViewRef.current?.scrollTo({x: 0, y: 100, animated: true});
// Scroll to end
scrollViewRef.current?.scrollToEnd({animated: true});interface ScrollViewProps extends ViewProps {
// Scrolling behavior
horizontal?: boolean;
pagingEnabled?: boolean;
scrollEnabled?: boolean;
// Scroll indicators
showsVerticalScrollIndicator?: boolean;
showsHorizontalScrollIndicator?: boolean;
// Content configuration
contentContainerStyle?: ViewStyle;
contentInset?: {top?: number; left?: number; bottom?: number; right?: number};
contentOffset?: {x: number; y: number};
// Bounce behavior
bounces?: boolean;
bouncesZoom?: boolean;
alwaysBounceHorizontal?: boolean;
alwaysBounceVertical?: boolean;
// Zoom
maximumZoomScale?: number;
minimumZoomScale?: number;
zoomScale?: number;
// Keyboard
keyboardDismissMode?: 'none' | 'interactive' | 'on-drag';
keyboardShouldPersistTaps?: 'always' | 'never' | 'handled';
// Events
onScroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
onScrollBeginDrag?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
onScrollEndDrag?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
onMomentumScrollBegin?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
onMomentumScrollEnd?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
// Refresh control
refreshControl?: React.ReactElement<RefreshControlProps>;
// Scroll methods (via ref)
scrollTo?: (options?: {x?: number; y?: number; animated?: boolean}) => void;
scrollToEnd?: (options?: {animated?: boolean}) => void;
}
interface NativeScrollEvent {
contentOffset: {x: number; y: number};
contentSize: {width: number; height: number};
layoutMeasurement: {width: number; height: number};
zoomScale?: number;
}A component for displaying text with styling and touch handling capabilities.
import {Text} from 'react-native';
// Basic text
<Text>Simple text</Text>
// Styled text
<Text style={{fontSize: 18, color: 'blue', fontWeight: 'bold'}}>
Styled text
</Text>
// Nested text with different styles
<Text>
I am bold
<Text style={{fontWeight: 'bold'}}>and red</Text>
<Text style={{color: 'red'}}> text</Text>
</Text>
// Touchable text
<Text
onPress={() => console.log('Text pressed')}
style={{color: 'blue', textDecorationLine: 'underline'}}
>
Clickable text
</Text>
// Text with number of lines
<Text numberOfLines={2} ellipsizeMode="tail">
This is a very long text that will be truncated after two lines with ellipsis at the end
</Text>
// Selectable text
<Text selectable={true}>
This text can be selected and copied
</Text>interface TextProps {
// Content
children?: React.ReactNode;
// Styling
style?: TextStyle;
// Text behavior
numberOfLines?: number;
ellipsizeMode?: 'head' | 'middle' | 'tail' | 'clip';
selectable?: boolean;
adjustsFontSizeToFit?: boolean; // iOS
minimumFontScale?: number; // iOS
// Touch handling
onPress?: (event: GestureResponderEvent) => void;
onLongPress?: (event: GestureResponderEvent) => void;
// Layout
onLayout?: (event: LayoutEvent) => void;
// Text selection (iOS)
onTextLayout?: (event: NativeSyntheticEvent<TextLayoutEvent>) => void;
// Accessibility
accessible?: boolean;
accessibilityLabel?: string;
accessibilityRole?: AccessibilityRole;
// Other
testID?: string;
nativeID?: string;
allowFontScaling?: boolean;
maxFontSizeMultiplier?: number;
}
interface TextStyle {
// Font
fontFamily?: string;
fontSize?: number;
fontStyle?: 'normal' | 'italic';
fontWeight?: 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900';
fontVariant?: FontVariant[];
// Color
color?: string;
// Text layout
textAlign?: 'auto' | 'left' | 'right' | 'center' | 'justify';
textAlignVertical?: 'auto' | 'top' | 'bottom' | 'center'; // Android
textDecorationLine?: 'none' | 'underline' | 'line-through' | 'underline line-through';
textDecorationStyle?: 'solid' | 'double' | 'dotted' | 'dashed';
textDecorationColor?: string;
textShadowColor?: string;
textShadowOffset?: {width: number; height: number};
textShadowRadius?: number;
textTransform?: 'none' | 'capitalize' | 'uppercase' | 'lowercase';
// Line spacing
lineHeight?: number;
letterSpacing?: number;
// Writing direction
writingDirection?: 'auto' | 'ltr' | 'rtl';
// Include layout style properties
includeFontPadding?: boolean; // Android
// Text shadow
textShadowColor?: string;
textShadowOffset?: {width: number; height: number};
textShadowRadius?: number;
}A component for displaying various types of images including network images, static resources, and base64 images.
import {Image} from 'react-native';
// Static image
<Image
source={require('./assets/image.png')}
style={{width: 100, height: 100}}
/>
// Network image
<Image
source={{uri: 'https://example.com/image.jpg'}}
style={{width: 200, height: 200}}
onLoad={() => console.log('Image loaded')}
onError={(error) => console.log('Image error:', error)}
/>
// Base64 image
<Image
source={{uri: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...'}}
style={{width: 50, height: 50}}
/>
// Image with resize modes
<Image
source={{uri: 'https://example.com/image.jpg'}}
style={{width: 300, height: 200}}
resizeMode="contain"
/>
// Network image with headers
<Image
source={{
uri: 'https://example.com/image.jpg',
headers: {
'Authorization': 'Bearer token',
},
}}
style={{width: 100, height: 100}}
/>
// Get image size
Image.getSize(
'https://example.com/image.jpg',
(width, height) => {
console.log('Image size:', width, height);
},
(error) => {
console.error('Failed to get image size:', error);
}
);
// Preload images
Image.prefetch('https://example.com/image.jpg')
.then(() => console.log('Image cached'))
.catch((error) => console.log('Cache error:', error));interface ImageProps {
// Source
source: ImageSourcePropType;
// Styling
style?: ImageStyle;
// Resize behavior
resizeMode?: 'cover' | 'contain' | 'stretch' | 'repeat' | 'center';
resizeMethod?: 'auto' | 'resize' | 'scale'; // Android
// Loading behavior
loadingIndicatorSource?: ImageSourcePropType;
defaultSource?: ImageSourcePropType; // iOS
// Events
onLoad?: (event: NativeSyntheticEvent<ImageLoadEvent>) => void;
onLoadStart?: () => void;
onLoadEnd?: () => void;
onError?: (error: NativeSyntheticEvent<ImageErrorEvent>) => void;
onProgress?: (event: NativeSyntheticEvent<ImageProgressEvent>) => void;
// Layout
onLayout?: (event: LayoutEvent) => void;
// Accessibility
accessible?: boolean;
accessibilityLabel?: string;
// Other
testID?: string;
blurRadius?: number;
capInsets?: EdgeInsets; // iOS
tintColor?: string;
// iOS specific
fadeDuration?: number; // Android
}
interface ImageSourcePropType {
uri?: string;
bundle?: string;
method?: string;
headers?: {[key: string]: string};
body?: string;
cache?: 'default' | 'reload' | 'force-cache' | 'only-if-cached'; // iOS
width?: number;
height?: number;
scale?: number;
}
interface ImageStyle extends ViewStyle {
resizeMode?: 'cover' | 'contain' | 'stretch' | 'repeat' | 'center';
tintColor?: string;
overlayColor?: string; // Android
}
// Static methods
interface ImageStatic {
getSize(
uri: string,
success: (width: number, height: number) => void,
failure?: (error: any) => void
): void;
getSizeWithHeaders(
uri: string,
headers: {[key: string]: string},
success: (width: number, height: number) => void,
failure?: (error: any) => void
): void;
prefetch(url: string): Promise<boolean>;
queryCache(urls: string[]): Promise<{[url: string]: 'memory' | 'disk'}>;
}A component for rendering an image as a background with child components overlaid on top.
import {ImageBackground} from 'react-native';
// Basic usage
<ImageBackground
source={{uri: 'https://example.com/background.jpg'}}
style={{width: '100%', height: 200}}
>
<Text style={{color: 'white', fontSize: 24}}>
Text over background image
</Text>
</ImageBackground>
// With local image
<ImageBackground
source={require('./assets/background.png')}
style={styles.backgroundImage}
resizeMode="cover"
>
<View style={styles.overlay}>
<Text style={styles.title}>Welcome</Text>
<Button title="Get Started" onPress={handlePress} />
</View>
</ImageBackground>
// With image loading states
<ImageBackground
source={{uri: imageUrl}}
style={styles.container}
onLoad={() => setImageLoaded(true)}
onError={() => setImageError(true)}
>
{!imageLoaded && <ActivityIndicator size="large" />}
<Text>Content over background</Text>
</ImageBackground>interface ImageBackgroundProps extends ImageProps {
children?: React.ReactNode;
imageStyle?: ImageStyle;
imageRef?: React.Ref<Image>;
}A foundational component for inputting text into the app via a keyboard.
import {TextInput} from 'react-native';
// Basic text input
const [text, setText] = useState('');
<TextInput
style={{height: 40, borderColor: 'gray', borderWidth: 1, padding: 10}}
onChangeText={setText}
value={text}
placeholder="Enter text here"
/>
// Multiline text input
<TextInput
style={{height: 100, textAlignVertical: 'top'}}
multiline={true}
numberOfLines={4}
onChangeText={setText}
value={text}
placeholder="Enter multiple lines"
/>
// Secure text input (password)
<TextInput
style={styles.input}
secureTextEntry={true}
onChangeText={setPassword}
value={password}
placeholder="Password"
/>
// Numeric input
<TextInput
style={styles.input}
keyboardType="numeric"
onChangeText={setNumber}
value={number}
placeholder="Enter number"
/>
// Email input
<TextInput
style={styles.input}
keyboardType="email-address"
autoCapitalize="none"
autoComplete="email"
onChangeText={setEmail}
value={email}
placeholder="Email address"
/>
// Input with submit handling
<TextInput
style={styles.input}
onChangeText={setText}
value={text}
onSubmitEditing={handleSubmit}
returnKeyType="send"
blurOnSubmit={true}
/>
// Focus management
const inputRef = useRef(null);
// Focus the input
inputRef.current?.focus();
// Blur the input
inputRef.current?.blur();
// Clear the input
inputRef.current?.clear();interface TextInputProps {
// Value and change handling
value?: string;
defaultValue?: string;
onChangeText?: (text: string) => void;
onEndEditing?: (event: NativeSyntheticEvent<TextInputEndEditingEvent>) => void;
onSubmitEditing?: (event: NativeSyntheticEvent<TextInputSubmitEditingEvent>) => void;
// Styling
style?: ViewStyle;
// Placeholder
placeholder?: string;
placeholderTextColor?: string;
// Text behavior
multiline?: boolean;
numberOfLines?: number; // Android
maxLength?: number;
editable?: boolean;
// Keyboard configuration
keyboardType?: KeyboardType;
returnKeyType?: ReturnKeyType;
autoCapitalize?: 'none' | 'sentences' | 'words' | 'characters';
autoComplete?: AutoCompleteType;
autoCorrect?: boolean;
spellCheck?: boolean;
// Security
secureTextEntry?: boolean;
textContentType?: TextContentType; // iOS
// Selection
selection?: {start: number; end?: number};
selectionColor?: string;
onSelectionChange?: (event: NativeSyntheticEvent<TextInputSelectionChangeEvent>) => void;
// Focus handling
onFocus?: (event: NativeSyntheticEvent<TextInputFocusEvent>) => void;
onBlur?: (event: NativeSyntheticEvent<TextInputFocusEvent>) => void;
blurOnSubmit?: boolean;
// Keyboard behavior
keyboardAppearance?: 'default' | 'light' | 'dark'; // iOS
enablesReturnKeyAutomatically?: boolean; // iOS
// Layout
onLayout?: (event: LayoutEvent) => void;
onContentSizeChange?: (event: NativeSyntheticEvent<TextInputContentSizeChangeEvent>) => void;
// Accessibility
accessible?: boolean;
accessibilityLabel?: string;
// Input accessory
inputAccessoryViewID?: string; // iOS
// Other
testID?: string;
clearButtonMode?: 'never' | 'while-editing' | 'unless-editing' | 'always'; // iOS
clearTextOnFocus?: boolean; // iOS
selectTextOnFocus?: boolean;
// Text input methods (via ref)
focus?: () => void;
blur?: () => void;
clear?: () => void;
isFocused?: () => boolean;
}
type KeyboardType =
| 'default'
| 'number-pad'
| 'decimal-pad'
| 'numeric'
| 'email-address'
| 'phone-pad'
| 'url'
| 'ascii-capable'
| 'numbers-and-punctuation'
| 'name-phone-pad'
| 'twitter'
| 'web-search'
| 'visible-password';
type ReturnKeyType =
| 'done'
| 'go'
| 'next'
| 'search'
| 'send'
| 'none'
| 'previous'
| 'default'
| 'emergency-call'
| 'google'
| 'join'
| 'route'
| 'yahoo';A basic button component with platform-specific styling.
import {Button} from 'react-native';
// Basic button
<Button
title="Press me"
onPress={() => Alert.alert('Button pressed!')}
/>
// Disabled button
<Button
title="Disabled"
onPress={() => {}}
disabled={true}
/>
// Button with color (Android)
<Button
title="Colored Button"
color="#ff5722"
onPress={handlePress}
/>
// iOS button styling
<Button
title="iOS Button"
onPress={handlePress}
// Note: iOS buttons inherit color from tintColor
/>interface ButtonProps {
title: string;
onPress: (event: GestureResponderEvent) => void;
color?: string;
disabled?: boolean;
accessibilityLabel?: string;
testID?: string;
}A component which enables customization of the keyboard input accessory view on iOS.
import {InputAccessoryView, TextInput, Button} from 'react-native';
// Basic input accessory view
<View>
<TextInput
inputAccessoryViewID="uniqueID"
style={styles.textInput}
placeholder="Enter text"
/>
<InputAccessoryView nativeID="uniqueID">
<View style={styles.accessory}>
<Button title="Done" onPress={() => Keyboard.dismiss()} />
</View>
</InputAccessoryView>
</View>
// Multiple text inputs sharing same accessory
<View>
<TextInput
inputAccessoryViewID="sharedAccessory"
placeholder="First input"
style={styles.input}
/>
<TextInput
inputAccessoryViewID="sharedAccessory"
placeholder="Second input"
style={styles.input}
/>
<InputAccessoryView nativeID="sharedAccessory">
<View style={styles.toolbar}>
<Button title="Previous" onPress={goToPrevious} />
<Button title="Next" onPress={goToNext} />
<Button title="Done" onPress={finishEditing} />
</View>
</InputAccessoryView>
</View>
// Custom keyboard toolbar
<View>
<TextInput
inputAccessoryViewID="customToolbar"
multiline
style={styles.textArea}
placeholder="Enter your message"
/>
<InputAccessoryView nativeID="customToolbar">
<View style={styles.customToolbar}>
<TouchableOpacity onPress={insertBold}>
<Text style={styles.toolbarButton}>B</Text>
</TouchableOpacity>
<TouchableOpacity onPress={insertItalic}>
<Text style={styles.toolbarButton}>I</Text>
</TouchableOpacity>
<TouchableOpacity onPress={insertLink}>
<Text style={styles.toolbarButton}>Link</Text>
</TouchableOpacity>
<View style={styles.spacer} />
<TouchableOpacity onPress={sendMessage}>
<Text style={styles.sendButton}>Send</Text>
</TouchableOpacity>
</View>
</InputAccessoryView>
</View>interface InputAccessoryViewProps {
// Required: Unique identifier
nativeID: string;
// Content
children?: React.ReactNode;
// Styling
style?: ViewStyle;
// Background color
backgroundColor?: string;
}Note: InputAccessoryView is iOS-only. On Android, this component renders nothing.
A wrapper that responds to touches by decreasing the opacity of the wrapped view.
import {TouchableOpacity} from 'react-native';
// Basic touchable
<TouchableOpacity onPress={() => console.log('Pressed!')}>
<View style={styles.button}>
<Text>Touch me</Text>
</View>
</TouchableOpacity>
// Custom opacity
<TouchableOpacity
activeOpacity={0.6}
onPress={handlePress}
onLongPress={handleLongPress}
>
<Image source={{uri: 'image.jpg'}} style={styles.image} />
</TouchableOpacity>
// With disabled state
<TouchableOpacity
disabled={isLoading}
onPress={handleSubmit}
style={[styles.button, isLoading && styles.disabledButton]}
>
<Text style={styles.buttonText}>
{isLoading ? 'Loading...' : 'Submit'}
</Text>
</TouchableOpacity>interface TouchableOpacityProps extends TouchableWithoutFeedbackProps {
activeOpacity?: number;
style?: ViewStyle;
children?: React.ReactNode;
}A wrapper that responds to touches with an overlay color.
import {TouchableHighlight} from 'react-native';
// Basic highlight
<TouchableHighlight
onPress={handlePress}
underlayColor="#DDDDDD"
>
<View style={styles.button}>
<Text>Press me</Text>
</View>
</TouchableHighlight>
// Custom highlight color
<TouchableHighlight
onPress={handlePress}
underlayColor="rgba(255, 0, 0, 0.3)"
style={styles.card}
>
<View>
<Text style={styles.title}>Card Title</Text>
<Text style={styles.description}>Card description</Text>
</View>
</TouchableHighlight>interface TouchableHighlightProps extends TouchableWithoutFeedbackProps {
underlayColor?: string;
onShowUnderlay?: () => void;
onHideUnderlay?: () => void;
style?: ViewStyle;
children?: React.ReactNode;
}A modern touchable component with configurable press behaviors and comprehensive event handling.
import {Pressable} from 'react-native';
// Basic pressable
<Pressable onPress={() => console.log('Pressed')}>
<Text>Press me</Text>
</Pressable>
// With press state styling
<Pressable
onPress={handlePress}
style={({pressed}) => [
styles.button,
pressed && styles.pressed
]}
>
{({pressed}) => (
<Text style={pressed ? styles.pressedText : styles.text}>
{pressed ? 'Pressed!' : 'Press me'}
</Text>
)}
</Pressable>
// Advanced press handling
<Pressable
onPress={handlePress}
onPressIn={() => setPressed(true)}
onPressOut={() => setPressed(false)}
onLongPress={handleLongPress}
onHoverIn={() => setHovered(true)} // Web/desktop
onHoverOut={() => setHovered(false)}
pressRetentionOffset={{top: 20, left: 20, right: 20, bottom: 20}}
hitSlop={{top: 10, left: 10, right: 10, bottom: 10}}
android_ripple={{color: 'rgba(0, 0, 0, 0.32)'}}
>
<View style={styles.pressable}>
<Text>Advanced Pressable</Text>
</View>
</Pressable>
// Disabled pressable
<Pressable
disabled={isLoading}
onPress={handlePress}
style={({pressed}) => [
styles.button,
isLoading && styles.disabled,
pressed && !isLoading && styles.pressed
]}
>
<Text>{isLoading ? 'Loading...' : 'Submit'}</Text>
</Pressable>interface PressableProps {
// Press handling
onPress?: (event: GestureResponderEvent) => void;
onPressIn?: (event: GestureResponderEvent) => void;
onPressOut?: (event: GestureResponderEvent) => void;
onLongPress?: (event: GestureResponderEvent) => void;
// Hover handling (web/desktop)
onHoverIn?: (event: MouseEvent) => void;
onHoverOut?: (event: MouseEvent) => void;
// Focus handling
onFocus?: (event: FocusEvent) => void;
onBlur?: (event: FocusEvent) => void;
// Configuration
disabled?: boolean;
hitSlop?: EdgeInsets;
pressRetentionOffset?: EdgeInsets;
delayLongPress?: number;
// Styling with state
style?: ViewStyle | ((state: PressableStateCallbackType) => ViewStyle);
children?: React.ReactNode | ((state: PressableStateCallbackType) => React.ReactNode);
// Platform specific
android_ripple?: AndroidRippleConfig;
android_disableSound?: boolean;
// Accessibility
accessible?: boolean;
accessibilityLabel?: string;
accessibilityRole?: AccessibilityRole;
accessibilityState?: AccessibilityState;
// Other
testID?: string;
unstable_pressDelay?: number;
}
interface PressableStateCallbackType {
pressed: boolean;
hovered?: boolean;
focused?: boolean;
}
interface AndroidRippleConfig {
color?: string;
borderless?: boolean;
radius?: number;
}A performant interface for rendering basic, flat lists with lazy loading and optimization.
import {FlatList} from 'react-native';
// Basic list
const data = [
{id: '1', title: 'Item 1'},
{id: '2', title: 'Item 2'},
{id: '3', title: 'Item 3'},
];
<FlatList
data={data}
renderItem={({item}) => (
<View style={styles.item}>
<Text>{item.title}</Text>
</View>
)}
keyExtractor={item => item.id}
/>
// Horizontal list
<FlatList
data={photos}
renderItem={({item}) => (
<Image source={{uri: item.url}} style={styles.photo} />
)}
keyExtractor={item => item.id}
horizontal={true}
showsHorizontalScrollIndicator={false}
/>
// List with separators
<FlatList
data={data}
renderItem={renderItem}
keyExtractor={item => item.id}
ItemSeparatorComponent={() => <View style={styles.separator} />}
ListHeaderComponent={() => <Text style={styles.header}>Header</Text>}
ListFooterComponent={() => <Text style={styles.footer}>Footer</Text>}
ListEmptyComponent={() => <Text>No items found</Text>}
/>
// Infinite scroll
<FlatList
data={data}
renderItem={renderItem}
keyExtractor={item => item.id}
onEndReached={loadMore}
onEndReachedThreshold={0.1}
refreshing={refreshing}
onRefresh={onRefresh}
ListFooterComponent={isLoading ? <ActivityIndicator /> : null}
/>
// Grid layout
<FlatList
data={data}
renderItem={renderItem}
keyExtractor={item => item.id}
numColumns={2}
columnWrapperStyle={styles.row}
/>
// Performance optimization
<FlatList
data={largeData}
renderItem={renderItem}
keyExtractor={item => item.id}
getItemLayout={(data, index) => ({
length: ITEM_HEIGHT,
offset: ITEM_HEIGHT * index,
index,
})}
initialNumToRender={10}
maxToRenderPerBatch={5}
updateCellsBatchingPeriod={100}
windowSize={10}
/>interface FlatListProps<ItemT> extends VirtualizedListProps<ItemT> {
// Data
data?: ReadonlyArray<ItemT> | null;
// Rendering
renderItem: ListRenderItem<ItemT>;
// Layout
numColumns?: number;
columnWrapperStyle?: ViewStyle;
horizontal?: boolean;
// Components
ItemSeparatorComponent?: React.ComponentType<any> | null;
ListEmptyComponent?: React.ComponentType<any> | React.ReactElement | null;
ListFooterComponent?: React.ComponentType<any> | React.ReactElement | null;
ListHeaderComponent?: React.ComponentType<any> | React.ReactElement | null;
// Keys and extraction
keyExtractor?: (item: ItemT, index: number) => string;
extraData?: any;
// Performance
getItemLayout?: (data: ArrayLike<ItemT> | null | undefined, index: number) => {length: number, offset: number, index: number};
initialNumToRender?: number;
initialScrollIndex?: number;
// Scroll behavior
onEndReached?: ((info: {distanceFromEnd: number}) => void) | null;
onEndReachedThreshold?: number | null;
// Refresh
refreshing?: boolean | null;
onRefresh?: (() => void) | null;
// View management
removeClippedSubviews?: boolean;
viewabilityConfig?: ViewabilityConfig;
onViewableItemsChanged?: ((info: {viewableItems: ViewToken[], changed: ViewToken[]}) => void) | null;
// Scroll methods (via ref)
scrollToEnd?: (params?: {animated?: boolean}) => void;
scrollToIndex?: (params: {animated?: boolean, index: number, viewOffset?: number, viewPosition?: number}) => void;
scrollToItem?: (params: {animated?: boolean, item: ItemT, viewPosition?: number}) => void;
scrollToOffset?: (params: {animated?: boolean, offset: number}) => void;
}
interface ListRenderItem<ItemT> {
(info: {item: ItemT, index: number, separators: {
highlight: () => void,
unhighlight: () => void,
updateProps: (select: 'leading' | 'trailing', newProps: any) => void,
}}): React.ReactElement | null;
}A performant interface for rendering sectioned lists with headers and optimized scrolling.
import {SectionList} from 'react-native';
// Basic sectioned list
const sections = [
{
title: 'Fruits',
data: ['Apple', 'Banana', 'Orange'],
},
{
title: 'Vegetables',
data: ['Carrot', 'Broccoli', 'Spinach'],
},
];
<SectionList
sections={sections}
keyExtractor={(item, index) => item + index}
renderItem={({item}) => (
<View style={styles.item}>
<Text>{item}</Text>
</View>
)}
renderSectionHeader={({section: {title}}) => (
<Text style={styles.header}>{title}</Text>
)}
/>
// Advanced sectioned list
<SectionList
sections={sections}
keyExtractor={(item, index) => item.id + index}
renderItem={({item, index, section}) => (
<TouchableOpacity onPress={() => handleItemPress(item)}>
<View style={styles.item}>
<Text>{item.title}</Text>
<Text style={styles.subtitle}>{item.subtitle}</Text>
</View>
</TouchableOpacity>
)}
renderSectionHeader={({section: {title, data}}) => (
<View style={styles.sectionHeader}>
<Text style={styles.sectionTitle}>{title}</Text>
<Text style={styles.count}>({data.length} items)</Text>
</View>
)}
renderSectionFooter={({section}) => (
<View style={styles.sectionFooter}>
<Text>End of {section.title}</Text>
</View>
)}
ItemSeparatorComponent={() => <View style={styles.separator} />}
SectionSeparatorComponent={() => <View style={styles.sectionSeparator} />}
ListHeaderComponent={() => <Text style={styles.listHeader}>All Items</Text>}
ListFooterComponent={() => <Text style={styles.listFooter}>End of list</Text>}
stickySectionHeadersEnabled={true}
/>
// With custom section structure
const customSections = [
{
title: 'Today',
data: todayItems,
color: 'blue',
},
{
title: 'Yesterday',
data: yesterdayItems,
color: 'gray',
},
];
<SectionList
sections={customSections}
keyExtractor={item => item.id}
renderItem={({item, section}) => (
<View style={[styles.item, {borderLeftColor: section.color}]}>
<Text>{item.title}</Text>
</View>
)}
renderSectionHeader={({section}) => (
<View style={[styles.header, {backgroundColor: section.color}]}>
<Text style={styles.headerText}>{section.title}</Text>
</View>
)}
/>interface SectionListProps<ItemT, SectionT> extends VirtualizedListProps<ItemT> {
// Data
sections: ReadonlyArray<SectionListData<ItemT, SectionT>>;
// Rendering
renderItem: SectionListRenderItem<ItemT, SectionT>;
renderSectionHeader?: (info: {section: SectionListData<ItemT, SectionT>}) => React.ReactElement | null;
renderSectionFooter?: (info: {section: SectionListData<ItemT, SectionT>}) => React.ReactElement | null;
// Components
ItemSeparatorComponent?: React.ComponentType<any> | null;
SectionSeparatorComponent?: React.ComponentType<any> | null;
ListEmptyComponent?: React.ComponentType<any> | React.ReactElement | null;
ListFooterComponent?: React.ComponentType<any> | React.ReactElement | null;
ListHeaderComponent?: React.ComponentType<any> | React.ReactElement | null;
// Behavior
stickySectionHeadersEnabled?: boolean;
// Keys
keyExtractor?: (item: ItemT, index: number) => string;
// Scroll methods (via ref)
scrollToLocation?: (params: SectionListScrollParams) => void;
}
interface SectionListData<ItemT, SectionT = DefaultSectionT> {
data: ReadonlyArray<ItemT>;
key?: string;
// Custom section properties
[key: string]: any;
}
interface SectionListRenderItem<ItemT, SectionT> {
(info: {
item: ItemT,
index: number,
section: SectionListData<ItemT, SectionT>,
separators: {
highlight: () => void,
unhighlight: () => void,
updateProps: (select: 'leading' | 'trailing', newProps: any) => void,
}
}): React.ReactElement | null;
}
interface SectionListScrollParams {
animated?: boolean;
itemIndex: number;
sectionIndex: number;
viewOffset?: number;
viewPosition?: number;
}A boolean input component for toggling between two states.
import {Switch} from 'react-native';
// Basic switch
const [isEnabled, setIsEnabled] = useState(false);
<Switch
trackColor={{false: '#767577', true: '#81b0ff'}}
thumbColor={isEnabled ? '#f5dd4b' : '#f4f3f4'}
ios_backgroundColor="#3e3e3e"
onValueChange={setIsEnabled}
value={isEnabled}
/>
// Switch with labels
<View style={styles.switchContainer}>
<Text>Enable notifications</Text>
<Switch
value={notificationsEnabled}
onValueChange={setNotificationsEnabled}
/>
</View>
// Disabled switch
<Switch
disabled={true}
value={false}
trackColor={{false: '#ccc', true: '#ccc'}}
thumbColor="#999"
/>interface SwitchProps {
// State
value?: boolean;
onValueChange?: (value: boolean) => void;
// Styling
thumbColor?: string;
trackColor?: {false?: string; true?: string};
// Behavior
disabled?: boolean;
// iOS specific
ios_backgroundColor?: string;
// Accessibility
accessible?: boolean;
accessibilityLabel?: string;
accessibilityRole?: AccessibilityRole;
accessibilityState?: AccessibilityState;
// Other
testID?: string;
}A component for showing loading state with a spinning indicator.
import {ActivityIndicator} from 'react-native';
// Basic activity indicator
<ActivityIndicator />
// Large colored indicator
<ActivityIndicator size="large" color="#0000ff" />
// Custom size (number for exact size)
<ActivityIndicator size={50} color="red" />
// Animated indicator in loading state
{isLoading && (
<View style={styles.loadingContainer}>
<ActivityIndicator size="large" color="#007AFF" />
<Text style={styles.loadingText}>Loading...</Text>
</View>
)}
// Overlay loading
<View style={styles.container}>
{/* Your content */}
<Text>Content here</Text>
{isLoading && (
<View style={styles.overlay}>
<ActivityIndicator size="large" color="white" />
</View>
)}
</View>interface ActivityIndicatorProps {
// Behavior
animating?: boolean;
// Appearance
color?: string;
size?: 'small' | 'large' | number;
// Layout
style?: ViewStyle;
// iOS specific
hidesWhenStopped?: boolean;
// Accessibility
accessible?: boolean;
accessibilityLabel?: string;
// Other
testID?: string;
}A component for adding pull-to-refresh functionality to scroll views.
import {RefreshControl} from 'react-native';
// Basic refresh control
const [refreshing, setRefreshing] = useState(false);
const onRefresh = useCallback(() => {
setRefreshing(true);
// Fetch new data
fetchData().then(() => {
setRefreshing(false);
});
}, []);
<ScrollView
refreshControl={
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
}
>
<Text>Pull down to refresh</Text>
</ScrollView>
// Customized refresh control
<FlatList
data={data}
renderItem={renderItem}
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={onRefresh}
colors={['#ff0000', '#00ff00', '#0000ff']} // Android
tintColor="#ff0000" // iOS
title="Pull to refresh" // iOS
titleColor="#00ff00" // iOS
progressBackgroundColor="#ffff00" // Android
/>
}
/>interface RefreshControlProps {
// State
refreshing?: boolean;
onRefresh?: () => void;
// iOS specific
tintColor?: string;
title?: string;
titleColor?: string;
// Android specific
colors?: string[];
progressBackgroundColor?: string;
progressViewOffset?: number;
// Layout
style?: ViewStyle;
// Other
enabled?: boolean;
}A component for presenting content above an enclosing view.
import {Modal} from 'react-native';
// Basic modal
const [modalVisible, setModalVisible] = useState(false);
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => setModalVisible(false)}
>
<View style={styles.centeredView}>
<View style={styles.modalView}>
<Text style={styles.modalText}>Hello World!</Text>
<Pressable
style={[styles.button, styles.buttonClose]}
onPress={() => setModalVisible(!modalVisible)}
>
<Text style={styles.textStyle}>Hide Modal</Text>
</Pressable>
</View>
</View>
</Modal>
// Full screen modal
<Modal
animationType="fade"
visible={modalVisible}
onRequestClose={() => setModalVisible(false)}
>
<SafeAreaView style={styles.fullScreenModal}>
<View style={styles.header}>
<TouchableOpacity onPress={() => setModalVisible(false)}>
<Text style={styles.closeButton}>Close</Text>
</TouchableOpacity>
</View>
<View style={styles.content}>
<Text>Full screen modal content</Text>
</View>
</SafeAreaView>
</Modal>
// Modal with overlay
<Modal
transparent={true}
visible={modalVisible}
animationType="fade"
onRequestClose={() => setModalVisible(false)}
>
<TouchableOpacity
style={styles.overlay}
activeOpacity={1}
onPress={() => setModalVisible(false)}
>
<View style={styles.modalContainer}>
<TouchableOpacity activeOpacity={1}>
<View style={styles.modal}>
<Text>Modal content that won't close when touched</Text>
</View>
</TouchableOpacity>
</View>
</TouchableOpacity>
</Modal>interface ModalProps {
// Visibility
visible?: boolean;
// Animation
animationType?: 'none' | 'slide' | 'fade';
// Presentation
transparent?: boolean;
presentationStyle?: 'fullScreen' | 'pageSheet' | 'formSheet' | 'overFullScreen'; // iOS
// Events
onRequestClose?: () => void;
onShow?: (event: NativeSyntheticEvent<any>) => void;
onDismiss?: () => void; // iOS
// iOS specific
supportedOrientations?: ('portrait' | 'portrait-upside-down' | 'landscape' | 'landscape-left' | 'landscape-right')[];
onOrientationChange?: (event: NativeSyntheticEvent<any>) => void;
// Android specific
hardwareAccelerated?: boolean;
statusBarTranslucent?: boolean;
// Content
children?: React.ReactNode;
// Other
testID?: string;
}A component for controlling the app status bar appearance.
import {StatusBar} from 'react-native';
// Basic status bar
<StatusBar barStyle="dark-content" />
// Hidden status bar
<StatusBar hidden={true} />
// Animated status bar changes
<StatusBar
barStyle="light-content"
backgroundColor="#6a51ae"
animated={true}
/>
// Dynamic status bar based on theme
const isDark = useColorScheme() === 'dark';
<StatusBar
barStyle={isDark ? 'light-content' : 'dark-content'}
backgroundColor={isDark ? '#000' : '#fff'}
/>
// Status bar in different screens
function HomeScreen() {
return (
<View>
<StatusBar barStyle="dark-content" backgroundColor="white" />
<Text>Home Screen</Text>
</View>
);
}
function ProfileScreen() {
return (
<View>
<StatusBar barStyle="light-content" backgroundColor="blue" />
<Text>Profile Screen</Text>
</View>
);
}
// Static methods
StatusBar.setBarStyle('light-content', true);
StatusBar.setBackgroundColor('blue', true); // Android
StatusBar.setHidden(true, 'slide'); // iOSinterface StatusBarProps {
// Appearance
barStyle?: 'default' | 'light-content' | 'dark-content';
// Visibility
hidden?: boolean;
// Animation
animated?: boolean;
// Android specific
backgroundColor?: string;
translucent?: boolean;
// iOS specific
networkActivityIndicatorVisible?: boolean;
showHideTransition?: 'fade' | 'slide';
}
// Static methods
interface StatusBarStatic {
setBarStyle(style: 'default' | 'light-content' | 'dark-content', animated?: boolean): void;
setBackgroundColor(color: string, animated?: boolean): void; // Android
setHidden(hidden: boolean, animation?: 'none' | 'fade' | 'slide'): void;
setNetworkActivityIndicatorVisible(visible: boolean): void; // iOS
setTranslucent(translucent: boolean): void; // Android
}A component that automatically adjusts its height, position, or bottom padding based on the keyboard height.
import {KeyboardAvoidingView} from 'react-native';
// Basic keyboard avoiding view
<KeyboardAvoidingView
style={{flex: 1}}
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
>
<ScrollView>
<TextInput style={styles.input} placeholder="Enter text" />
<TextInput style={styles.input} placeholder="Enter more text" />
</ScrollView>
</KeyboardAvoidingView>
// With custom offset
<KeyboardAvoidingView
behavior="padding"
keyboardVerticalOffset={Platform.select({ios: 60, android: 80})}
style={styles.container}
>
<View style={styles.form}>
<TextInput placeholder="Email" />
<TextInput placeholder="Password" secureTextEntry />
<Button title="Login" onPress={handleLogin} />
</View>
</KeyboardAvoidingView>
// In modal or screen with header
<KeyboardAvoidingView
behavior="height"
keyboardVerticalOffset={100} // Adjust for header height
style={{flex: 1}}
>
<View style={styles.content}>
<TextInput multiline style={styles.textArea} />
</View>
</KeyboardAvoidingView>interface KeyboardAvoidingViewProps extends ViewProps {
// Behavior
behavior?: 'height' | 'position' | 'padding';
// Offset
keyboardVerticalOffset?: number;
// Content
contentContainerStyle?: ViewStyle;
// Events
onKeyboardChange?: (event: KeyboardEvent) => void;
// Layout
enabled?: boolean;
}This comprehensive documentation covers all the core React Native components with their interfaces, usage patterns, and examples. Each component includes TypeScript definitions and practical code examples showing common use cases.
Install with Tessl CLI
npx tessl i tessl/npm-react-native@1000.0.0docs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10