轻松聘
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.
 
 
 

64 lines
1.9 KiB

import { Image, StyleSheet, Text, View } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import type { ComponentProps } from 'react';
import { colors } from '../../../src/theme';
import { ASSET_REGISTRY, type AssetName } from '../assets';
type IconName = ComponentProps<typeof Ionicons>['name'];
interface Props {
/** 素材位名(见 assets.ts 的 ASSET_REGISTRY) */
name: AssetName;
width: number;
height: number;
radius?: number;
}
/**
* 内容配图槽位:素材已提供则渲染真实图,否则画一个**带文字标注**的占位框。
*
* 与 `Illustration` 的分工:那个是「小尺寸图标位」(头像 / Logo),占位只画色块;
* 这个是「内容大图位」,占位必须让看图的人知道这里要放什么图,
* 所以把 `assets.ts` 里的 hint 直接标在页面上,补图后标注自动消失。
*/
export function ImageSlot({ name, width, height, radius = 16 }: Props) {
const def = ASSET_REGISTRY[name];
if (def.source) {
return (
<Image source={def.source} style={{ width, height, borderRadius: radius }} resizeMode="cover" />
);
}
return (
<View style={[styles.slot, { width, height, borderRadius: radius, backgroundColor: def.tint }]}>
<Ionicons name={def.icon as IconName} size={26} color={colors.primary} />
<Text style={styles.tag}>配图待补</Text>
<Text style={styles.hint}>{def.hint}</Text>
</View>
);
}
const styles = StyleSheet.create({
slot: {
alignItems: 'center',
justifyContent: 'center',
paddingHorizontal: 20,
borderWidth: 1,
borderStyle: 'dashed',
borderColor: colors.primaryBorder,
},
tag: {
marginTop: 8,
fontSize: 12,
fontWeight: '700',
color: colors.primaryText,
},
hint: {
marginTop: 4,
fontSize: 12,
lineHeight: 18,
textAlign: 'center',
color: colors.textSecondary,
},
});