@uiw/react-native
Version:
UIW for React Native
144 lines (139 loc) • 3.81 kB
JavaScript
import React from 'react';
import { View, Dimensions, StyleSheet, Text, TouchableOpacity, Modal, Animated } from 'react-native';
export { default as ActionSheetItem } from './item';
let MainWidth = Dimensions.get('window').width;
let MainHeight = Dimensions.get('window').height;
export default class ActionSheet extends React.Component {
fadeAnim = new Animated.Value(0);
animatedRef = React.createRef();
constructor(props) {
super(props);
this.state = {
animatedHeight: 0,
stateVisible: false
};
}
onClose = () => {
Animated.timing(this.fadeAnim, {
toValue: 0,
duration: 150,
useNativeDriver: true
}).start(({
finished
}) => {
this.setState({
stateVisible: false
});
});
};
UNSAFE_componentWillReceiveProps(nextProps) {
if (nextProps.visible) {
this.setState({
stateVisible: true
});
Animated.timing(this.fadeAnim, {
toValue: 0,
duration: 0,
useNativeDriver: true
}).start(({
finished
}) => {
this.animatedRef.current && this.animatedRef.current.measure((_frameOffsetX, _frameOffsetY, _width, _height, pageOffsetX, pageOffsetY) => {
this.setState({
animatedHeight: _height
}, () => {
Animated.timing(this.fadeAnim, {
toValue: -_height,
duration: 150,
useNativeDriver: true
}).start();
});
});
});
} else {
this.onClose();
}
}
render() {
const {
children,
visible,
cancelText = '取消',
onCancel,
...other
} = this.props;
const {
stateVisible
} = this.state;
return <Modal animationType="fade" // slide none fade
transparent={true} visible={stateVisible} onRequestClose={this.onClose} {...other}>
<TouchableOpacity activeOpacity={1} style={[styles.position, styles.spread]} onPress={() => onCancel && this.onClose()}>
<Animated.View style={[styles.spread, styles.backdrop]}></Animated.View>
</TouchableOpacity>
<Animated.View style={[styles.actionSheet, {
bottom: -this.state.animatedHeight,
transform: [{
translateY: this.fadeAnim
}]
}]} ref={this.animatedRef}>
{React.Children.toArray(children).map((item, index) => <View key={index}>
{index !== 0 && <View style={styles.actionSheetItemDivider} />}
{item}
</View>)}
<View style={styles.divider} />
{typeof cancelText !== 'object' ? <TouchableOpacity activeOpacity={1} onPress={this.onClose}>
<View style={styles.actionSheetItem}>
<Text style={styles.actionSheetItemText}>{cancelText}</Text>
</View>
</TouchableOpacity> : <View>{cancelText}</View>}
</Animated.View>
</Modal>;
}
}
const styles = StyleSheet.create({
position: {
position: 'absolute',
backgroundColor: 'transparent',
top: 0,
bottom: 0,
left: 0,
right: 0,
zIndex: 9998
},
backdrop: {
backgroundColor: '#000',
opacity: 0.2
},
spread: {
width: MainWidth,
height: MainHeight
},
actionSheet: {
width: MainWidth,
position: 'absolute',
left: 0,
right: 0,
backgroundColor: '#fff',
zIndex: 9999
},
divider: {
backgroundColor: 'rgba(197,217,232,.3)',
width: MainWidth,
height: 6
},
actionSheetItemDivider: {
borderBottomColor: 'rgba(197,217,232,.3)',
borderBottomWidth: 2,
width: MainWidth
},
actionSheetItem: {
width: MainWidth,
height: 50,
justifyContent: 'center',
alignItems: 'center'
},
actionSheetItemText: {
fontSize: 20,
fontWeight: '400'
}
});