Added theme components. Reorganized them. Prepping for Tech Tracker Rewrite
This commit is contained in:
		@@ -1,6 +1,6 @@
 | 
				
			|||||||
import { Image, StyleSheet, Platform } from 'react-native';
 | 
					import { Image, StyleSheet, Platform } from 'react-native';
 | 
				
			||||||
import ParallaxScrollView from '@/components/default/ParallaxScrollView';
 | 
					import ParallaxScrollView from '@/components/default/ParallaxScrollView';
 | 
				
			||||||
import { ThemedText, ThemedView } from '@/components/theme/Theme';
 | 
					import { ThemedText, ThemedView } from '@/components/theme';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const HomeScreen = () => {
 | 
					const HomeScreen = () => {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@ import { StyleSheet, Image, Platform } from 'react-native';
 | 
				
			|||||||
import { Collapsible } from '@/components/default/Collapsible';
 | 
					import { Collapsible } from '@/components/default/Collapsible';
 | 
				
			||||||
import { ExternalLink } from '@/components/default/ExternalLink';
 | 
					import { ExternalLink } from '@/components/default/ExternalLink';
 | 
				
			||||||
import ParallaxScrollView from '@/components/default/ParallaxScrollView';
 | 
					import ParallaxScrollView from '@/components/default/ParallaxScrollView';
 | 
				
			||||||
import { ThemedText, ThemedView } from '@/components/theme/Theme';
 | 
					import { ThemedText, ThemedView } from '@/components/theme';
 | 
				
			||||||
import { IconSymbol } from '@/components/ui/IconSymbol';
 | 
					import { IconSymbol } from '@/components/ui/IconSymbol';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const TabTwoScreen = () => {
 | 
					const TabTwoScreen = () => {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,6 @@
 | 
				
			|||||||
import { Link, Stack } from 'expo-router';
 | 
					import { Link, Stack } from 'expo-router';
 | 
				
			||||||
import { StyleSheet } from 'react-native';
 | 
					import { StyleSheet } from 'react-native';
 | 
				
			||||||
import { ThemedText, ThemedView } from '@/components/theme/Theme';
 | 
					import { ThemedText, ThemedTextButton, ThemedView } from '@/components/theme';
 | 
				
			||||||
import TextButton from '@/components/theme/buttons/TextButton';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const NotFoundScreen = () => {
 | 
					const NotFoundScreen = () => {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
@@ -10,7 +9,7 @@ const NotFoundScreen = () => {
 | 
				
			|||||||
      <ThemedView style={styles.container}>
 | 
					      <ThemedView style={styles.container}>
 | 
				
			||||||
        <ThemedText type='title'>This screen doesn't exist.</ThemedText>
 | 
					        <ThemedText type='title'>This screen doesn't exist.</ThemedText>
 | 
				
			||||||
        <Link href='/'>
 | 
					        <Link href='/'>
 | 
				
			||||||
          <TextButton width={200} height={45} text='Go to home screen' fontSize={24} />
 | 
					          <ThemedTextButton width={200} height={45} text='Go to home screen' fontSize={24} />
 | 
				
			||||||
        </Link>
 | 
					        </Link>
 | 
				
			||||||
      </ThemedView>
 | 
					      </ThemedView>
 | 
				
			||||||
    </>
 | 
					    </>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
import { PropsWithChildren, useState } from 'react';
 | 
					import { PropsWithChildren, useState } from 'react';
 | 
				
			||||||
import { StyleSheet, TouchableOpacity } from 'react-native';
 | 
					import { StyleSheet, TouchableOpacity } from 'react-native';
 | 
				
			||||||
import { ThemedText, ThemedView } from '@/components/theme/Theme';
 | 
					import { ThemedText, ThemedView } from '@/components/theme';
 | 
				
			||||||
import { IconSymbol } from '@/components/ui/IconSymbol';
 | 
					import { IconSymbol } from '@/components/ui/IconSymbol';
 | 
				
			||||||
import { Colors } from '@/constants/Colors';
 | 
					import { Colors } from '@/constants/Colors';
 | 
				
			||||||
import { useColorScheme } from '@/hooks/useColorScheme';
 | 
					import { useColorScheme } from '@/hooks/useColorScheme';
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,7 @@ import Animated, {
 | 
				
			|||||||
  useAnimatedStyle,
 | 
					  useAnimatedStyle,
 | 
				
			||||||
  useScrollViewOffset,
 | 
					  useScrollViewOffset,
 | 
				
			||||||
} from 'react-native-reanimated';
 | 
					} from 'react-native-reanimated';
 | 
				
			||||||
import { ThemedView } from '@/components/theme/Theme';
 | 
					import { ThemedView } from '@/components/theme';
 | 
				
			||||||
import { useBottomTabOverflow } from '@/components/ui/TabBarBackground';
 | 
					import { useBottomTabOverflow } from '@/components/ui/TabBarBackground';
 | 
				
			||||||
import { useColorScheme } from '@/hooks/useColorScheme';
 | 
					import { useColorScheme } from '@/hooks/useColorScheme';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,33 +0,0 @@
 | 
				
			|||||||
import Button from '@/components/theme/buttons/Button';
 | 
					 | 
				
			||||||
import { ThemedText } from '@/components/theme/Theme';
 | 
					 | 
				
			||||||
import { Colors } from '@/constants/Colors';
 | 
					 | 
				
			||||||
import { useColorScheme } from '@/hooks/useColorScheme';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const DEFAULT_FONT_SIZE = 16;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Props = {
 | 
					 | 
				
			||||||
  width?: number;
 | 
					 | 
				
			||||||
  height?: number;
 | 
					 | 
				
			||||||
  text: string;
 | 
					 | 
				
			||||||
  fontSize?: number;
 | 
					 | 
				
			||||||
  onPress?: () => void;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const TextButton = ({ width, height, text, fontSize, onPress }: Props) => {
 | 
					 | 
				
			||||||
  const scheme = useColorScheme() ?? 'dark';
 | 
					 | 
				
			||||||
  return (
 | 
					 | 
				
			||||||
    <Button width={width} height={height} onPress={onPress}>
 | 
					 | 
				
			||||||
      <ThemedText
 | 
					 | 
				
			||||||
        style={[
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            color: Colors[scheme].background,
 | 
					 | 
				
			||||||
            fontSize: fontSize ?? DEFAULT_FONT_SIZE,
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ]}
 | 
					 | 
				
			||||||
      >
 | 
					 | 
				
			||||||
        {text}
 | 
					 | 
				
			||||||
      </ThemedText>
 | 
					 | 
				
			||||||
    </Button>
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
export default TextButton;
 | 
					 | 
				
			||||||
@@ -1,25 +1,30 @@
 | 
				
			|||||||
import { StyleSheet, Pressable } from 'react-native';
 | 
					import React from 'react';
 | 
				
			||||||
import { ThemedView } from '@/components/theme/Theme';
 | 
					import { StyleSheet, Pressable, PressableProps } from 'react-native';
 | 
				
			||||||
 | 
					import { ThemedView } from '@/components/theme';
 | 
				
			||||||
import { Colors } from '@/constants/Colors';
 | 
					import { Colors } from '@/constants/Colors';
 | 
				
			||||||
import { useColorScheme } from '@/hooks/useColorScheme';
 | 
					import { useColorScheme } from '@/hooks/useColorScheme';
 | 
				
			||||||
import { StyleProp, ViewStyle } from 'react-native';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const DEFAULT_WIDTH = 320;
 | 
					const DEFAULT_WIDTH = 320;
 | 
				
			||||||
const DEFAULT_HEIGHT = 68;
 | 
					const DEFAULT_HEIGHT = 68;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Props = {
 | 
					type ThemedButtonProps = PressableProps & {
 | 
				
			||||||
  width?: number;
 | 
					  width?: number;
 | 
				
			||||||
  height?: number;
 | 
					  height?: number;
 | 
				
			||||||
  onPress?: () => void;
 | 
					  containerStyle?: object;
 | 
				
			||||||
 | 
					  buttonStyle?: object;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Button = ({
 | 
					const ThemedButton: React.FC<ThemedButtonProps> = ({
 | 
				
			||||||
  width,
 | 
					  width,
 | 
				
			||||||
  height,
 | 
					  height,
 | 
				
			||||||
  children,
 | 
					  children,
 | 
				
			||||||
  onPress,
 | 
					  containerStyle,
 | 
				
			||||||
}: Props & React.ComponentProps<typeof Pressable>) => {
 | 
					  buttonStyle,
 | 
				
			||||||
 | 
					  style,
 | 
				
			||||||
 | 
					  ...restProps // This now includes onPress automatically
 | 
				
			||||||
 | 
					}) => {
 | 
				
			||||||
  const scheme = useColorScheme() ?? 'dark';
 | 
					  const scheme = useColorScheme() ?? 'dark';
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <ThemedView
 | 
					    <ThemedView
 | 
				
			||||||
      style={[
 | 
					      style={[
 | 
				
			||||||
@@ -28,18 +33,25 @@ const Button = ({
 | 
				
			|||||||
          width: width ?? DEFAULT_WIDTH,
 | 
					          width: width ?? DEFAULT_WIDTH,
 | 
				
			||||||
          height: height ?? DEFAULT_HEIGHT,
 | 
					          height: height ?? DEFAULT_HEIGHT,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        containerStyle,
 | 
				
			||||||
      ]}
 | 
					      ]}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <Pressable
 | 
					      <Pressable
 | 
				
			||||||
        style={[styles.button, { backgroundColor: Colors[scheme].text }]}
 | 
					        style={[
 | 
				
			||||||
        onPress={onPress}
 | 
					          styles.button, 
 | 
				
			||||||
 | 
					          { backgroundColor: Colors[scheme].text },
 | 
				
			||||||
 | 
					          buttonStyle,
 | 
				
			||||||
 | 
					          style,
 | 
				
			||||||
 | 
					        ]}
 | 
				
			||||||
 | 
					        {...restProps} // This passes onPress and all other Pressable props
 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
        {children}
 | 
					        {children}
 | 
				
			||||||
      </Pressable>
 | 
					      </Pressable>
 | 
				
			||||||
    </ThemedView>
 | 
					    </ThemedView>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
export default Button;
 | 
					
 | 
				
			||||||
 | 
					export default ThemedButton;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const styles = StyleSheet.create({
 | 
					const styles = StyleSheet.create({
 | 
				
			||||||
  buttonContainer: {
 | 
					  buttonContainer: {
 | 
				
			||||||
							
								
								
									
										55
									
								
								components/theme/buttons/ThemedTextButton.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								components/theme/buttons/ThemedTextButton.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
				
			|||||||
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					import { TextStyle, PressableProps } from 'react-native';
 | 
				
			||||||
 | 
					import { ThemedButton, ThemedText } from '@/components/theme';
 | 
				
			||||||
 | 
					import { Colors } from '@/constants/Colors';
 | 
				
			||||||
 | 
					import { useColorScheme } from '@/hooks/useColorScheme';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const DEFAULT_FONT_SIZE = 16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Extend ThemedButton props (which already extends PressableProps)
 | 
				
			||||||
 | 
					type ThemedTextButtonProps = Omit<PressableProps, 'children'> & {
 | 
				
			||||||
 | 
					  width?: number;
 | 
				
			||||||
 | 
					  height?: number;
 | 
				
			||||||
 | 
					  text: string;
 | 
				
			||||||
 | 
					  fontSize?: number;
 | 
				
			||||||
 | 
					  textStyle?: TextStyle;
 | 
				
			||||||
 | 
					  containerStyle?: object;
 | 
				
			||||||
 | 
					  buttonStyle?: object;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const ThemedTextButton: React.FC<ThemedTextButtonProps> = ({
 | 
				
			||||||
 | 
					  width,
 | 
				
			||||||
 | 
					  height,
 | 
				
			||||||
 | 
					  text,
 | 
				
			||||||
 | 
					  fontSize,
 | 
				
			||||||
 | 
					  textStyle,
 | 
				
			||||||
 | 
					  containerStyle,
 | 
				
			||||||
 | 
					  buttonStyle,
 | 
				
			||||||
 | 
					  ...restProps // This includes onPress and all other Pressable props
 | 
				
			||||||
 | 
					}) => {
 | 
				
			||||||
 | 
					  const scheme = useColorScheme() ?? 'dark';
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <ThemedButton 
 | 
				
			||||||
 | 
					      width={width} 
 | 
				
			||||||
 | 
					      height={height}
 | 
				
			||||||
 | 
					      containerStyle={containerStyle}
 | 
				
			||||||
 | 
					      buttonStyle={buttonStyle}
 | 
				
			||||||
 | 
					      {...restProps}
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
 | 
					      <ThemedText
 | 
				
			||||||
 | 
					        style={[
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            color: Colors[scheme].background,
 | 
				
			||||||
 | 
					            fontSize: fontSize ?? DEFAULT_FONT_SIZE,
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          textStyle,
 | 
				
			||||||
 | 
					        ]}
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        {text}
 | 
				
			||||||
 | 
					      </ThemedText>
 | 
				
			||||||
 | 
					    </ThemedButton>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default ThemedTextButton;
 | 
				
			||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
import { View, type ViewProps } from 'react-native';
 | 
					import { type ViewProps } from 'react-native';
 | 
				
			||||||
import { Text, type TextProps, StyleSheet } from 'react-native';
 | 
					import { Text, type TextProps, StyleSheet } from 'react-native';
 | 
				
			||||||
import { useThemeColor } from '@/hooks/useThemeColor';
 | 
					import { useThemeColor } from '@/hooks/useThemeColor';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -12,12 +12,7 @@ export type ThemedTextProps = TextProps & {
 | 
				
			|||||||
  type?: 'default' | 'title' | 'defaultSemiBold' | 'subtitle' | 'link';
 | 
					  type?: 'default' | 'title' | 'defaultSemiBold' | 'subtitle' | 'link';
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const ThemedView = ({ style, lightColor, darkColor, ...otherProps }: ThemedViewProps) => {
 | 
					const ThemedText = ({
 | 
				
			||||||
  const backgroundColor = useThemeColor({ light: lightColor, dark: darkColor }, 'background');
 | 
					 | 
				
			||||||
  return <View style={[{ backgroundColor }, style]} {...otherProps} />;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const ThemedText = ({
 | 
					 | 
				
			||||||
  style,
 | 
					  style,
 | 
				
			||||||
  lightColor,
 | 
					  lightColor,
 | 
				
			||||||
  darkColor,
 | 
					  darkColor,
 | 
				
			||||||
@@ -40,6 +35,7 @@ export const ThemedText = ({
 | 
				
			|||||||
    />
 | 
					    />
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					export default ThemedText;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const styles = StyleSheet.create({
 | 
					const styles = StyleSheet.create({
 | 
				
			||||||
  default: {
 | 
					  default: {
 | 
				
			||||||
							
								
								
									
										13
									
								
								components/theme/default/ThemedView.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								components/theme/default/ThemedView.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					import { View, type ViewProps } from 'react-native';
 | 
				
			||||||
 | 
					import { useThemeColor } from '@/hooks/useThemeColor';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type ThemedViewProps = ViewProps & {
 | 
				
			||||||
 | 
					  lightColor?: string;
 | 
				
			||||||
 | 
					  darkColor?: string;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const ThemedView = ({ style, lightColor, darkColor, ...otherProps }: ThemedViewProps) => {
 | 
				
			||||||
 | 
					  const backgroundColor = useThemeColor({ light: lightColor, dark: darkColor }, 'background');
 | 
				
			||||||
 | 
					  return <View style={[{ backgroundColor }, style]} {...otherProps} />;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					export default ThemedView;
 | 
				
			||||||
							
								
								
									
										25
									
								
								components/theme/index.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								components/theme/index.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					import ThemedText from '@/components/theme/default/ThemedText';
 | 
				
			||||||
 | 
					import ThemedView from '@/components/theme/default/ThemedView';
 | 
				
			||||||
 | 
					import ThemedButton from '@/components/theme/buttons/ThemedButton';
 | 
				
			||||||
 | 
					import ThemedTextButton from '@/components/theme/buttons/ThemedTextButton';
 | 
				
			||||||
 | 
					import ThemedTextInput from '@/components/theme/inputs/ThemedTextInput';
 | 
				
			||||||
 | 
					import ThemedCard from '@/components/theme/ui/ThemedCard';
 | 
				
			||||||
 | 
					import ThemedBadge from '@/components/theme/ui/ThemedBadge';
 | 
				
			||||||
 | 
					import ThemedIcon from '@/components/theme/ui/ThemedIcon';
 | 
				
			||||||
 | 
					import ThemedSwitch from '@/components/theme/inputs/ThemedSwitch';
 | 
				
			||||||
 | 
					import ThemedAvatar from '@/components/theme/ui/ThemedAvatar';
 | 
				
			||||||
 | 
					import ThemedSearchBar from '@/components/theme/inputs/ThemedSearchBar';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export {
 | 
				
			||||||
 | 
					  ThemedText,
 | 
				
			||||||
 | 
					  ThemedView,
 | 
				
			||||||
 | 
					  ThemedButton,
 | 
				
			||||||
 | 
					  ThemedTextButton,
 | 
				
			||||||
 | 
					  ThemedTextInput,
 | 
				
			||||||
 | 
					  ThemedCard,
 | 
				
			||||||
 | 
					  ThemedBadge,
 | 
				
			||||||
 | 
					  ThemedIcon,
 | 
				
			||||||
 | 
					  ThemedSwitch,
 | 
				
			||||||
 | 
					  ThemedAvatar,
 | 
				
			||||||
 | 
					  ThemedSearchBar,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										62
									
								
								components/theme/inputs/ThemedSearchBar.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								components/theme/inputs/ThemedSearchBar.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
				
			|||||||
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					import { StyleSheet, ViewProps, View, DimensionValue } from 'react-native';
 | 
				
			||||||
 | 
					import { Ionicons } from '@expo/vector-icons';
 | 
				
			||||||
 | 
					import { ThemedTextInput } from '@/components/theme';
 | 
				
			||||||
 | 
					import { Colors } from '@/constants/Colors';
 | 
				
			||||||
 | 
					import { useColorScheme } from '@/hooks/useColorScheme';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ThemedSearchBarProps = ViewProps & {
 | 
				
			||||||
 | 
					  placeholder?: string;
 | 
				
			||||||
 | 
					  value: string;
 | 
				
			||||||
 | 
					  onChangeText: (text: string) => void;
 | 
				
			||||||
 | 
					  width?: DimensionValue;
 | 
				
			||||||
 | 
					  height?: number;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const ThemedSearchBar: React.FC<ThemedSearchBarProps> = ({
 | 
				
			||||||
 | 
					  placeholder = 'Search',
 | 
				
			||||||
 | 
					  value,
 | 
				
			||||||
 | 
					  onChangeText,
 | 
				
			||||||
 | 
					  width = '100%',
 | 
				
			||||||
 | 
					  height = 40,
 | 
				
			||||||
 | 
					  style,
 | 
				
			||||||
 | 
					  ...restProps
 | 
				
			||||||
 | 
					}) => {
 | 
				
			||||||
 | 
					  const scheme = useColorScheme() ?? 'dark';
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <View style={[styles.container, { width }, style]} {...restProps}>
 | 
				
			||||||
 | 
					      <Ionicons 
 | 
				
			||||||
 | 
					        name="search" 
 | 
				
			||||||
 | 
					        size={20} 
 | 
				
			||||||
 | 
					        color={Colors[scheme].text} 
 | 
				
			||||||
 | 
					        style={styles.icon} 
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
 | 
					      <ThemedTextInput
 | 
				
			||||||
 | 
					        placeholder={placeholder}
 | 
				
			||||||
 | 
					        value={value}
 | 
				
			||||||
 | 
					        onChangeText={onChangeText}
 | 
				
			||||||
 | 
					        height={height}
 | 
				
			||||||
 | 
					        width={width}
 | 
				
			||||||
 | 
					        style={styles.input}
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
 | 
					    </View>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const styles = StyleSheet.create({
 | 
				
			||||||
 | 
					  container: {
 | 
				
			||||||
 | 
					    flexDirection: 'row',
 | 
				
			||||||
 | 
					    alignItems: 'center',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  icon: {
 | 
				
			||||||
 | 
					    position: 'absolute',
 | 
				
			||||||
 | 
					    zIndex: 1,
 | 
				
			||||||
 | 
					    left: 15,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  input: {
 | 
				
			||||||
 | 
					    paddingLeft: 45,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default ThemedSearchBar;
 | 
				
			||||||
							
								
								
									
										26
									
								
								components/theme/inputs/ThemedSwitch.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								components/theme/inputs/ThemedSwitch.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					import { Switch, SwitchProps } from 'react-native';
 | 
				
			||||||
 | 
					import { Colors } from '@/constants/Colors';
 | 
				
			||||||
 | 
					import { useColorScheme } from '@/hooks/useColorScheme';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ThemedSwitchProps = SwitchProps;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const ThemedSwitch: React.FC<ThemedSwitchProps> = ({
 | 
				
			||||||
 | 
					  ...props
 | 
				
			||||||
 | 
					}) => {
 | 
				
			||||||
 | 
					  const scheme = useColorScheme() ?? 'dark';
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <Switch
 | 
				
			||||||
 | 
					      trackColor={{ 
 | 
				
			||||||
 | 
					        false: Colors[scheme].border, 
 | 
				
			||||||
 | 
					        true: Colors[scheme].tint + '80' 
 | 
				
			||||||
 | 
					      }}
 | 
				
			||||||
 | 
					      thumbColor={props.value ? Colors[scheme].tint : Colors[scheme].card}
 | 
				
			||||||
 | 
					      ios_backgroundColor={Colors[scheme].border}
 | 
				
			||||||
 | 
					      {...props}
 | 
				
			||||||
 | 
					    />
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default ThemedSwitch;
 | 
				
			||||||
							
								
								
									
										63
									
								
								components/theme/inputs/ThemedTextInput.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								components/theme/inputs/ThemedTextInput.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
				
			|||||||
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					import { StyleSheet, TextInput, TextInputProps, DimensionValue } from 'react-native';
 | 
				
			||||||
 | 
					import { ThemedView } from '@/components/theme';
 | 
				
			||||||
 | 
					import { Colors } from '@/constants/Colors';
 | 
				
			||||||
 | 
					import { useColorScheme } from '@/hooks/useColorScheme';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const DEFAULT_WIDTH = 320;
 | 
				
			||||||
 | 
					const DEFAULT_HEIGHT = 50;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ThemedTextInputProps = TextInputProps & {
 | 
				
			||||||
 | 
					  width?: DimensionValue;
 | 
				
			||||||
 | 
					  height?: DimensionValue
 | 
				
			||||||
 | 
					  containerStyle?: object;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const ThemedTextInput: React.FC<ThemedTextInputProps> = ({
 | 
				
			||||||
 | 
					  width = DEFAULT_WIDTH,
 | 
				
			||||||
 | 
					  height = DEFAULT_HEIGHT,
 | 
				
			||||||
 | 
					  containerStyle,
 | 
				
			||||||
 | 
					  style,
 | 
				
			||||||
 | 
					  ...restProps
 | 
				
			||||||
 | 
					}) => {
 | 
				
			||||||
 | 
					  const scheme = useColorScheme() ?? 'dark';
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <ThemedView
 | 
				
			||||||
 | 
					      style={[
 | 
				
			||||||
 | 
					        styles.inputContainer,
 | 
				
			||||||
 | 
					        { width, height },
 | 
				
			||||||
 | 
					        containerStyle,
 | 
				
			||||||
 | 
					      ]}
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
 | 
					      <TextInput
 | 
				
			||||||
 | 
					        style={[
 | 
				
			||||||
 | 
					          styles.input,
 | 
				
			||||||
 | 
					          { 
 | 
				
			||||||
 | 
					            color: Colors[scheme].text,
 | 
				
			||||||
 | 
					            backgroundColor: Colors[scheme].background,
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          style,
 | 
				
			||||||
 | 
					        ]}
 | 
				
			||||||
 | 
					        placeholderTextColor={Colors[scheme].text + '80'} // 50% opacity
 | 
				
			||||||
 | 
					        {...restProps}
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
 | 
					    </ThemedView>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default ThemedTextInput;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const styles = StyleSheet.create({
 | 
				
			||||||
 | 
					  inputContainer: {
 | 
				
			||||||
 | 
					    padding: 3,
 | 
				
			||||||
 | 
					    borderRadius: 10,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  input: {
 | 
				
			||||||
 | 
					    width: '100%',
 | 
				
			||||||
 | 
					    height: '100%',
 | 
				
			||||||
 | 
					    borderRadius: 8,
 | 
				
			||||||
 | 
					    paddingHorizontal: 15,
 | 
				
			||||||
 | 
					    fontSize: 16,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
							
								
								
									
										84
									
								
								components/theme/ui/ThemedAvatar.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								components/theme/ui/ThemedAvatar.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,84 @@
 | 
				
			|||||||
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					import { StyleSheet, Image, ImageProps, View } from 'react-native';
 | 
				
			||||||
 | 
					import { ThemedText } from '@/components/theme';
 | 
				
			||||||
 | 
					import { Colors } from '@/constants/Colors';
 | 
				
			||||||
 | 
					import { useColorScheme } from '@/hooks/useColorScheme';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ThemedAvatarProps = Omit<ImageProps, 'source'> & {
 | 
				
			||||||
 | 
					  size?: number;
 | 
				
			||||||
 | 
					  source?: ImageProps['source'];
 | 
				
			||||||
 | 
					  name?: string;
 | 
				
			||||||
 | 
					  borderWidth?: number;
 | 
				
			||||||
 | 
					  borderColor?: string;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const ThemedAvatar: React.FC<ThemedAvatarProps> = ({
 | 
				
			||||||
 | 
					  size = 50,
 | 
				
			||||||
 | 
					  source,
 | 
				
			||||||
 | 
					  name,
 | 
				
			||||||
 | 
					  borderWidth = 0,
 | 
				
			||||||
 | 
					  borderColor,
 | 
				
			||||||
 | 
					  style,
 | 
				
			||||||
 | 
					  ...restProps
 | 
				
			||||||
 | 
					}) => {
 | 
				
			||||||
 | 
					  const scheme = useColorScheme() ?? 'dark';
 | 
				
			||||||
 | 
					  const border = borderColor || Colors[scheme].tint;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // Get initials from name
 | 
				
			||||||
 | 
					  const getInitials = (name?: string) => {
 | 
				
			||||||
 | 
					    if (!name) return '';
 | 
				
			||||||
 | 
					    return name
 | 
				
			||||||
 | 
					      .split(' ')
 | 
				
			||||||
 | 
					      .map(part => part[0])
 | 
				
			||||||
 | 
					      .join('')
 | 
				
			||||||
 | 
					      .toUpperCase()
 | 
				
			||||||
 | 
					      .substring(0, 2);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  const initials = getInitials(name);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <View
 | 
				
			||||||
 | 
					      style={[
 | 
				
			||||||
 | 
					        styles.container,
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          width: size,
 | 
				
			||||||
 | 
					          height: size,
 | 
				
			||||||
 | 
					          borderRadius: size / 2,
 | 
				
			||||||
 | 
					          borderWidth,
 | 
				
			||||||
 | 
					          borderColor: border,
 | 
				
			||||||
 | 
					          backgroundColor: source ? 'transparent' : Colors[scheme].tint,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      ]}
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
 | 
					      {source ? (
 | 
				
			||||||
 | 
					        <Image
 | 
				
			||||||
 | 
					          source={source}
 | 
				
			||||||
 | 
					          style={[
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              width: size - 2 * borderWidth,
 | 
				
			||||||
 | 
					              height: size - 2 * borderWidth,
 | 
				
			||||||
 | 
					              borderRadius: (size - 2 * borderWidth) / 2,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            style,
 | 
				
			||||||
 | 
					          ]}
 | 
				
			||||||
 | 
					          {...restProps}
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					      ) : (
 | 
				
			||||||
 | 
					        <ThemedText style={{ color: Colors[scheme].background, fontSize: size * 0.4 }}>
 | 
				
			||||||
 | 
					          {initials}
 | 
				
			||||||
 | 
					        </ThemedText>
 | 
				
			||||||
 | 
					      )}
 | 
				
			||||||
 | 
					    </View>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const styles = StyleSheet.create({
 | 
				
			||||||
 | 
					  container: {
 | 
				
			||||||
 | 
					    alignItems: 'center',
 | 
				
			||||||
 | 
					    justifyContent: 'center',
 | 
				
			||||||
 | 
					    overflow: 'hidden',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default ThemedAvatar;
 | 
				
			||||||
							
								
								
									
										62
									
								
								components/theme/ui/ThemedBadge.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								components/theme/ui/ThemedBadge.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
				
			|||||||
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					import { StyleSheet, ViewProps } from 'react-native';
 | 
				
			||||||
 | 
					import { ThemedView, ThemedText } from '@/components/theme';
 | 
				
			||||||
 | 
					import { Colors } from '@/constants/Colors';
 | 
				
			||||||
 | 
					import { useColorScheme } from '@/hooks/useColorScheme';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ThemedBadgeProps = ViewProps & {
 | 
				
			||||||
 | 
					  value: number | string;
 | 
				
			||||||
 | 
					  size?: number;
 | 
				
			||||||
 | 
					  color?: string;
 | 
				
			||||||
 | 
					  textColor?: string;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const ThemedBadge: React.FC<ThemedBadgeProps> = ({
 | 
				
			||||||
 | 
					  value,
 | 
				
			||||||
 | 
					  size = 24,
 | 
				
			||||||
 | 
					  color,
 | 
				
			||||||
 | 
					  textColor,
 | 
				
			||||||
 | 
					  style,
 | 
				
			||||||
 | 
					  ...restProps
 | 
				
			||||||
 | 
					}) => {
 | 
				
			||||||
 | 
					  const scheme = useColorScheme() ?? 'dark';
 | 
				
			||||||
 | 
					  const badgeColor = color || Colors[scheme].tint;
 | 
				
			||||||
 | 
					  const badgeTextColor = textColor || Colors[scheme].background;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <ThemedView
 | 
				
			||||||
 | 
					      style={[
 | 
				
			||||||
 | 
					        styles.badge,
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          width: size,
 | 
				
			||||||
 | 
					          height: size,
 | 
				
			||||||
 | 
					          borderRadius: size / 2,
 | 
				
			||||||
 | 
					          backgroundColor: badgeColor,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        style,
 | 
				
			||||||
 | 
					      ]}
 | 
				
			||||||
 | 
					      {...restProps}
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
 | 
					      <ThemedText 
 | 
				
			||||||
 | 
					        style={[
 | 
				
			||||||
 | 
					          styles.text, 
 | 
				
			||||||
 | 
					          { color: badgeTextColor, fontSize: size * 0.5 }
 | 
				
			||||||
 | 
					        ]}
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        {value}
 | 
				
			||||||
 | 
					      </ThemedText>
 | 
				
			||||||
 | 
					    </ThemedView>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const styles = StyleSheet.create({
 | 
				
			||||||
 | 
					  badge: {
 | 
				
			||||||
 | 
					    alignItems: 'center',
 | 
				
			||||||
 | 
					    justifyContent: 'center',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  text: {
 | 
				
			||||||
 | 
					    fontWeight: 'bold',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default ThemedBadge;
 | 
				
			||||||
							
								
								
									
										64
									
								
								components/theme/ui/ThemedCard.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								components/theme/ui/ThemedCard.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
				
			|||||||
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					import { StyleSheet, ViewProps, Platform, DimensionValue } from 'react-native';
 | 
				
			||||||
 | 
					import { ThemedView } from '@/components/theme';
 | 
				
			||||||
 | 
					import { Colors } from '@/constants/Colors';
 | 
				
			||||||
 | 
					import { useColorScheme } from '@/hooks/useColorScheme';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ThemedCardProps = ViewProps & {
 | 
				
			||||||
 | 
					  width?: DimensionValue;
 | 
				
			||||||
 | 
					  height?: DimensionValue;
 | 
				
			||||||
 | 
					  padding?: number;
 | 
				
			||||||
 | 
					  elevation?: number;
 | 
				
			||||||
 | 
					  borderRadius?: number;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const ThemedCard: React.FC<ThemedCardProps> = ({
 | 
				
			||||||
 | 
					  width = '100%',
 | 
				
			||||||
 | 
					  height,
 | 
				
			||||||
 | 
					  padding = 16,
 | 
				
			||||||
 | 
					  elevation = 3,
 | 
				
			||||||
 | 
					  borderRadius = 12,
 | 
				
			||||||
 | 
					  style,
 | 
				
			||||||
 | 
					  children,
 | 
				
			||||||
 | 
					  ...restProps
 | 
				
			||||||
 | 
					}) => {
 | 
				
			||||||
 | 
					  const scheme = useColorScheme() ?? 'dark';
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <ThemedView
 | 
				
			||||||
 | 
					      style={[
 | 
				
			||||||
 | 
					        styles.card,
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          width,
 | 
				
			||||||
 | 
					          height,
 | 
				
			||||||
 | 
					          padding,
 | 
				
			||||||
 | 
					          borderRadius,
 | 
				
			||||||
 | 
					          backgroundColor: Colors[scheme].card,
 | 
				
			||||||
 | 
					          ...Platform.select({
 | 
				
			||||||
 | 
					            ios: {
 | 
				
			||||||
 | 
					              shadowColor: Colors[scheme].text,
 | 
				
			||||||
 | 
					              shadowOffset: { width: 0, height: elevation/2 },
 | 
				
			||||||
 | 
					              shadowOpacity: 0.1,
 | 
				
			||||||
 | 
					              shadowRadius: elevation,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            android: {
 | 
				
			||||||
 | 
					              elevation,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					          }),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        style,
 | 
				
			||||||
 | 
					      ]}
 | 
				
			||||||
 | 
					      {...restProps}
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
 | 
					      {children}
 | 
				
			||||||
 | 
					    </ThemedView>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const styles = StyleSheet.create({
 | 
				
			||||||
 | 
					  card: {
 | 
				
			||||||
 | 
					    overflow: 'hidden',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default ThemedCard;
 | 
				
			||||||
							
								
								
									
										37
									
								
								components/theme/ui/ThemedDivider.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								components/theme/ui/ThemedDivider.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					import { StyleSheet, ViewProps, View, DimensionValue } from 'react-native';
 | 
				
			||||||
 | 
					import { Colors } from '@/constants/Colors';
 | 
				
			||||||
 | 
					import { useColorScheme } from '@/hooks/useColorScheme';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ThemedDividerProps = ViewProps & {
 | 
				
			||||||
 | 
					  orientation?: 'horizontal' | 'vertical';
 | 
				
			||||||
 | 
					  thickness?: DimensionValue
 | 
				
			||||||
 | 
					  length?: DimensionValue
 | 
				
			||||||
 | 
					  color?: string;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const ThemedDivider: React.FC<ThemedDividerProps> = ({
 | 
				
			||||||
 | 
					  orientation = 'horizontal',
 | 
				
			||||||
 | 
					  thickness = 1,
 | 
				
			||||||
 | 
					  length = '100%',
 | 
				
			||||||
 | 
					  style,
 | 
				
			||||||
 | 
					  ...restProps
 | 
				
			||||||
 | 
					}) => {
 | 
				
			||||||
 | 
					  const scheme = useColorScheme() ?? 'dark';
 | 
				
			||||||
 | 
					  const color = restProps.color || Colors[scheme].border;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <View
 | 
				
			||||||
 | 
					      style={[
 | 
				
			||||||
 | 
					        orientation === 'horizontal' 
 | 
				
			||||||
 | 
					          ? { height: thickness, width: length } 
 | 
				
			||||||
 | 
					          : { width: thickness, height: length },
 | 
				
			||||||
 | 
					        { backgroundColor: color },
 | 
				
			||||||
 | 
					        style,
 | 
				
			||||||
 | 
					      ]}
 | 
				
			||||||
 | 
					      {...restProps}
 | 
				
			||||||
 | 
					    />
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default ThemedDivider;
 | 
				
			||||||
							
								
								
									
										34
									
								
								components/theme/ui/ThemedIcon.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								components/theme/ui/ThemedIcon.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					import { StyleSheet, ViewProps } from 'react-native';
 | 
				
			||||||
 | 
					import { Ionicons } from '@expo/vector-icons'; // Or your preferred icon library
 | 
				
			||||||
 | 
					import { Colors } from '@/constants/Colors';
 | 
				
			||||||
 | 
					import { useColorScheme } from '@/hooks/useColorScheme';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ThemedIconProps = ViewProps & {
 | 
				
			||||||
 | 
					  name: string;
 | 
				
			||||||
 | 
					  size?: number;
 | 
				
			||||||
 | 
					  color?: string;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const ThemedIcon: React.FC<ThemedIconProps> = ({
 | 
				
			||||||
 | 
					  name,
 | 
				
			||||||
 | 
					  size = 24,
 | 
				
			||||||
 | 
					  color,
 | 
				
			||||||
 | 
					  style,
 | 
				
			||||||
 | 
					  ...restProps
 | 
				
			||||||
 | 
					}) => {
 | 
				
			||||||
 | 
					  const scheme = useColorScheme() ?? 'dark';
 | 
				
			||||||
 | 
					  const iconColor = color || Colors[scheme].text;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <Ionicons
 | 
				
			||||||
 | 
					      name={name}
 | 
				
			||||||
 | 
					      size={size}
 | 
				
			||||||
 | 
					      color={iconColor}
 | 
				
			||||||
 | 
					      style={style}
 | 
				
			||||||
 | 
					      {...restProps}
 | 
				
			||||||
 | 
					    />
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default ThemedIcon;
 | 
				
			||||||
@@ -1,26 +1,50 @@
 | 
				
			|||||||
/**
 | 
					// Dark mode colors
 | 
				
			||||||
 * Below are the colors that are used in the app. The colors are defined in the light and dark mode.
 | 
					const dark = '#2e2f3d';
 | 
				
			||||||
 * There are many other ways to style your app. For example, [Nativewind](https://www.nativewind.dev/), [Tamagui](https://tamagui.dev/), [unistyles](https://reactnativeunistyles.vercel.app), etc.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const tintColorLight = '#0a7ea4';
 | 
					 | 
				
			||||||
const tintColorDark = '#fff';
 | 
					const tintColorDark = '#fff';
 | 
				
			||||||
 | 
					const iconColorDark = '#9BA1A6';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Light mode colors
 | 
				
			||||||
 | 
					const light = '#ECEDEE';
 | 
				
			||||||
 | 
					const tintColorLight = '#0a7ea4';
 | 
				
			||||||
 | 
					const iconColorLight = '#687076';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const Colors = {
 | 
					export const Colors = {
 | 
				
			||||||
  light: {
 | 
					  light: {
 | 
				
			||||||
    text: '#11181C',
 | 
					    text: dark,
 | 
				
			||||||
    background: '#fff',
 | 
					    background: light,
 | 
				
			||||||
    tint: tintColorLight,
 | 
					    tint: tintColorLight,
 | 
				
			||||||
    icon: '#687076',
 | 
					    icon: iconColorLight,
 | 
				
			||||||
    tabIconDefault: '#687076',
 | 
					    tabIconDefault: iconColorLight,
 | 
				
			||||||
    tabIconSelected: tintColorLight,
 | 
					    tabIconSelected: tintColorLight,
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // New colors
 | 
				
			||||||
 | 
					    card: '#ffffff',
 | 
				
			||||||
 | 
					    border: '#d0d7de',
 | 
				
			||||||
 | 
					    notification: '#f85149',
 | 
				
			||||||
 | 
					    placeholder: '#8b949e',
 | 
				
			||||||
 | 
					    inactive: '#afb8c1',
 | 
				
			||||||
 | 
					    subtle: '#f6f8fa',
 | 
				
			||||||
 | 
					    error: '#e5484d',
 | 
				
			||||||
 | 
					    success: '#46954a',
 | 
				
			||||||
 | 
					    warning: '#daaa3f'
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  dark: {
 | 
					  dark: {
 | 
				
			||||||
    text: '#ECEDEE',
 | 
					    text: light,
 | 
				
			||||||
    background: '#151718',
 | 
					    background: dark,
 | 
				
			||||||
    tint: tintColorDark,
 | 
					    tint: tintColorDark,
 | 
				
			||||||
    icon: '#9BA1A6',
 | 
					    icon: iconColorDark,
 | 
				
			||||||
    tabIconDefault: '#9BA1A6',
 | 
					    tabIconDefault: iconColorDark,
 | 
				
			||||||
    tabIconSelected: tintColorDark,
 | 
					    tabIconSelected: tintColorDark,
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // New colors
 | 
				
			||||||
 | 
					    card: '#3a3b4a',
 | 
				
			||||||
 | 
					    border: '#444c56',
 | 
				
			||||||
 | 
					    notification: '#ff6a69',
 | 
				
			||||||
 | 
					    placeholder: '#636e7b',
 | 
				
			||||||
 | 
					    inactive: '#4d5560',
 | 
				
			||||||
 | 
					    subtle: '#272934',
 | 
				
			||||||
 | 
					    error: '#ff6369',
 | 
				
			||||||
 | 
					    success: '#3fb950',
 | 
				
			||||||
 | 
					    warning: '#d29922'
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user