Skip to content

Instantly share code, notes, and snippets.

@HerbertLim
Created September 15, 2020 05:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save HerbertLim/2cf57971fd3da927cf5c9633307c0412 to your computer and use it in GitHub Desktop.
Save HerbertLim/2cf57971fd3da927cf5c9633307c0412 to your computer and use it in GitHub Desktop.
GuideTips React Native component
import React, {Component} from 'react';
import {
View,
StyleSheet,
TouchableOpacity,
} from 'react-native';
import {
dispRate, isAndroid,
} from '../config';
const TIPS_TAIL_HEIGHT = 13*dispRate;
const TIPS_TAIL_WIDTH = 8*dispRate;
const TIPS_BORDER_WIDTH = 0;
const TIPS_BACKGROUND_COLOR = 'dimgrey';
export default class GuideTips extends Component {
static defaultProps = {
pointDirection: 'lower', // 'upper'
pointAlign: 'center', // 'left', 'right'
pointDistanceFromCenter: 0,
verticalAlign: 'top', // 'bottom'
horizontalAlign: 'left', //
backgroundColor: TIPS_BACKGROUND_COLOR,
}
timer = null;
componentDidMount() {
if (this.props.timeout > 0) {
this.timer = setTimeout(() => {
this.props.onClose()
}, this.props.timeout)
}
}
componentWillUnmount() {
if (this.timer) clearTimeout(this.timer)
}
getPositionStyle() {
const {
verticalAlign,
horizontalAlign,
verticalPosition,
horizontalPosition,
} = this.props;
let positionStyle = {}
let finalVerticalAlign = 'top';
let finalHorizontalAlign = 'left';
if (verticalAlign === 'top' || verticalAlign === 'bottom') {
finalVerticalAlign = verticalAlign;
}
if (horizontalAlign === 'right' || horizontalAlign === 'left') {
finalHorizontalAlign = horizontalAlign;
}
positionStyle[finalVerticalAlign] = verticalPosition;
positionStyle[finalHorizontalAlign] = horizontalPosition;
// console.log(`GuideTips.getPositionStyle: `, positionStyle)
return positionStyle;
}
getPointStyle() {
const {
pointDirection,
pointAlign,
pointLocation,
backgroundColor,
} = this.props;
let pointStyle = {};
const finalPointDirection = pointDirection ? pointDirection : 'lower';
pointStyle.transform = [{rotate: finalPointDirection === 'lower' ? '180deg' : '0deg'}];
if (pointAlign === 'right') {
pointStyle['marginRight'] = pointLocation;
} else {
pointStyle['marginLeft'] = pointLocation;
}
pointStyle.borderBottomColor = backgroundColor;
// console.log(`GuideTips.getPointStyle: `, pointStyle)
return pointStyle;
}
getTopStyle() {
const {
pointAlign,
} = this.props;
let topStyle = {
flexDirection: 'column',
alignItems: 'center',
}
if (pointAlign === 'left') {
topStyle.alignItems = 'flex-start';
}
if (pointAlign === 'right') {
topStyle.alignItems = 'flex-end';
}
// console.log(`GuideTips.getPointStyle: `, topStyle)
return topStyle;
}
onTouch = () => {
if (this.timer) clearTimeout(this.timer)
this.props.onClose()
}
render() {
const {
pointDirection,
backgroundColor,
isVisible,
} = this.props;
const finalPointDirection = pointDirection ? pointDirection : 'lower';
const pointStyle = this.getPointStyle()
const positionStyle = this.getPositionStyle()
const topAlignStyle = this.getTopStyle()
// console.log(`GuideTips.render: isVisible:${isVisible}, finalPointDirection:${finalPointDirection}`)
if (this.props.isVisible) {
return (
<TouchableOpacity
style={[styles.topContainer, positionStyle, topAlignStyle]}
onPress={this.onTouch}
>
{
finalPointDirection === 'upper' &&
<View style={[styles.tipsTriangle, pointStyle]}/>
}
<View style={[styles.tipsBubble, {backgroundColor}]}>
{this.props.children}
</View>
{/*
<View style={[styles.tipsTriangleBorder]}/>
*/}
{
finalPointDirection === 'lower' &&
<View style={[styles.tipsTriangle, pointStyle]}/>
}
</TouchableOpacity>
)
} else {
return null;
}
}
}
const styles = StyleSheet.create({
topContainer: {
position: 'absolute',
//flexDirection: 'column',
//alignItems: 'center',
borderRadius: 4*dispRate,
},
tipsBubble: {
justifyContent: 'center',
paddingVertical: 8*dispRate,
paddingHorizontal: 12*dispRate,
borderRadius: 5,
borderWidth: TIPS_BORDER_WIDTH,
backgroundColor: TIPS_BACKGROUND_COLOR,
marginVertical: isAndroid ? -1 : 0,
},
tipsTriangle: {
width: 0,
height: 0,
backgroundColor: 'transparent',
borderStyle: 'solid',
borderLeftWidth: TIPS_TAIL_WIDTH/2,
borderRightWidth: TIPS_TAIL_WIDTH/2,
borderBottomWidth: TIPS_TAIL_HEIGHT,
borderLeftColor: 'transparent',
borderRightColor: 'transparent',
borderBottomColor: TIPS_BACKGROUND_COLOR,
transform: [
{rotate: '180deg'}
],
},
tipsTriangleBorder: {
width: 0,
height: 0,
backgroundColor: 'transparent',
borderStyle: 'solid',
borderLeftWidth: TIPS_TAIL_WIDTH/2,
borderRightWidth: TIPS_TAIL_WIDTH/2,
borderBottomWidth: TIPS_TAIL_HEIGHT-1,
borderLeftColor: 'transparent',
borderRightColor: 'transparent',
transform: [
{rotate: '180deg'}
],
marginTop: -TIPS_BORDER_WIDTH,
},
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment