107 lines
2.5 KiB
JavaScript
107 lines
2.5 KiB
JavaScript
import { useState } from "react";
|
|
import Animated, {
|
|
Easing,
|
|
interpolate,
|
|
useAnimatedStyle,
|
|
useSharedValue,
|
|
withTiming,
|
|
} from "react-native-reanimated";
|
|
import Card from "../Card";
|
|
import { Text, TouchableOpacity, View } from "react-native";
|
|
import MyIcon from "../Icon";
|
|
import { AppStyles } from "../../utils";
|
|
|
|
export function AccordionItem({
|
|
appContext,
|
|
title,
|
|
description,
|
|
cardTopicText,
|
|
disablePaddingBottom,
|
|
}) {
|
|
const shareValue = useSharedValue(0);
|
|
const [bodySectionHeight, setBodySectionHeight] = useState(0);
|
|
|
|
const bodyHeight = useAnimatedStyle(() => ({
|
|
height: interpolate(shareValue.value, [0, 1], [0, bodySectionHeight]),
|
|
}));
|
|
|
|
const iconStyle = useAnimatedStyle(() => {
|
|
return {
|
|
transform: [
|
|
{
|
|
rotate: `${interpolate(shareValue.value, [0, 1], [0, 180])}deg`,
|
|
},
|
|
],
|
|
};
|
|
});
|
|
|
|
const toggleExpanded = () => {
|
|
if (shareValue.value === 0) {
|
|
shareValue.value = withTiming(1, {
|
|
duration: 500,
|
|
easing: Easing.bezier(0.4, 0.0, 0.2, 1),
|
|
});
|
|
} else {
|
|
shareValue.value = withTiming(0, {
|
|
duration: 500,
|
|
easing: Easing.bezier(0.4, 0.0, 0.2, 1),
|
|
});
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Card
|
|
cardTopicText={cardTopicText}
|
|
disablePaddingBottom={disablePaddingBottom}
|
|
>
|
|
<TouchableOpacity activeOpacity={0.7} onPress={toggleExpanded}>
|
|
<View
|
|
style={{
|
|
flexDirection: "row",
|
|
justifyContent: "space-between",
|
|
alignItems: "center",
|
|
}}
|
|
>
|
|
<Text
|
|
style={[
|
|
{
|
|
color: appContext.appTheme.text,
|
|
width: "90%",
|
|
},
|
|
AppStyles.typography16,
|
|
]}
|
|
>
|
|
{title}
|
|
</Text>
|
|
|
|
<Animated.View style={iconStyle}>
|
|
<MyIcon name="chevron-down" size={24} />
|
|
</Animated.View>
|
|
</View>
|
|
</TouchableOpacity>
|
|
|
|
<Animated.View style={[{ overflow: "hidden", marginTop: 6 }, bodyHeight]}>
|
|
<View
|
|
style={{
|
|
position: "absolute",
|
|
bottom: 0,
|
|
left: 0,
|
|
}}
|
|
onLayout={(event) =>
|
|
setBodySectionHeight(event.nativeEvent.layout.height)
|
|
}
|
|
>
|
|
<Text
|
|
style={[
|
|
{ color: appContext.appTheme.textSecondary },
|
|
AppStyles.typography14,
|
|
]}
|
|
>
|
|
{description}
|
|
</Text>
|
|
</View>
|
|
</Animated.View>
|
|
</Card>
|
|
);
|
|
}
|