Version: next

Pressable

Pressable is a Core Component wrapper that can detect various stages of press interactions on any of its defined children.

<Pressable onPress={onPressFunction}>
<Text>I'm pressable!</Text>
</Pressable>

How it works

On an element wrapped by Pressable:

  • onPressIn is called when a press is activated.
  • onPressOut is called when the press gesture is deactivated.

After pressing onPressIn, one of two things will happen:

  1. The person will remove their finger, triggering onPressOut followed by onPress.
  2. If the person leaves their finger longer than 370 milliseconds before removing it, onLongPress is triggered. (onPressOut will still fire when they remove their finger.)
Diagram of the onPress events in sequence.

Fingers are not the most precise instruments, and it is common for users to accidentally activate the wrong element or miss the activation area. To help, Pressable has an optional HitRect you can use to define how far a touch can register away from the the wrapped element. Presses can start anywhere within a HitRect.

PressRect allows presses to move beyond the element and its HitRect while maintaining activation and being eligible for a "press"—think of sliding your finger slowly away from a button you're pressing down on.

The touch area never extends past the parent view bounds and the Z-index of sibling views always takes precedence if a touch hits two overlapping views.

Diagram of HitRect and PressRect and how they work.
You can set HitRect with hitSlop and set PressRect with pressRetentionOffset.

Pressable uses React Native's Pressability API. For more information around the state machine flow of Pressability and how it works, check out the implementation for Pressability.

Example

import React, { useState } from 'react';
import { Pressable, StyleSheet, Text, View } from 'react-native';
const App = () => {
const [timesPressed, setTimesPressed] = useState(0);
let textLog = '';
if (timesPressed > 1) {
textLog = timesPressed + 'x onPress';
} else if (timesPressed > 0) {
textLog = 'onPress';
}
return (
<View>
<Pressable
onPress={() => {
setTimesPressed((current) => current + 1);
}}
style={({ pressed }) => [
{
backgroundColor: pressed
? 'rgb(210, 230, 255)'
: 'white'
},
styles.wrapperCustom
]}>
{({ pressed }) => (
<Text style={styles.text}>
{pressed ? 'Pressed!' : 'Press Me'}
</Text>
)}
</Pressable>
<View style={styles.logBox}>
<Text testID="pressable_press_console">{textLog}</Text>
</View>
</View>
);
};
const styles = StyleSheet.create({
text: {
fontSize: 16
},
wrapperCustom: {
borderRadius: 8,
padding: 6
},
logBox: {
padding: 20,
margin: 10,
borderWidth: StyleSheet.hairlineWidth,
borderColor: '#f0f0f0',
backgroundColor: '#f9f9f9'
}
});
export default App;

Props

android_disableSound
Android

If true, doesn't play Android system sound on press.

TypeRequiredDefault
booleanNofalse

android_ripple
Android

Enables the Android ripple effect and configures its properties.

TypeRequired
RippleConfigNo

children

Either children or a function that receives a boolean reflecting whether the component is currently pressed.

TypeRequired
React NodeNo

delayLongPress

Duration (in milliseconds) from onPressIn before onLongPress is called.

TypeRequiredDefault
numberNo370

disabled

Whether the press behavior is disabled.

TypeRequiredDefault
booleanNofalse

hitSlop

Sets additional distance outside of element in which a press can be detected.

TypeRequired
Rect or numberNo

onLongPress

Called if the time after onPressIn lasts longer than 370 milliseconds. This time period can be customized with delayLongPress.

TypeRequired
PressEventNo

onPress

Called after onPressOut.

TypeRequired
PressEventNo

onPressIn

Called immediately when a touch is engaged, before onPressOut and onPress.

TypeRequired
PressEventNo

onPressOut

Called when a touch is released.

TypeRequired
PressEventNo

pressRetentionOffset

Additional distance outside of this view in which a touch is considered a press before onPressOut is triggered.

TypeRequiredDefault
Rect or numberNo{ bottom: 30, left: 20, right: 20, top: 20 }

style

Either view styles or a function that receives a boolean reflecting whether the component is currently pressed and returns view styles.

TypeRequired
ViewStylePropNo

testOnly_pressed

Used only for documentation or testing (e.g. snapshot testing).

TypeRequiredDefault
booleanNofalse

Type Definitions

RippleConfig

Ripple effect configuration for the android_ripple property.

Type
object

Properties:

NameTypeRequiredDescription
colorcolorNoDefines the color of the ripple effect.
borderlessbooleanNoDefines if ripple effect should not include border.
radiusnumberNoDefines the radius of the ripple effect.