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

87 lines
2.7 KiB

import type { NativeScrollEvent, NativeSyntheticEvent } from 'react-native';
import { ScrollView, StyleSheet, Text, View } from 'react-native';
import { colors } from '../../../src/theme';
const ITEM_H = 44;
function Column({
items,
value,
onValueChange,
width,
}: {
items: string[];
value: string;
onValueChange: (v: string) => void;
width: number;
}) {
const idx = Math.max(0, items.indexOf(value));
const handleEnd = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
const y = e.nativeEvent.contentOffset.y;
const i = Math.min(items.length - 1, Math.max(0, Math.round(y / ITEM_H)));
const v = items[i];
if (v !== value) onValueChange(v);
};
return (
<View style={[styles.col, { width }]}>
<View style={styles.highlight} pointerEvents="none" />
<ScrollView
style={styles.scroll}
showsVerticalScrollIndicator={false}
snapToInterval={ITEM_H}
snapToAlignment="center"
decelerationRate="fast"
contentOffset={{ x: 0, y: idx * ITEM_H }}
contentContainerStyle={{ paddingVertical: ITEM_H }}
onMomentumScrollEnd={handleEnd}
>
{items.map((it) => (
<View key={it} style={styles.item}>
<Text style={[styles.itemText, it === value && styles.itemTextActive]}>{it}</Text>
</View>
))}
</ScrollView>
</View>
);
}
interface DualProps {
year: string;
month: string;
onYearChange: (v: string) => void;
onMonthChange: (v: string) => void;
}
/** 年月双滚轮:用于出生年月 / 首次参加工作 / 入职时间 */
export function YearMonthWheel({ year, month, onYearChange, onMonthChange }: DualProps) {
const years = Array.from({ length: 40 }, (_, i) => `${2026 - i}年`);
const months = Array.from({ length: 12 }, (_, i) => `${i + 1}月`);
return (
<View style={styles.dual}>
<Column items={years} value={year} onValueChange={onYearChange} width={130} />
<Column items={months} value={month} onValueChange={onMonthChange} width={110} />
</View>
);
}
const styles = StyleSheet.create({
col: { height: ITEM_H * 3, position: 'relative' },
scroll: { flex: 1 },
highlight: {
position: 'absolute',
top: ITEM_H,
left: 0,
right: 0,
height: ITEM_H,
borderTopWidth: 1,
borderBottomWidth: 1,
borderColor: colors.border,
backgroundColor: colors.primaryLight,
opacity: 0.45,
},
item: { height: ITEM_H, alignItems: 'center', justifyContent: 'center' },
itemText: { fontSize: 18, color: colors.textHint },
itemTextActive: { fontSize: 20, fontWeight: '700', color: colors.textPrimary },
dual: { flexDirection: 'row', justifyContent: 'center', gap: 14 },
});