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.

268 lines
5.9 KiB

1 month ago
/**
*
*
1 month ago
*
*
1 month ago
* React Native CSS
*/
import { StyleSheet, TextStyle, ViewStyle } from 'react-native';
import Colors from '@/constants/Colors';
import { ThemeEnum } from '@/constants/theme';
1 month ago
/**
*
*/
export type ThemeStyles = {
[ThemeEnum.LIGHT]: any;
[ThemeEnum.DARK]: any;
[ThemeEnum.ORANGE]: any;
1 month ago
};
/**
*
*
1 month ago
* CSS 使
*
1 month ago
* @param createStyles -
* @returns
*
1 month ago
* @example
* ```tsx
* const styles = createThemeStyles((colors) => ({
* container: {
* backgroundColor: colors.background,
* padding: 16,
* },
* text: {
* color: colors.text,
* fontSize: 16,
* },
* }));
*
1 month ago
* // 使用
* const theme = useColorScheme();
* <View style={styles[theme].container}>
* <Text style={styles[theme].text}>Hello</Text>
* </View>
* ```
*/
export function createThemeStyles<T extends StyleSheet.NamedStyles<T>>(
createStyles: (colors: typeof Colors.light & typeof Colors.dark & typeof Colors.orange) => T
1 month ago
): ThemeStyles {
return {
light: StyleSheet.create(createStyles(Colors.light)),
dark: StyleSheet.create(createStyles(Colors.dark)),
orange: StyleSheet.create(createStyles(Colors.light)),
1 month ago
};
}
/**
*
*
1 month ago
*
*
1 month ago
* @param lightStyles -
* @param darkStyles -
* @param orangeStyles -
1 month ago
* @returns
*
1 month ago
* @example
* ```tsx
* const styles = createResponsiveThemeStyles(
* {
* container: { backgroundColor: '#fff', padding: 16 },
* text: { color: '#000', fontSize: 14 },
* },
* {
* container: { backgroundColor: '#000', padding: 20 },
* text: { color: '#fff', fontSize: 16 },
* }
* );
* ```
*/
export function createResponsiveThemeStyles<T extends StyleSheet.NamedStyles<T>>(
lightStyles: T,
darkStyles: T,
orangeStyles: T
1 month ago
): ThemeStyles {
return {
light: StyleSheet.create(lightStyles),
dark: StyleSheet.create(darkStyles),
orange: StyleSheet.create(lightStyles),
1 month ago
};
}
/**
*
*
1 month ago
* Tailwind CSS
*/
export const commonStyles = createThemeStyles((colors) => ({
// 容器样式
container: {
flex: 1,
backgroundColor: colors.background,
},
containerPadded: {
flex: 1,
backgroundColor: colors.background,
padding: 16,
},
containerCentered: {
flex: 1,
backgroundColor: colors.background,
justifyContent: 'center',
alignItems: 'center',
},
1 month ago
// 卡片样式
card: {
backgroundColor: colors.card,
borderRadius: 8,
padding: 16,
borderWidth: 1,
borderColor: colors.border,
},
cardElevated: {
backgroundColor: colors.card,
borderRadius: 8,
padding: 16,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
1 month ago
// 文本样式
textPrimary: {
color: colors.text,
fontSize: 16,
} as TextStyle,
textSecondary: {
color: colors.textSecondary,
fontSize: 14,
} as TextStyle,
textTertiary: {
color: colors.textTertiary,
fontSize: 12,
} as TextStyle,
textTitle: {
color: colors.text,
fontSize: 24,
fontWeight: 'bold',
} as TextStyle,
textSubtitle: {
color: colors.text,
fontSize: 18,
fontWeight: '600',
} as TextStyle,
1 month ago
// 按钮样式
button: {
backgroundColor: colors.buttonPrimary,
paddingVertical: 12,
paddingHorizontal: 24,
borderRadius: 8,
alignItems: 'center',
justifyContent: 'center',
} as ViewStyle,
buttonOutline: {
backgroundColor: 'transparent',
paddingVertical: 12,
paddingHorizontal: 24,
borderRadius: 8,
borderWidth: 1,
borderColor: colors.buttonPrimary,
alignItems: 'center',
justifyContent: 'center',
} as ViewStyle,
buttonText: {
color: '#FFFFFF',
fontSize: 16,
fontWeight: '600',
} as TextStyle,
buttonTextOutline: {
color: colors.buttonPrimary,
fontSize: 16,
fontWeight: '600',
} as TextStyle,
1 month ago
// 输入框样式
input: {
backgroundColor: colors.inputBackground,
borderWidth: 1,
borderColor: colors.inputBorder,
borderRadius: 8,
paddingVertical: 12,
paddingHorizontal: 16,
fontSize: 16,
color: colors.text,
} as TextStyle,
inputFocused: {
backgroundColor: colors.inputBackground,
borderWidth: 2,
borderColor: colors.primary,
borderRadius: 8,
paddingVertical: 12,
paddingHorizontal: 16,
fontSize: 16,
color: colors.text,
} as TextStyle,
1 month ago
// 分隔线
separator: {
height: 1,
backgroundColor: colors.separator,
} as ViewStyle,
separatorVertical: {
width: 1,
backgroundColor: colors.separator,
} as ViewStyle,
1 month ago
// 间距
spacingXs: { height: 4 } as ViewStyle,
spacingSm: { height: 8 } as ViewStyle,
spacingMd: { height: 16 } as ViewStyle,
spacingLg: { height: 24 } as ViewStyle,
spacingXl: { height: 32 } as ViewStyle,
1 month ago
// 布局
row: {
flexDirection: 'row',
alignItems: 'center',
} as ViewStyle,
rowBetween: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
} as ViewStyle,
column: {
flexDirection: 'column',
} as ViewStyle,
center: {
justifyContent: 'center',
alignItems: 'center',
} as ViewStyle,
}));
/**
*
*
1 month ago
* @param styles -
* @param theme -
* @returns
*
1 month ago
* @example
* ```tsx
* const theme = useColorScheme();
* const style = getThemeStyle(styles, theme);
* <View style={style.container} />
* ```
*/
export function getThemeStyle<T>(styles: ThemeStyles, theme: ThemeEnum): T {
1 month ago
return styles[theme];
}