From a9ae08236e7353141a563973712625441f5a0c48 Mon Sep 17 00:00:00 2001 From: mogbonjubolaolasunkanmi-art Date: Mon, 27 Jul 2026 12:28:35 +0000 Subject: [PATCH] feat: commit solution for the listed issue --- components/shared-ui/collapsible.tsx | 46 ++++++++++++++++++++++++ components/shared-ui/icon-symbol.ios.tsx | 32 +++++++++++++++++ components/shared-ui/icon-symbol.tsx | 41 +++++++++++++++++++++ 3 files changed, 119 insertions(+) create mode 100644 components/shared-ui/collapsible.tsx create mode 100644 components/shared-ui/icon-symbol.ios.tsx create mode 100644 components/shared-ui/icon-symbol.tsx diff --git a/components/shared-ui/collapsible.tsx b/components/shared-ui/collapsible.tsx new file mode 100644 index 00000000..e66df267 --- /dev/null +++ b/components/shared-ui/collapsible.tsx @@ -0,0 +1,46 @@ +import { PropsWithChildren, useState } from 'react'; +import { StyleSheet, TouchableOpacity } from 'react-native'; + +import { ThemedText } from '@/components/themed-text'; +import { ThemedView } from '@/components/themed-view'; +import { IconSymbol } from '@/components/ui/icon-symbol'; +import { Colors } from '@/constants/theme'; +import { useTheme } from '@/store'; + +export const Collapsible = ({ children, title }: PropsWithChildren & { title: string }) => { + const [isOpen, setIsOpen] = useState(false); + const theme = useTheme(); + + return ( + + setIsOpen(value => !value)} + activeOpacity={0.8} + > + + + {title} + + {isOpen && {children}} + + ); +} + +const styles = StyleSheet.create({ + heading: { + flexDirection: 'row', + alignItems: 'center', + gap: 6, + }, + content: { + marginTop: 6, + marginLeft: 24, + }, +}); diff --git a/components/shared-ui/icon-symbol.ios.tsx b/components/shared-ui/icon-symbol.ios.tsx new file mode 100644 index 00000000..3ba00d17 --- /dev/null +++ b/components/shared-ui/icon-symbol.ios.tsx @@ -0,0 +1,32 @@ +import { SymbolView, SymbolViewProps, SymbolWeight } from 'expo-symbols'; +import { StyleProp, ViewStyle } from 'react-native'; + +export const IconSymbol = ({ + name, + size = 24, + color, + style, + weight = 'regular', +}: { + name: SymbolViewProps['name']; + size?: number; + color: string; + style?: StyleProp; + weight?: SymbolWeight; +}) => { + return ( + + ); +} diff --git a/components/shared-ui/icon-symbol.tsx b/components/shared-ui/icon-symbol.tsx new file mode 100644 index 00000000..288f07bf --- /dev/null +++ b/components/shared-ui/icon-symbol.tsx @@ -0,0 +1,41 @@ +// Fallback for using MaterialIcons on Android and web. + +import MaterialIcons from '@expo/vector-icons/MaterialIcons'; +import { SymbolWeight, SymbolViewProps } from 'expo-symbols'; +import { ComponentProps } from 'react'; +import { OpaqueColorValue, type StyleProp, type TextStyle } from 'react-native'; + +type IconMapping = Record['name']>; +type IconSymbolName = keyof typeof MAPPING; + +/** + * Add your SF Symbols to Material Icons mappings here. + * - see Material Icons in the [Icons Directory](https://icons.expo.fyi). + * - see SF Symbols in the [SF Symbols](https://developer.apple.com/sf-symbols/) app. + */ +const MAPPING = { + 'house.fill': 'home', + 'paperplane.fill': 'send', + 'chevron.left.forwardslash.chevron.right': 'code', + 'chevron.right': 'chevron-right', +} as IconMapping; + +/** + * An icon component that uses native SF Symbols on iOS, and Material Icons on Android and web. + * This ensures a consistent look across platforms, and optimal resource usage. + * Icon `name`s are based on SF Symbols and require manual mapping to Material Icons. + */ +export const IconSymbol = ({ + name, + size = 24, + color, + style, +}: { + name: IconSymbolName; + size?: number; + color: string | OpaqueColorValue; + style?: StyleProp; + weight?: SymbolWeight; +}) => { + return ; +}