memowake-front/components/ThemedText.tsx
2025-08-07 18:55:05 +08:00

78 lines
1.8 KiB
TypeScript

import { StyleProp, StyleSheet, Text, TextStyle, type TextProps } from 'react-native';
import { Fonts } from '@/constants/Fonts';
import { useThemeColor } from '@/hooks/useThemeColor';
export type ThemedTextProps = TextProps & {
lightColor?: string;
darkColor?: string;
type?: 'default' | 'title' | 'defaultSemiBold' | 'subtitle' | 'link';
weight?: 'regular' | 'medium' | 'semiBold' | 'bold';
size?: 'xs' | 'sm' | 'base' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl';
};
export function ThemedText({
style,
lightColor,
darkColor,
type = 'default',
weight = 'regular',
size,
...rest
}: ThemedTextProps) {
const color = useThemeColor({ light: lightColor, dark: darkColor }, 'text');
const baseStyle: StyleProp<TextStyle> = {
fontFamily: Fonts.primary,
color,
fontWeight: Fonts[weight as keyof typeof Fonts] as TextStyle['fontWeight'],
};
if (size) {
baseStyle.fontSize = Fonts[size as keyof typeof Fonts];
}
return (
<Text
style={[
baseStyle,
type === 'default' ? styles.default : undefined,
type === 'title' ? styles.title : undefined,
type === 'defaultSemiBold' ? styles.defaultSemiBold : undefined,
type === 'subtitle' ? styles.subtitle : undefined,
type === 'link' ? styles.link : undefined,
style,
]}
{...rest}
/>
);
}
const styles = StyleSheet.create({
default: {
fontSize: Fonts.base,
lineHeight: 24,
},
defaultSemiBold: {
fontSize: Fonts.base,
lineHeight: 24,
fontWeight: '600',
},
title: {
fontSize: Fonts['2xl'],
fontWeight: '700',
lineHeight: 32,
},
subtitle: {
fontSize: Fonts.lg,
fontWeight: '600',
lineHeight: 28,
},
link: {
fontSize: Fonts.sm,
lineHeight: 20,
color: '#0a7ea4',
textDecorationLine: 'underline',
},
});