diff options
Diffstat (limited to 'components/Collapsible.tsx')
-rw-r--r-- | components/Collapsible.tsx | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/components/Collapsible.tsx b/components/Collapsible.tsx new file mode 100644 index 0000000..55bff2f --- /dev/null +++ b/components/Collapsible.tsx @@ -0,0 +1,45 @@ +import { PropsWithChildren, useState } from 'react'; +import { StyleSheet, TouchableOpacity } from 'react-native'; + +import { ThemedText } from '@/components/ThemedText'; +import { ThemedView } from '@/components/ThemedView'; +import { IconSymbol } from '@/components/ui/IconSymbol'; +import { Colors } from '@/constants/Colors'; +import { useColorScheme } from '@/hooks/useColorScheme'; + +export function Collapsible({ children, title }: PropsWithChildren & { title: string }) { + const [isOpen, setIsOpen] = useState(false); + const theme = useColorScheme() ?? 'light'; + + return ( + <ThemedView> + <TouchableOpacity + style={styles.heading} + onPress={() => setIsOpen((value) => !value)} + activeOpacity={0.8}> + <IconSymbol + name="chevron.right" + size={18} + weight="medium" + color={theme === 'light' ? Colors.light.icon : Colors.dark.icon} + style={{ transform: [{ rotate: isOpen ? '90deg' : '0deg' }] }} + /> + + <ThemedText type="defaultSemiBold">{title}</ThemedText> + </TouchableOpacity> + {isOpen && <ThemedView style={styles.content}>{children}</ThemedView>} + </ThemedView> + ); +} + +const styles = StyleSheet.create({ + heading: { + flexDirection: 'row', + alignItems: 'center', + gap: 6, + }, + content: { + marginTop: 6, + marginLeft: 24, + }, +}); |