react-native-navigation
Version:
React Native Navigation - truly native navigation for iOS and Android
115 lines (110 loc) • 3.26 kB
JavaScript
"use strict";
import * as React from 'react';
import * as PropTypes from 'prop-types';
import { View, Platform, findNodeHandle, TouchableNativeFeedback, TouchableWithoutFeedback } from 'react-native';
// Polyfill GestureResponderEvent type with additional `force` property (iOS)
import { jsx as _jsx } from "react/jsx-runtime";
const PREVIEW_DELAY = 350;
const PREVIEW_MIN_FORCE = 0.1;
const PREVIEW_TIMEOUT = 1250;
export class TouchablePreview extends React.PureComponent {
static propTypes = {
children: PropTypes.node,
touchableComponent: PropTypes.func,
onPress: PropTypes.func,
onPressIn: PropTypes.func,
onPeekIn: PropTypes.func,
onPeekOut: PropTypes.func,
label: PropTypes.string
};
static defaultProps = {
touchableComponent: TouchableWithoutFeedback
};
static peeking = false;
touchStartedAt = 0;
onRef = /*#__PURE__*/React.createRef();
onPress = () => {
const {
onPress
} = this.props;
if (typeof onPress !== 'function' || TouchablePreview.peeking) {
return;
}
return onPress();
};
onPressIn = () => {
if (Platform.OS === 'ios') {
const {
onPressIn
} = this.props;
if (!onPressIn) {
return;
}
const reactTag = findNodeHandle(this.onRef.current);
return onPressIn({
reactTag
});
}
// Other platforms don't support 3D Touch Preview API
return null;
};
onTouchStart = event => {
// Store a timestamp of the initial touch start
this.touchStartedAt = event.nativeEvent.timestamp;
};
onTouchMove = event => {
clearTimeout(this.timeout);
const {
force,
timestamp
} = event.nativeEvent;
const diff = timestamp - this.touchStartedAt;
if (force > PREVIEW_MIN_FORCE && diff > PREVIEW_DELAY) {
TouchablePreview.peeking = true;
if (typeof this.props.onPeekIn === 'function') {
this.props.onPeekIn();
}
}
//@ts-ignore
this.timeout = setTimeout(this.onTouchEnd, PREVIEW_TIMEOUT);
};
onTouchEnd = () => {
clearTimeout(this.timeout);
TouchablePreview.peeking = false;
if (typeof this.props.onPeekOut === 'function') {
this.props.onPeekOut();
}
};
render() {
const {
children,
touchableComponent,
...props
} = this.props;
// Default to TouchableWithoutFeedback for iOS if set to TouchableNativeFeedback
const Touchable = Platform.OS === 'ios' && touchableComponent instanceof TouchableNativeFeedback ? TouchableWithoutFeedback : touchableComponent;
// Wrap component with Touchable for handling platform touches
// and a single react View for detecting force and timing.
return (
/*#__PURE__*/
/**
* @TODO (Jin Shin 25 June 2020)
* Ignoring this for now so that it builds.
*/
// @ts-ignore
_jsx(Touchable, {
...props,
ref: this.onRef,
onPress: this.onPress,
onPressIn: this.onPressIn,
children: /*#__PURE__*/_jsx(View, {
onTouchStart: this.onTouchStart,
onTouchMove: this.onTouchMove,
onTouchEnd: this.onTouchEnd,
children: children
})
})
);
}
}
//# sourceMappingURL=TouchablePreview.js.map