0
# Layout Components
1
2
Fundamental layout and container components including View, ScrollView, SafeAreaView, Modal, and KeyboardAvoidingView. These provide the structural foundation for React Native Web applications with comprehensive styling, accessibility, and platform integration features.
3
4
## View
5
6
The fundamental container component for building UI layouts. Renders as a `div` or `span` element with full React Native styling support, gesture handling, and accessibility features.
7
8
```javascript { .api }
9
const View: React.ComponentType<ViewProps>;
10
```
11
12
**Props:**
13
- `style` - Style object with full React Native styling support including flexbox, positioning, and transforms
14
- `pointerEvents` - Controls touch event handling: `'auto'` | `'none'` | `'box-none'` | `'box-only'`
15
- `onLayout` - Callback when component layout changes, receives layout measurements
16
- `accessible` - Whether component is accessible to assistive technologies
17
- `accessibilityRole` - Semantic role for screen readers (button, text, etc.)
18
- `accessibilityLabel` - Accessibility label for screen readers
19
- `href` - Makes View render as an anchor link for navigation
20
- `hrefAttrs` - Link attributes: `{download?: boolean, rel?: string, target?: string}`
21
- `dir` - Text direction: `'ltr'` | `'rtl'` | `'auto'`
22
- `lang` - Language code for internationalization
23
- `children` - Child elements (cannot contain bare text strings)
24
25
**Responder Events:**
26
- `onStartShouldSetResponder` - Should component become responder on touch start
27
- `onMoveShouldSetResponder` - Should component become responder on touch move
28
- `onResponderGrant` - Component became responder
29
- `onResponderMove` - Touch move while responder
30
- `onResponderRelease` - Touch ended while responder
31
- `onResponderTerminate` - Responder was terminated
32
33
**Platform Methods:**
34
- `blur()` - Remove focus from component
35
- `focus()` - Focus component
36
- `measure(callback)` - Get component dimensions and position
37
- `measureInWindow(callback)` - Get component position relative to window
38
- `measureLayout(relativeNode, onSuccess, onFail)` - Get position relative to another component
39
40
**Usage:**
41
```javascript
42
import { View } from "react-native-web";
43
44
<View
45
style={{ flex: 1, backgroundColor: '#f0f0f0' }}
46
onLayout={(event) => console.log(event.nativeEvent.layout)}
47
accessibilityRole="main"
48
>
49
<Text>Content goes here</Text>
50
</View>
51
52
// As a link
53
<View
54
href="/about"
55
hrefAttrs={{ target: '_blank' }}
56
style={{ padding: 20 }}
57
>
58
<Text>Navigate to About</Text>
59
</View>
60
```
61
62
## ScrollView
63
64
A scrollable container component with support for horizontal/vertical scrolling, pull-to-refresh, sticky headers, and comprehensive scroll event handling.
65
66
```javascript { .api }
67
const ScrollView: React.ComponentType<ScrollViewProps>;
68
```
69
70
**Props:**
71
- `horizontal` - Enable horizontal scrolling instead of vertical
72
- `showsHorizontalScrollIndicator` - Show/hide horizontal scroll bar
73
- `showsVerticalScrollIndicator` - Show/hide vertical scroll bar
74
- `scrollEnabled` - Enable/disable scrolling
75
- `contentContainerStyle` - Style applied to scroll content container
76
- `refreshControl` - Pull-to-refresh component
77
- `stickyHeaderIndices` - Array of child indices to stick to top when scrolling
78
- `pagingEnabled` - Snap to page boundaries when scrolling
79
- `keyboardDismissMode` - When to dismiss keyboard: `'none'` | `'interactive'` | `'on-drag'`
80
- `centerContent` - Center content when smaller than scroll view
81
- `scrollEventThrottle` - Throttle scroll events (milliseconds)
82
- `onScroll` - Scroll event handler
83
- `onScrollBeginDrag` - User starts dragging
84
- `onScrollEndDrag` - User stops dragging
85
- `onMomentumScrollBegin` - Momentum scrolling starts
86
- `onMomentumScrollEnd` - Momentum scrolling ends
87
- `onContentSizeChange` - Content size changes: `(width, height) => void`
88
89
**Methods:**
90
- `scrollTo({x?, y?, animated?})` - Scroll to specific coordinates
91
- `scrollToEnd({animated?})` - Scroll to bottom (or right if horizontal)
92
- `flashScrollIndicators()` - Briefly show scroll indicators
93
94
**Usage:**
95
```javascript
96
import { ScrollView, RefreshControl } from "react-native-web";
97
98
function App() {
99
const scrollRef = useRef();
100
const [refreshing, setRefreshing] = useState(false);
101
102
const onRefresh = () => {
103
setRefreshing(true);
104
// Refresh data
105
setTimeout(() => setRefreshing(false), 2000);
106
};
107
108
return (
109
<ScrollView
110
ref={scrollRef}
111
horizontal={false}
112
showsVerticalScrollIndicator={true}
113
contentContainerStyle={{ padding: 20 }}
114
refreshControl={
115
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
116
}
117
stickyHeaderIndices={[0]}
118
onScroll={(event) => {
119
console.log(event.nativeEvent.contentOffset);
120
}}
121
scrollEventThrottle={16}
122
>
123
<Text style={{ position: 'sticky' }}>Header</Text>
124
{/* Content */}
125
</ScrollView>
126
);
127
}
128
```
129
130
## SafeAreaView
131
132
A container that automatically applies safe area insets to avoid content being obscured by system UI elements like notches, status bars, or home indicators.
133
134
```javascript { .api }
135
const SafeAreaView: React.ComponentType<ViewProps>;
136
```
137
138
**Props:**
139
- Inherits all `ViewProps`
140
- Automatically applies `paddingTop`, `paddingRight`, `paddingBottom`, `paddingLeft` using CSS `env()` or `constant()` safe area functions
141
142
**Usage:**
143
```javascript
144
import { SafeAreaView, View, Text } from "react-native-web";
145
146
<SafeAreaView style={{ flex: 1, backgroundColor: '#fff' }}>
147
<View style={{ flex: 1, padding: 20 }}>
148
<Text>Content will respect safe areas</Text>
149
</View>
150
</SafeAreaView>
151
```
152
153
The component automatically detects browser support for `constant()` vs `env()` CSS functions and applies appropriate safe area insets.
154
155
## Modal
156
157
A modal dialog component that renders content in a portal above other content with focus management, animation support, and accessibility features.
158
159
```javascript { .api }
160
const Modal: React.ComponentType<ModalProps>;
161
```
162
163
**Props:**
164
- `visible` - Whether modal is visible (default: true)
165
- `animationType` - Animation type: `'none'` | `'slide'` | `'fade'`
166
- `transparent` - Whether modal background is transparent
167
- `onRequestClose` - Callback when modal should be closed (required on Android)
168
- `onShow` - Callback when modal becomes visible
169
- `onDismiss` - Callback when modal is dismissed
170
- `presentationStyle` - Presentation style: `'fullScreen'` | `'pageSheet'` | `'formSheet'` | `'overFullScreen'`
171
- `hardwareAccelerated` - Use hardware acceleration (Android only)
172
- `statusBarTranslucent` - Status bar translucency (Android only)
173
- `supportedOrientations` - Supported orientations array
174
- `onOrientationChange` - Orientation change callback
175
- `children` - Modal content
176
177
**Usage:**
178
```javascript
179
import { Modal, View, Text, Button } from "react-native-web";
180
181
function App() {
182
const [modalVisible, setModalVisible] = useState(false);
183
184
return (
185
<View>
186
<Button title="Show Modal" onPress={() => setModalVisible(true)} />
187
188
<Modal
189
visible={modalVisible}
190
animationType="slide"
191
transparent={true}
192
onRequestClose={() => setModalVisible(false)}
193
onShow={() => console.log('Modal shown')}
194
onDismiss={() => console.log('Modal dismissed')}
195
>
196
<View style={{ flex: 1, backgroundColor: 'rgba(0,0,0,0.5)' }}>
197
<View style={{
198
flex: 1,
199
justifyContent: 'center',
200
alignItems: 'center',
201
backgroundColor: 'white',
202
margin: 20,
203
borderRadius: 10
204
}}>
205
<Text>Modal Content</Text>
206
<Button title="Close" onPress={() => setModalVisible(false)} />
207
</View>
208
</View>
209
</Modal>
210
</View>
211
);
212
}
213
```
214
215
## KeyboardAvoidingView
216
217
A container that automatically adjusts its position when the virtual keyboard appears, helping keep important content visible during text input.
218
219
```javascript { .api }
220
const KeyboardAvoidingView: React.ComponentType<KeyboardAvoidingViewProps>;
221
```
222
223
**Props:**
224
- `behavior` - Adjustment behavior: `'height'` | `'padding'` | `'position'`
225
- `keyboardVerticalOffset` - Distance between top of keyboard and component (number)
226
- `contentContainerStyle` - Style for the content container
227
- Inherits all `ViewProps`
228
229
**Usage:**
230
```javascript
231
import { KeyboardAvoidingView, TextInput, View } from "react-native-web";
232
233
<KeyboardAvoidingView
234
behavior="padding"
235
keyboardVerticalOffset={64}
236
style={{ flex: 1 }}
237
>
238
<View style={{ flex: 1, justifyContent: 'flex-end', padding: 20 }}>
239
<TextInput
240
placeholder="Type here..."
241
style={{ borderWidth: 1, padding: 10, borderRadius: 5 }}
242
/>
243
</View>
244
</KeyboardAvoidingView>
245
```
246
247
Note: On web, keyboard avoidance behavior is limited compared to native platforms, as the virtual keyboard API is not fully standardized across browsers.
248
249
## Types
250
251
```javascript { .api }
252
interface ViewProps {
253
style?: ViewStyle;
254
pointerEvents?: 'auto' | 'none' | 'box-none' | 'box-only';
255
onLayout?: (event: LayoutEvent) => void;
256
accessible?: boolean;
257
accessibilityRole?: string;
258
accessibilityLabel?: string;
259
children?: React.ReactNode;
260
href?: string;
261
hrefAttrs?: {
262
download?: boolean;
263
rel?: string;
264
target?: string;
265
};
266
dir?: 'ltr' | 'rtl';
267
lang?: string;
268
// Responder events
269
onStartShouldSetResponder?: (event: ResponderEvent) => boolean;
270
onMoveShouldSetResponder?: (event: ResponderEvent) => boolean;
271
onResponderGrant?: (event: ResponderEvent) => void;
272
onResponderMove?: (event: ResponderEvent) => void;
273
onResponderRelease?: (event: ResponderEvent) => void;
274
onResponderTerminate?: (event: ResponderEvent) => void;
275
onResponderTerminationRequest?: (event: ResponderEvent) => boolean;
276
}
277
278
interface ScrollViewProps extends ViewProps {
279
horizontal?: boolean;
280
showsHorizontalScrollIndicator?: boolean;
281
showsVerticalScrollIndicator?: boolean;
282
scrollEnabled?: boolean;
283
contentContainerStyle?: ViewStyle;
284
refreshControl?: React.ReactElement;
285
stickyHeaderIndices?: number[];
286
pagingEnabled?: boolean;
287
keyboardDismissMode?: 'none' | 'interactive' | 'on-drag';
288
centerContent?: boolean;
289
scrollEventThrottle?: number;
290
onScroll?: (event: ScrollEvent) => void;
291
onScrollBeginDrag?: (event: ScrollEvent) => void;
292
onScrollEndDrag?: (event: ScrollEvent) => void;
293
onMomentumScrollBegin?: (event: ScrollEvent) => void;
294
onMomentumScrollEnd?: (event: ScrollEvent) => void;
295
onContentSizeChange?: (width: number, height: number) => void;
296
}
297
298
interface ModalProps extends ViewProps {
299
visible?: boolean;
300
animationType?: 'none' | 'slide' | 'fade';
301
transparent?: boolean;
302
onRequestClose?: () => void;
303
onShow?: () => void;
304
onDismiss?: () => void;
305
presentationStyle?: 'fullScreen' | 'pageSheet' | 'formSheet' | 'overFullScreen';
306
hardwareAccelerated?: boolean;
307
statusBarTranslucent?: boolean;
308
supportedOrientations?: Array<'portrait' | 'portrait-upside-down' | 'landscape' | 'landscape-left' | 'landscape-right'>;
309
onOrientationChange?: (event: {orientation: 'portrait' | 'landscape'}) => void;
310
}
311
312
interface KeyboardAvoidingViewProps extends ViewProps {
313
behavior?: 'height' | 'padding' | 'position';
314
keyboardVerticalOffset?: number;
315
contentContainerStyle?: ViewStyle;
316
}
317
```