You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Collapsible.tsx 1.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. import { PropsWithChildren, useState } from 'react';
  2. import { StyleSheet, TouchableOpacity } from 'react-native';
  3. import { ThemedText } from '@/components/ThemedText';
  4. import { ThemedView } from '@/components/ThemedView';
  5. import { IconSymbol } from '@/components/ui/IconSymbol';
  6. import { Colors } from '@/constants/Colors';
  7. import { useColorScheme } from '@/hooks/useColorScheme';
  8. export function Collapsible({ children, title }: PropsWithChildren & { title: string }) {
  9. const [isOpen, setIsOpen] = useState(false);
  10. const theme = useColorScheme() ?? 'light';
  11. return (
  12. <ThemedView>
  13. <TouchableOpacity
  14. style={styles.heading}
  15. onPress={() => setIsOpen((value) => !value)}
  16. activeOpacity={0.8}>
  17. <IconSymbol
  18. name="chevron.right"
  19. size={18}
  20. weight="medium"
  21. color={theme === 'light' ? Colors.light.icon : Colors.dark.icon}
  22. style={{ transform: [{ rotate: isOpen ? '90deg' : '0deg' }] }}
  23. />
  24. <ThemedText type="defaultSemiBold">{title}</ThemedText>
  25. </TouchableOpacity>
  26. {isOpen && <ThemedView style={styles.content}>{children}</ThemedView>}
  27. </ThemedView>
  28. );
  29. }
  30. const styles = StyleSheet.create({
  31. heading: {
  32. flexDirection: 'row',
  33. alignItems: 'center',
  34. gap: 6,
  35. },
  36. content: {
  37. marginTop: 6,
  38. marginLeft: 24,
  39. },
  40. });