React Native for Web is a comprehensive compatibility library that enables React Native components and APIs to run seamlessly on web browsers using React DOM.
—
User interaction components including buttons, touchables, and pressable elements with comprehensive gesture handling, accessibility support, and rich visual feedback capabilities.
A basic button component with built-in styling and accessibility features. Simple to use with minimal configuration required.
const Button: React.ComponentType<ButtonProps>;Props:
title - Button text (required)onPress - Press event handlerdisabled - Whether button is disabledcolor - Button background coloraccessibilityLabel - Screen reader labeltestID - Test identifierUsage:
import { Button } from "react-native-web";
<Button
title="Click Me"
onPress={() => alert('Button pressed!')}
color="#2196F3"
disabled={false}
/>
// Custom styling via color
<Button
title="Success"
onPress={handleSubmit}
color="#4CAF50"
accessibilityLabel="Submit form"
/>Note: Button is deprecated in favor of Pressable for more advanced use cases.
The most advanced and flexible interactive component with rich state management, hover support, and customizable styling based on interaction states.
const Pressable: React.ComponentType<PressableProps>;Props:
children - Content or function that receives interaction state: (state: {hovered, focused, pressed}) => React.NodeonPress - Press event handleronPressIn - Press start handleronPressOut - Press end handleronLongPress - Long press handleronHoverIn - Mouse hover start handler (web only)onHoverOut - Mouse hover end handler (web only)disabled - Whether component is disableddelayLongPress - Long press delay in millisecondsdelayPressIn - Press in delay in millisecondsdelayPressOut - Press out delay in millisecondsstyle - Style object or function that receives interaction stateInteraction State:
focused - Component has keyboard focushovered - Mouse is hovering (web only)pressed - Component is currently pressedUsage:
import { Pressable, Text } from "react-native-web";
// Basic pressable
<Pressable onPress={() => console.log('Pressed!')}>
<Text>Press me</Text>
</Pressable>
// Dynamic styling based on state
<Pressable
onPress={handlePress}
style={({pressed, hovered}) => ({
backgroundColor: pressed ? '#ddd' : hovered ? '#eee' : '#f5f5f5',
padding: 16,
borderRadius: 8,
transform: pressed ? 'scale(0.98)' : 'scale(1)',
})}
>
<Text>Interactive Button</Text>
</Pressable>
// Function children with state
<Pressable
onPress={handlePress}
onLongPress={handleLongPress}
delayLongPress={800}
>
{({pressed, hovered, focused}) => (
<View style={{
padding: 12,
backgroundColor: pressed ? '#007AFF' : '#f0f0f0',
borderRadius: 6,
borderWidth: focused ? 2 : 0,
borderColor: '#007AFF',
}}>
<Text style={{
color: pressed ? '#fff' : '#000',
fontWeight: hovered ? 'bold' : 'normal'
}}>
{pressed ? 'Pressed!' : 'Press & Hold'}
</Text>
</View>
)}
</Pressable>
// Complex interaction handling
<Pressable
onPress={() => navigation.navigate('Details')}
onHoverIn={() => setIsHovered(true)}
onHoverOut={() => setIsHovered(false)}
onPressIn={() => Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light)}
style={({pressed, hovered}) => [
styles.card,
pressed && styles.cardPressed,
hovered && styles.cardHovered
]}
>
<Text>Navigate to Details</Text>
</Pressable>A wrapper that reduces opacity when pressed, providing visual feedback. Simpler than Pressable but with less flexibility.
const TouchableOpacity: React.ComponentType<TouchableOpacityProps>;Props:
activeOpacity - Opacity when pressed (default: 0.2)onPress - Press event handleronPressIn - Press start handleronPressOut - Press end handleronLongPress - Long press handlerdisabled - Whether component is disableddelayPressIn - Press in delay in millisecondsdelayPressOut - Press out delay in millisecondsdelayLongPress - Long press delay in millisecondsstyle - Component stylingchildren - Child componentsUsage:
import { TouchableOpacity, Text, View } from "react-native-web";
<TouchableOpacity
onPress={() => console.log('Pressed!')}
activeOpacity={0.6}
style={{
backgroundColor: '#007AFF',
padding: 16,
borderRadius: 8,
alignItems: 'center'
}}
>
<Text style={{ color: 'white', fontWeight: 'bold' }}>
Tap Me
</Text>
</TouchableOpacity>
// Custom opacity and timing
<TouchableOpacity
onPress={handlePress}
onLongPress={handleLongPress}
activeOpacity={0.8}
delayPressIn={100}
delayPressOut={200}
delayLongPress={1000}
>
<View style={styles.button}>
<Text>Custom Timing</Text>
</View>
</TouchableOpacity>Note: TouchableOpacity is deprecated in favor of Pressable.
Shows an underlay color when pressed by reducing the child opacity and showing a background color.
const TouchableHighlight: React.ComponentType<TouchableHighlightProps>;Props:
underlayColor - Background color when pressed (default: 'black')activeOpacity - Child opacity when pressed (default: 0.85)onPress - Press event handleronPressIn - Press start handleronPressOut - Press end handleronLongPress - Long press handleronShowUnderlay - Called when underlay is shownonHideUnderlay - Called when underlay is hiddendisabled - Whether component is disabledstyle - Component stylingchildren - Single child component (required)Usage:
import { TouchableHighlight, Text, View } from "react-native-web";
<TouchableHighlight
onPress={() => console.log('Pressed!')}
underlayColor="#DDDDDD"
activeOpacity={0.7}
style={{
backgroundColor: '#f0f0f0',
padding: 16,
borderRadius: 8
}}
>
<Text>Highlight on Press</Text>
</TouchableHighlight>
// Custom underlay behavior
<TouchableHighlight
onPress={handlePress}
underlayColor="rgba(0, 122, 255, 0.1)"
activeOpacity={0.9}
onShowUnderlay={() => console.log('Showing highlight')}
onHideUnderlay={() => console.log('Hiding highlight')}
>
<View style={styles.listItem}>
<Text>List Item with Highlight</Text>
</View>
</TouchableHighlight>Note: TouchableHighlight must have exactly one child component.
Captures touch events without providing visual feedback. Useful for creating custom interactive areas.
const TouchableWithoutFeedback: React.ComponentType<TouchableWithoutFeedbackProps>;Props:
onPress - Press event handleronPressIn - Press start handleronPressOut - Press end handleronLongPress - Long press handlerdisabled - Whether component is disableddelayPressIn - Press in delay in millisecondsdelayPressOut - Press out delay in millisecondsdelayLongPress - Long press delay in millisecondsaccessibilityLabel - Screen reader labelaccessibilityRole - Semantic rolechildren - Single child component (required)Usage:
import { TouchableWithoutFeedback, View, Text } from "react-native-web";
<TouchableWithoutFeedback
onPress={() => console.log('Area pressed')}
onLongPress={() => showContextMenu()}
>
<View style={{ padding: 20, backgroundColor: '#f5f5f5' }}>
<Text>Pressable area with no visual feedback</Text>
</View>
</TouchableWithoutFeedback>
// Custom gesture handling
<TouchableWithoutFeedback
onPressIn={() => setPressed(true)}
onPressOut={() => setPressed(false)}
onLongPress={handleLongPress}
delayLongPress={500}
>
<View style={[
styles.customArea,
pressed && styles.customAreaPressed
]}>
<Text>Custom Feedback Area</Text>
</View>
</TouchableWithoutFeedback>Note: TouchableWithoutFeedback must have exactly one child component.
Provides Material Design ripple effect on Android. On web, falls back to TouchableWithoutFeedback behavior.
const TouchableNativeFeedback: React.ComponentType<TouchableNativeFeedbackProps>;Props:
background - Ripple background configuration (Android only)useForeground - Whether to use foreground ripple (Android only)onPress - Press event handlerdisabled - Whether component is disabledchildren - Single child component (required)Usage:
import { TouchableNativeFeedback, View, Text } from "react-native-web";
<TouchableNativeFeedback
onPress={() => console.log('Pressed!')}
background={TouchableNativeFeedback.Ripple('#000', false)}
>
<View style={styles.button}>
<Text>Material Design Button</Text>
</View>
</TouchableNativeFeedback>
// Borderless ripple
<TouchableNativeFeedback
onPress={handlePress}
background={TouchableNativeFeedback.Ripple('#007AFF', true)}
useForeground={true}
>
<View style={styles.iconButton}>
<Icon name="heart" />
</View>
</TouchableNativeFeedback>Note: On web, this component provides basic touch handling without the native ripple effect.
interface ButtonProps {
title: string;
onPress?: (event: PressEvent) => void;
disabled?: boolean;
color?: string;
accessibilityLabel?: string;
testID?: string;
}
interface StateCallbackType {
focused: boolean;
hovered: boolean;
pressed: boolean;
}
interface PressableProps extends ViewProps {
children: React.ReactNode | ((state: StateCallbackType) => React.ReactNode);
onPress?: (event: PressEvent) => void;
onPressIn?: (event: PressEvent) => void;
onPressOut?: (event: PressEvent) => void;
onLongPress?: (event: PressEvent) => void;
onHoverIn?: (event: HoverEvent) => void;
onHoverOut?: (event: HoverEvent) => void;
disabled?: boolean;
delayLongPress?: number;
delayPressIn?: number;
delayPressOut?: number;
style?: ViewStyle | ((state: StateCallbackType) => ViewStyle);
}
interface TouchableOpacityProps extends ViewProps {
activeOpacity?: number;
onPress?: (event: PressEvent) => void;
onPressIn?: (event: PressEvent) => void;
onPressOut?: (event: PressEvent) => void;
onLongPress?: (event: PressEvent) => void;
disabled?: boolean;
delayPressIn?: number;
delayPressOut?: number;
delayLongPress?: number;
style?: ViewStyle;
children?: React.ReactNode;
}
interface TouchableHighlightProps extends ViewProps {
underlayColor?: ColorValue;
activeOpacity?: number;
onPress?: (event: PressEvent) => void;
onPressIn?: (event: PressEvent) => void;
onPressOut?: (event: PressEvent) => void;
onLongPress?: (event: PressEvent) => void;
onShowUnderlay?: () => void;
onHideUnderlay?: () => void;
disabled?: boolean;
style?: ViewStyle;
children: React.ReactElement; // Must have exactly one child
}
interface TouchableWithoutFeedbackProps {
onPress?: (event: PressEvent) => void;
onPressIn?: (event: PressEvent) => void;
onPressOut?: (event: PressEvent) => void;
onLongPress?: (event: PressEvent) => void;
disabled?: boolean;
delayPressIn?: number;
delayPressOut?: number;
delayLongPress?: number;
accessibilityLabel?: string;
accessibilityRole?: string;
children: React.ReactElement; // Must have exactly one child
}
interface TouchableNativeFeedbackProps {
onPress?: (event: PressEvent) => void;
disabled?: boolean;
background?: any; // Platform-specific ripple configuration
useForeground?: boolean;
children: React.ReactElement; // Must have exactly one child
}Install with Tessl CLI
npx tessl i tessl/npm-react-native-web