@uiw/react-native
Version:
UIW for React Native
109 lines (105 loc) • 2.6 kB
JavaScript
import React from 'react';
import { View, StyleSheet, Text, Animated } from 'react-native';
import Item from './item';
import Button from '../Button';
import Icon from '../Icon';
export default class MenuDropdown extends React.Component {
static defaultProps = {
title: '菜单'
};
state = {
btnIcon: 'down',
visibleMenu: false,
listHeightValue: new Animated.Value(0),
listHeight: 0
};
handleonPress = () => {
const {
visibleMenu
} = this.state;
this.setState({
visibleMenu: !visibleMenu,
btnIcon: visibleMenu ? 'down' : 'up'
});
if (visibleMenu) {
this.animateClose();
} else {
this.animateStart();
}
};
animateStart = () => {
Animated.timing(this.state.listHeightValue, {
toValue: 1,
duration: 500,
useNativeDriver: false // 动画值在不同的驱动方式之间是不能兼容的。因此如果你在某个动画中启用了原生驱动,那么所有和此动画依赖相同动画值的其他动画也必须启用原生驱动。
}).start();
};
animateClose = () => {
this.setState({
listHeightValue: new Animated.Value(0)
});
};
menuContainer = event => {
const {
height
} = event.nativeEvent.layout;
this.setState({
listHeight: height
});
};
render() {
const {
title,
children,
size,
...btnProps
} = this.props;
const {
btnIcon,
listHeightValue,
listHeight
} = this.state;
return <View style={styles.menuBox}>
<Button {...btnProps} onPress={this.handleonPress} size={size}>
<Text>{title}</Text>
<Icon name={btnIcon} size={17} />
</Button>
{
/* {
visibleMenu && */
}
<Animated.View style={[styles.list, // eslint-disable-next-line react-native/no-inline-styles
{
opacity: listHeightValue,
height: listHeightValue.interpolate({
inputRange: [0, 1],
outputRange: [0, listHeight || 5]
}),
top: size === 'large' ? 35 : size === 'small' ? 21 : 30
}]}>
<View onLayout={this.menuContainer}>{children}</View>
</Animated.View>
{
/* } */
}
</View>;
}
}
MenuDropdown.Item = Item;
const styles = StyleSheet.create({
menuBox: {},
list: {
position: 'absolute',
zIndex: 1000,
left: 0,
right: 0,
top: 0,
height: 100,
marginTop: 10,
borderColor: '#ddd',
borderWidth: 1,
borderRadius: 1,
backgroundColor: '#fff',
overflow: 'hidden'
}
});