@freeyeon2/react-native-swipe-up-down
Version:
197 lines (183 loc) • 5.6 kB
JavaScript
import React, { Component } from "react";
import {
Platform,
StyleSheet,
Text,
View,
PanResponder,
Dimensions,
LayoutAnimation,
TouchableOpacity,
} from "react-native";
import SwipeIcon from "./components/SwipeIcon";
import images from "./assets/images";
const MARGIN_TOP = Platform.OS === "ios" ? 20 : 0;
const DEVICE_HEIGHT = Dimensions.get("window").height - MARGIN_TOP;
export default class SwipeUpDown extends Component {
static defautProps = {
disablePressToShow: false,
};
constructor(props) {
super(props);
this.state = {
collapsed: true,
};
this.disablePressToShow = props.disablePressToShow;
this.SWIPE_HEIGHT = props.swipeHeight || 60;
this._panResponder = null;
this.top = this.SWIPE_HEIGHT;
this.height = this.SWIPE_HEIGHT;
this.customStyle = {
style: {
bottom: 0,
top: this.top,
height: this.height,
},
};
this.checkCollapsed = true;
this.showMini = this.showMini.bind(this);
this.showFull = this.showFull.bind(this);
}
componentWillMount() {
this._panResponder = PanResponder.create({
onMoveShouldSetPanResponder: (event, gestureState) => {
console.log(
"_onMoveShouldSetPanResponder__",
gestureState.dx,
gestureState.dy
);
return !(
Math.abs(gestureState.dx) < 5 && Math.abs(gestureState.dy) < 5
);
},
onPanResponderMove: this._onPanResponderMove.bind(this),
onPanResponderRelease: this._onPanResponderRelease.bind(this),
});
}
componentDidMount() {
this.props.hasRef && this.props.hasRef(this);
}
updateNativeProps() {
switch (this.props.animation) {
case "linear":
LayoutAnimation.linear();
break;
case "spring":
LayoutAnimation.spring();
break;
case "easeInEaseOut":
LayoutAnimation.easeInEaseOut();
break;
case "none":
default:
break;
}
this.viewRef.setNativeProps(this.customStyle);
}
_onPanResponderMove(event, gestureState) {
if (gestureState.dy > 0 && !this.checkCollapsed) {
// SWIPE DOWN
this.customStyle.style.top = this.top + gestureState.dy;
this.customStyle.style.height = DEVICE_HEIGHT - gestureState.dy;
this.swipeIconRef && this.swipeIconRef.setState({ icon: images.minus });
!this.state.collapsed && this.setState({ collapsed: true });
this.updateNativeProps();
} else if (this.checkCollapsed && gestureState.dy < -60) {
// SWIPE UP
this.top = 0;
this.customStyle.style.top = DEVICE_HEIGHT + gestureState.dy;
this.customStyle.style.height = -gestureState.dy + this.SWIPE_HEIGHT;
this.swipeIconRef &&
this.swipeIconRef.setState({ icon: images.minus, showIcon: true });
if (this.customStyle.style.top <= DEVICE_HEIGHT / 2) {
this.swipeIconRef &&
this.swipeIconRef.setState({
icon: images.arrow_down,
showIcon: true,
});
}
this.updateNativeProps();
this.state.collapsed && this.setState({ collapsed: false });
}
}
_onPanResponderRelease(event, gestureState) {
if (gestureState.dy < -100 || gestureState.dy < 100) {
this.showFull();
} else {
this.showMini();
}
}
showFull() {
const { onShowFull } = this.props;
this.customStyle.style.top = 0 + this.props.marginTop;
this.customStyle.style.height = DEVICE_HEIGHT - this.props.marginTop;
this.swipeIconRef &&
this.swipeIconRef.setState({ icon: images.arrow_down, showIcon: true });
this.updateNativeProps();
this.state.collapsed && this.setState({ collapsed: false });
this.checkCollapsed = false;
onShowFull && onShowFull();
}
showMini() {
const { onShowMini, itemMini } = this.props;
this.SWIPE_HEIGHT = this.props.miniHeight; //Avoid hiding when swiping down.
this.customStyle.style.top = itemMini
? DEVICE_HEIGHT - this.SWIPE_HEIGHT
: DEVICE_HEIGHT;
this.customStyle.style.height = itemMini ? this.SWIPE_HEIGHT : 0;
this.swipeIconRef && this.swipeIconRef.setState({ showIcon: false });
this.updateNativeProps();
!this.state.collapsed && this.setState({ collapsed: true });
this.checkCollapsed = true;
onShowMini && onShowMini();
}
render() {
const { itemMini, itemFull, style } = this.props;
const { collapsed } = this.state;
return (
<View
ref={(ref) => (this.viewRef = ref)}
{...this._panResponder.panHandlers}
style={[
styles.wrapSwipe,
{
height: this.SWIPE_HEIGHT,
marginTop: MARGIN_TOP,
},
!itemMini && collapsed && { marginBottom: -200 },
style,
]}
>
<SwipeIcon
onClose={() => this.showMini()}
hasRef={(ref) => (this.swipeIconRef = ref)}
/>
{collapsed ? (
itemMini ? (
<TouchableOpacity
activeOpacity={this.disablePressToShow ? 1 : 0.6}
style={{ height: this.SWIPE_HEIGHT }}
onPress={() => !this.disablePressToShow && this.showFull()}
>
{itemMini}
</TouchableOpacity>
) : null
) : (
itemFull
)}
</View>
);
}
}
const styles = StyleSheet.create({
wrapSwipe: {
padding: 10,
backgroundColor: "#ccc",
borderTopLeftRadius: 10,
borderTopRightRadius: 10,
position: "absolute",
bottom: 0,
left: 0,
right: 0,
},
});