react-native-dropdown-ostyle
Version:
Dropdown list with full customization
109 lines (100 loc) • 2.89 kB
JavaScript
import { Pressable, StyleSheet, Text, View } from "react-native";
import React, { useState } from "react";
import Animated, {
interpolate,
useAnimatedStyle,
useSharedValue,
withTiming,
} from "react-native-reanimated";
const Dropdown = ({
title,
items = [],
style,
titleStyle,
headerStyle,
headerRight,
headerLeft,
itemsLeft,
itemsLestLeft,
itemStyle,
contentStyle,
itemTextStyle,
shown = false,
onPress = () => {},
}) => {
const [contentHeight, setContentHeight] = useState(0);
const progress = useSharedValue(shown ? 1 : 0);
const rExtendStyle = useAnimatedStyle(() => {
const height = interpolate(progress.value, [0, 1], [0, contentHeight]);
return {
height: height,
};
});
const rChevronStyle = useAnimatedStyle(() => {
const rotate = interpolate(progress.value, [0, 1], [0, 90]);
return {
transform: [{ rotateZ: rotate + "deg" }],
};
});
const handlePress = () => {
progress.value = withTiming(progress.value > 0.5 ? 0 : 1);
};
return (
<View style={style}>
<View>
<Pressable onPress={handlePress}>
<View style={[styles.header, headerStyle]}>
{headerLeft}
<Text style={titleStyle}>{title}</Text>
{headerRight && (
<Animated.View style={rChevronStyle}>{headerRight}</Animated.View>
)}
</View>
</Pressable>
{contentHeight ? (
<Animated.View style={[styles.content, contentStyle, rExtendStyle]}>
{items.map((item, index) => (
<Pressable
key={index}
onPress={onPress.bind({}, item, index, items)}
>
<View style={itemStyle}>
{items.length - 1 === index
? itemsLestLeft || itemsLeft
: itemsLeft}
<Text style={[itemTextStyle]}>{item}</Text>
</View>
</Pressable>
))}
</Animated.View>
) : (
<View
style={[styles.content, contentStyle]}
onLayout={(event) => {
setContentHeight(event.nativeEvent.layout.height);
}}
>
{items.map((item, index) => (
<View key={index} style={itemStyle}>
{items.length - 1 === index
? itemsLestLeft || itemsLeft
: itemsLeft}
<Text style={[itemTextStyle]}>{item}</Text>
</View>
))}
</View>
)}
</View>
</View>
);
};
export default Dropdown;
const styles = StyleSheet.create({
header: {
flexDirection: "row",
alignItems: "center",
},
content: {
overflow: "hidden",
},
});