CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-native-web

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.

Pending
Overview
Eval results
Files

interactive-components.mddocs/

Interactive Components

User interaction components including buttons, touchables, and pressable elements with comprehensive gesture handling, accessibility support, and rich visual feedback capabilities.

Button

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 handler
  • disabled - Whether button is disabled
  • color - Button background color
  • accessibilityLabel - Screen reader label
  • testID - Test identifier

Usage:

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.

Pressable

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.Node
  • onPress - Press event handler
  • onPressIn - Press start handler
  • onPressOut - Press end handler
  • onLongPress - Long press handler
  • onHoverIn - Mouse hover start handler (web only)
  • onHoverOut - Mouse hover end handler (web only)
  • disabled - Whether component is disabled
  • delayLongPress - Long press delay in milliseconds
  • delayPressIn - Press in delay in milliseconds
  • delayPressOut - Press out delay in milliseconds
  • style - Style object or function that receives interaction state

Interaction State:

  • focused - Component has keyboard focus
  • hovered - Mouse is hovering (web only)
  • pressed - Component is currently pressed

Usage:

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>

TouchableOpacity

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 handler
  • onPressIn - Press start handler
  • onPressOut - Press end handler
  • onLongPress - Long press handler
  • disabled - Whether component is disabled
  • delayPressIn - Press in delay in milliseconds
  • delayPressOut - Press out delay in milliseconds
  • delayLongPress - Long press delay in milliseconds
  • style - Component styling
  • children - Child components

Usage:

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.

TouchableHighlight

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 handler
  • onPressIn - Press start handler
  • onPressOut - Press end handler
  • onLongPress - Long press handler
  • onShowUnderlay - Called when underlay is shown
  • onHideUnderlay - Called when underlay is hidden
  • disabled - Whether component is disabled
  • style - Component styling
  • children - 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.

TouchableWithoutFeedback

Captures touch events without providing visual feedback. Useful for creating custom interactive areas.

const TouchableWithoutFeedback: React.ComponentType<TouchableWithoutFeedbackProps>;

Props:

  • onPress - Press event handler
  • onPressIn - Press start handler
  • onPressOut - Press end handler
  • onLongPress - Long press handler
  • disabled - Whether component is disabled
  • delayPressIn - Press in delay in milliseconds
  • delayPressOut - Press out delay in milliseconds
  • delayLongPress - Long press delay in milliseconds
  • accessibilityLabel - Screen reader label
  • accessibilityRole - Semantic role
  • children - 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.

TouchableNativeFeedback

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 handler
  • disabled - Whether component is disabled
  • children - 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.

Types

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

docs

accessibility.md

animation.md

core-utilities.md

form-controls.md

hooks.md

index.md

interactive-components.md

layout-components.md

list-components.md

media-components.md

platform-apis.md

stylesheet.md

system-integration.md

text-input.md

tile.json