import { forwardRef } from 'react'; import { Text as RNText, TextProps as RNTextProps, TextStyle } from 'react-native'; import { useTheme } from '~/contexts/ThemeContext'; type TextVariant = | 'h1' | 'h2' | 'h3' | 'h4' | 'title' | 'body' | 'bodyLarge' | 'bodySmall' | 'caption' | 'label' | 'button'; type TextColor = | 'primary' | 'secondary' | 'tertiary' | 'inverse' | 'error' | 'success' | 'warning'; type TextWeight = 'regular' | 'medium' | 'semibold' | 'bold'; type TextProps = { variant?: TextVariant; color?: TextColor; weight?: TextWeight; align?: 'left' | 'center' | 'right'; children?: React.ReactNode; } & RNTextProps; export const Text = forwardRef(({ variant = 'body', color = 'primary', weight, align = 'left', style, children, ...props }, ref) => { const { theme } = useTheme(); // Variant styles const getVariantStyle = (): TextStyle => { switch (variant) { case 'h1': return { fontSize: 32, fontWeight: '700', lineHeight: 40, }; case 'h2': return { fontSize: 28, fontWeight: '700', lineHeight: 36, }; case 'h3': return { fontSize: 24, fontWeight: '600', lineHeight: 32, }; case 'h4': return { fontSize: 20, fontWeight: '600', lineHeight: 28, }; case 'title': return { fontSize: 44, fontWeight: '800', lineHeight: 52, }; case 'bodyLarge': return { fontSize: 18, fontWeight: '400', lineHeight: 28, }; case 'body': return { fontSize: 16, fontWeight: '400', lineHeight: 24, }; case 'bodySmall': return { fontSize: 14, fontWeight: '400', lineHeight: 20, }; case 'caption': return { fontSize: 12, fontWeight: '400', lineHeight: 16, }; case 'label': return { fontSize: 14, fontWeight: '500', lineHeight: 20, }; case 'button': return { fontSize: 16, fontWeight: '600', lineHeight: 24, }; default: return {}; } }; // Color mapping const getTextColor = (): string => { switch (color) { case 'primary': return theme.colors.text.primary; case 'secondary': return theme.colors.text.secondary; case 'tertiary': return theme.colors.text.tertiary; case 'inverse': return theme.colors.text.inverse; case 'error': return theme.colors.error; case 'success': return theme.colors.success; case 'warning': return theme.colors.warning; default: return theme.colors.text.primary; } }; // Weight mapping const getFontWeight = (): TextStyle['fontWeight'] => { if (weight) { const weightMap: Record = { regular: '400', medium: '500', semibold: '600', bold: '700', }; return weightMap[weight]; } return undefined; }; const textStyle: TextStyle = { ...getVariantStyle(), color: getTextColor(), textAlign: align, ...(weight && { fontWeight: getFontWeight() }), ...(style as TextStyle), }; return ( {children} ); }); Text.displayName = 'Text';