import * as React from 'react';
import { Component } from 'react';
import GenericTouchable, {
GenericTouchableProps,
TOUCHABLE_STATE,
} from './GenericTouchable';
import {
StyleSheet,
View,
TouchableHighlightProps as RNTouchableHighlightProps,
ColorValue,
ViewProps,
} from 'react-native';
interface State {
extraChildStyle: null | {
opacity?: number;
};
extraUnderlayStyle: null | {
backgroundColor?: ColorValue;
};
}
export type TouchableHighlightProps = RNTouchableHighlightProps &
GenericTouchableProps;
/**
* TouchableHighlight follows RN's implementation
*/
export default class TouchableHighlight extends Component<
TouchableHighlightProps,
State
> {
static defaultProps = {
...GenericTouchable.defaultProps,
activeOpacity: 0.85,
delayPressOut: 100,
underlayColor: 'black',
};
constructor(props: TouchableHighlightProps) {
super(props);
this.state = {
extraChildStyle: null,
extraUnderlayStyle: null,
};
}
// Copied from RN
showUnderlay = () => {
if (!this.hasPressHandler()) {
return;
}
this.setState({
extraChildStyle: {
opacity: this.props.activeOpacity,
},
extraUnderlayStyle: {
backgroundColor: this.props.underlayColor,
},
});
this.props.onShowUnderlay?.();
};
hasPressHandler = () =>
this.props.onPress ||
this.props.onPressIn ||
this.props.onPressOut ||
this.props.onLongPress;
hideUnderlay = () => {
this.setState({
extraChildStyle: null,
extraUnderlayStyle: null,
});
this.props.onHideUnderlay?.();
};
renderChildren() {
if (!this.props.children) {
return ;
}
const child = React.Children.only(
this.props.children
) as React.ReactElement; // TODO: not sure if OK but fixes error
return React.cloneElement(child, {
style: StyleSheet.compose(child.props.style, this.state.extraChildStyle),
});
}
onStateChange = (_from: number, to: number) => {
if (to === TOUCHABLE_STATE.BEGAN) {
this.showUnderlay();
} else if (
to === TOUCHABLE_STATE.UNDETERMINED ||
to === TOUCHABLE_STATE.MOVED_OUTSIDE
) {
this.hideUnderlay();
}
};
render() {
const { style = {}, ...rest } = this.props;
const { extraUnderlayStyle } = this.state;
return (
{this.renderChildren()}
);
}
}