refactor(coach): 重构教练组件,统一导入并简化UI实现与类型定义
This commit is contained in:
147
components/NumberKeyboard.tsx
Normal file
147
components/NumberKeyboard.tsx
Normal file
@@ -0,0 +1,147 @@
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import React from 'react';
|
||||
import {
|
||||
Dimensions,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from 'react-native';
|
||||
|
||||
interface NumberKeyboardProps {
|
||||
onNumberPress: (number: string) => void;
|
||||
onDeletePress: () => void;
|
||||
onDecimalPress: () => void;
|
||||
hasDecimal?: boolean;
|
||||
maxLength?: number;
|
||||
currentValue?: string;
|
||||
}
|
||||
|
||||
const { width } = Dimensions.get('window');
|
||||
const keyWidth = (width - 80) / 3; // 减去左右边距和间隙
|
||||
|
||||
export default function NumberKeyboard({
|
||||
onNumberPress,
|
||||
onDeletePress,
|
||||
onDecimalPress,
|
||||
hasDecimal = false,
|
||||
maxLength = 6,
|
||||
currentValue = '',
|
||||
}: NumberKeyboardProps) {
|
||||
const handleNumberPress = (number: string) => {
|
||||
if (currentValue.length >= maxLength) return;
|
||||
// 防止输入多个0开头
|
||||
if (currentValue === '0' && number === '0') return;
|
||||
// 如果当前是0,输入非0数字时替换
|
||||
if (currentValue === '0' && number !== '0') {
|
||||
// 这里不需要replace,直接传递number即可
|
||||
return;
|
||||
}
|
||||
onNumberPress(number);
|
||||
};
|
||||
|
||||
const handleDecimalPress = () => {
|
||||
if (hasDecimal || currentValue.includes('.')) return;
|
||||
onDecimalPress();
|
||||
};
|
||||
|
||||
const renderKey = (
|
||||
value: string,
|
||||
onPress: () => void,
|
||||
style?: any,
|
||||
textStyle?: any,
|
||||
disabled?: boolean
|
||||
) => (
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
styles.key,
|
||||
{ width: keyWidth },
|
||||
style,
|
||||
disabled && styles.keyDisabled
|
||||
]}
|
||||
onPress={onPress}
|
||||
disabled={disabled}
|
||||
activeOpacity={0.7}
|
||||
>
|
||||
{value === 'delete' ? (
|
||||
<Ionicons name="backspace-outline" size={24} color="#374151" />
|
||||
) : (
|
||||
<Text style={[styles.keyText, textStyle, disabled && styles.keyTextDisabled]}>
|
||||
{value}
|
||||
</Text>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
);
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={styles.row}>
|
||||
{renderKey('1', () => handleNumberPress('1'))}
|
||||
{renderKey('2', () => handleNumberPress('2'))}
|
||||
{renderKey('3', () => handleNumberPress('3'))}
|
||||
</View>
|
||||
<View style={styles.row}>
|
||||
{renderKey('4', () => handleNumberPress('4'))}
|
||||
{renderKey('5', () => handleNumberPress('5'))}
|
||||
{renderKey('6', () => handleNumberPress('6'))}
|
||||
</View>
|
||||
<View style={styles.row}>
|
||||
{renderKey('7', () => handleNumberPress('7'))}
|
||||
{renderKey('8', () => handleNumberPress('8'))}
|
||||
{renderKey('9', () => handleNumberPress('9'))}
|
||||
</View>
|
||||
<View style={styles.row}>
|
||||
{renderKey(
|
||||
'.',
|
||||
handleDecimalPress,
|
||||
undefined,
|
||||
undefined,
|
||||
hasDecimal || currentValue.includes('.')
|
||||
)}
|
||||
{renderKey('0', () => handleNumberPress('0'))}
|
||||
{renderKey('delete', onDeletePress)}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
backgroundColor: '#F9FAFB',
|
||||
paddingVertical: 20,
|
||||
paddingHorizontal: 20,
|
||||
borderTopWidth: 1,
|
||||
borderTopColor: '#E5E7EB',
|
||||
},
|
||||
row: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
marginBottom: 12,
|
||||
},
|
||||
key: {
|
||||
height: 50,
|
||||
backgroundColor: '#FFFFFF',
|
||||
borderRadius: 12,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 1 },
|
||||
shadowOpacity: 0.05,
|
||||
shadowRadius: 2,
|
||||
elevation: 1,
|
||||
borderWidth: 1,
|
||||
borderColor: '#E5E7EB',
|
||||
},
|
||||
keyDisabled: {
|
||||
backgroundColor: '#F3F4F6',
|
||||
opacity: 0.5,
|
||||
},
|
||||
keyText: {
|
||||
fontSize: 20,
|
||||
fontWeight: '600',
|
||||
color: '#374151',
|
||||
},
|
||||
keyTextDisabled: {
|
||||
color: '#9CA3AF',
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user