/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow
*/
'use strict';
const React = require('react');
const {
Animated,
Image,
StyleSheet,
Text,
TouchableHighlight,
TouchableOpacity,
NativeModules,
Platform,
TouchableNativeFeedback,
TouchableWithoutFeedback,
View,
} = require('react-native');
const forceTouchAvailable =
(NativeModules.PlatformConstants &&
NativeModules.PlatformConstants.forceTouchAvailable) ||
false;
class TouchableHighlightBox extends React.Component<{}, $FlowFixMeState> {
state = {
timesPressed: 0,
};
touchableOnPress = () => {
this.setState({
timesPressed: this.state.timesPressed + 1,
});
};
render() {
let textLog = '';
if (this.state.timesPressed > 1) {
textLog = this.state.timesPressed + 'x TouchableHighlight onPress';
} else if (this.state.timesPressed > 0) {
textLog = 'TouchableHighlight onPress';
}
return (
Tap Here For Custom Highlight!
{textLog}
);
}
}
class TouchableWithoutFeedbackBox extends React.Component<{}, $FlowFixMeState> {
state = {
timesPressed: 0,
};
textOnPress = () => {
this.setState({
timesPressed: this.state.timesPressed + 1,
});
};
render() {
let textLog = '';
if (this.state.timesPressed > 1) {
textLog = this.state.timesPressed + 'x TouchableWithoutFeedback onPress';
} else if (this.state.timesPressed > 0) {
textLog = 'TouchableWithoutFeedback onPress';
}
return (
Tap Here For No Feedback!
{textLog}
);
}
}
class TextOnPressBox extends React.Component<{}, $FlowFixMeState> {
state = {
timesPressed: 0,
};
textOnPress = () => {
this.setState({
timesPressed: this.state.timesPressed + 1,
});
};
render() {
let textLog = '';
if (this.state.timesPressed > 1) {
textLog = this.state.timesPressed + 'x text onPress';
} else if (this.state.timesPressed > 0) {
textLog = 'text onPress';
}
return (
Text has built-in onPress handling
{textLog}
);
}
}
class TouchableFeedbackEvents extends React.Component<{}, $FlowFixMeState> {
state = {
eventLog: [],
};
render() {
return (
this._appendEvent('press')}
onPressIn={() => this._appendEvent('pressIn')}
onPressOut={() => this._appendEvent('pressOut')}
onLongPress={() => this._appendEvent('longPress')}>
Press Me
{this.state.eventLog.map((e, ii) => (
{e}
))}
);
}
_appendEvent = eventName => {
const limit = 6;
const eventLog = this.state.eventLog.slice(0, limit - 1);
eventLog.unshift(eventName);
this.setState({eventLog});
};
}
class TouchableDelayEvents extends React.Component<{}, $FlowFixMeState> {
state = {
eventLog: [],
};
render() {
return (
this._appendEvent('press')}
delayPressIn={400}
onPressIn={() => this._appendEvent('pressIn - 400ms delay')}
delayPressOut={1000}
onPressOut={() => this._appendEvent('pressOut - 1000ms delay')}
delayLongPress={800}
onLongPress={() => this._appendEvent('longPress - 800ms delay')}>
Press Me
{this.state.eventLog.map((e, ii) => (
{e}
))}
);
}
_appendEvent = eventName => {
const limit = 6;
const eventLog = this.state.eventLog.slice(0, limit - 1);
eventLog.unshift(eventName);
this.setState({eventLog});
};
}
class ForceTouchExample extends React.Component<{}, $FlowFixMeState> {
state = {
force: 0,
};
_renderConsoleText = () => {
return forceTouchAvailable
? 'Force: ' + this.state.force.toFixed(3)
: '3D Touch is not available on this device';
};
render() {
return (
{this._renderConsoleText()}
true}
onResponderMove={event =>
this.setState({force: event.nativeEvent.force})
}
onResponderRelease={event => this.setState({force: 0})}>
Press Me
);
}
}
class TouchableHitSlop extends React.Component<{}, $FlowFixMeState> {
state = {
timesPressed: 0,
};
onPress = () => {
this.setState({
timesPressed: this.state.timesPressed + 1,
});
};
render() {
let log = '';
if (this.state.timesPressed > 1) {
log = this.state.timesPressed + 'x onPress';
} else if (this.state.timesPressed > 0) {
log = 'onPress';
}
return (
Press Outside This View
{log}
);
}
}
class TouchableDisabled extends React.Component<{}> {
render() {
return (
Disabled TouchableOpacity
Enabled TouchableOpacity
console.log('custom THW text - highlight')}>
Disabled TouchableHighlight
console.log('custom THW text - highlight')}>
Enabled TouchableHighlight
console.log('TWOF has been clicked')}
disabled={true}>
Disabled TouchableWithoutFeedback
console.log('TWOF has been clicked')}
disabled={false}>
Enabled TouchableWithoutFeedback
{Platform.OS === 'android' && (
console.log('custom TNF has been clicked')}
background={TouchableNativeFeedback.SelectableBackground()}>
Enabled TouchableNativeFeedback
)}
{Platform.OS === 'android' && (
console.log('custom TNF has been clicked')}
background={TouchableNativeFeedback.SelectableBackground()}>
Disabled TouchableNativeFeedback
)}
);
}
}
const heartImage = {
uri: 'https://pbs.twimg.com/media/BlXBfT3CQAA6cVZ.png:small',
};
const styles = StyleSheet.create({
row: {
justifyContent: 'center',
flexDirection: 'row',
},
centered: {
justifyContent: 'center',
},
image: {
width: 50,
height: 50,
},
text: {
fontSize: 16,
},
block: {
padding: 10,
},
button: {
color: '#007AFF',
},
disabledButton: {
color: '#007AFF',
opacity: 0.5,
},
nativeFeedbackButton: {
textAlign: 'center',
margin: 10,
},
hitSlopButton: {
color: 'white',
},
wrapper: {
borderRadius: 8,
},
wrapperCustom: {
borderRadius: 8,
padding: 6,
},
hitSlopWrapper: {
backgroundColor: 'red',
marginVertical: 30,
},
logBox: {
padding: 20,
margin: 10,
borderWidth: StyleSheet.hairlineWidth,
borderColor: '#f0f0f0',
backgroundColor: '#f9f9f9',
},
eventLogBox: {
padding: 10,
margin: 10,
height: 120,
borderWidth: StyleSheet.hairlineWidth,
borderColor: '#f0f0f0',
backgroundColor: '#f9f9f9',
},
forceTouchBox: {
padding: 10,
margin: 10,
borderWidth: StyleSheet.hairlineWidth,
borderColor: '#f0f0f0',
backgroundColor: '#f9f9f9',
alignItems: 'center',
},
textBlock: {
fontWeight: '500',
color: 'blue',
},
});
exports.displayName = (undefined: ?string);
exports.description = 'Touchable and onPress examples.';
exports.title = ' and onPress';
exports.examples = [
{
title: '',
description:
'TouchableHighlight works by adding an extra view with a ' +
'black background under the single child view. This works best when the ' +
'child view is fully opaque, although it can be made to work as a simple ' +
'background color change as well with the activeOpacity and ' +
'underlayColor props.',
render: function() {
return ;
},
},
{
title: '',
render: function() {
return ;
},
},
{
title: 'TouchableNativeFeedback with Animated child',
description:
'TouchableNativeFeedback can have an AnimatedComponent as a' +
'direct child.',
platform: 'android',
render: function() {
const mScale = new Animated.Value(1);
Animated.timing(mScale, {toValue: 0.3, duration: 1000}).start();
const style = {
backgroundColor: 'rgb(180, 64, 119)',
width: 200,
height: 100,
transform: [{scale: mScale}],
};
return (
);
},
},
{
title: ' with highlight',
render: function(): React.Element {
return ;
},
},
{
title: 'Touchable feedback events',
description:
' components accept onPress, onPressIn, ' +
'onPressOut, and onLongPress as props.',
render: function(): React.Element {
return ;
},
},
{
title: 'Touchable delay for events',
description:
' components also accept delayPressIn, ' +
'delayPressOut, and delayLongPress as props. These props impact the ' +
'timing of feedback events.',
render: function(): React.Element {
return ;
},
},
{
title: '3D Touch / Force Touch',
description:
'iPhone 6s and 6s plus support 3D touch, which adds a force property to touches',
render: function(): React.Element {
return ;
},
platform: 'ios',
},
{
title: 'Touchable Hit Slop',
description:
' components accept hitSlop prop which extends the touch area ' +
'without changing the view bounds.',
render: function(): React.Element {
return ;
},
},
{
title: 'Disabled Touchable*',
description:
' components accept disabled prop which prevents ' +
'any interaction with component',
render: function(): React.Element {
return ;
},
},
];