forked from Expensify/App
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.tsx
78 lines (64 loc) · 2.18 KB
/
index.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import type {ReactNode} from 'react';
import React from 'react';
import type {StyleProp, ViewStyle} from 'react-native';
import {View} from 'react-native';
import type {SharedValue} from 'react-native-reanimated';
import Animated, {Easing, useAnimatedStyle, useDerivedValue, useSharedValue, withTiming} from 'react-native-reanimated';
type AccordionProps = {
/** Giving information whether the component is open */
isExpanded: SharedValue<boolean>;
/** Element that is inside Accordion */
children: ReactNode;
/** Duration of expansion animation */
duration?: number;
/** Additional external style */
style?: StyleProp<ViewStyle>;
/** Was toggle triggered */
isToggleTriggered: SharedValue<boolean>;
};
function Accordion({isExpanded, children, duration = 300, isToggleTriggered, style}: AccordionProps) {
const height = useSharedValue(0);
const derivedHeight = useDerivedValue(() => {
if (!isToggleTriggered.get()) {
return isExpanded.get() ? height.get() : 0;
}
return withTiming(height.get() * Number(isExpanded.get()), {
duration,
easing: Easing.inOut(Easing.quad),
});
});
const derivedOpacity = useDerivedValue(() => {
if (!isToggleTriggered.get()) {
return isExpanded.get() ? 1 : 0;
}
return withTiming(isExpanded.get() ? 1 : 0, {
duration,
easing: Easing.inOut(Easing.quad),
});
});
const animatedStyle = useAnimatedStyle(() => {
if (!isToggleTriggered.get() && !isExpanded.get()) {
return {
height: 0,
opacity: 0,
};
}
return {
height: !isToggleTriggered.get() ? undefined : derivedHeight.get(),
opacity: derivedOpacity.get(),
};
});
return (
<Animated.View style={[animatedStyle, style]}>
<View
onLayout={(e) => {
height.set(e.nativeEvent.layout.height);
}}
>
{children}
</View>
</Animated.View>
);
}
Accordion.displayName = 'Accordion';
export default Accordion;